This is an archive of the discontinued LLVM Phabricator instance.

[XRay][compiler-rt][Darwin] Minimal XRay build support in Darwin
ClosedPublic

Authored by dberris on Oct 20 2017, 1:06 AM.

Details

Summary

This change is the first in a series of changes to get the XRay runtime
building on macOS. This first allows us to build the minimal parts of
XRay to get us started on supporting macOS development. These include:

  • CMake changes to allow targeting x86_64 initially.
  • Allowing for building the initialisation routines without .preinit_array support.
  • Use __sanitizer::SleepForMillis() to work around the lack of clock_nanosleep on macOS.
  • Deprecate the xray_fdr_log_grace_period_us flag, and introduce the xray_fdr_log_grace_period_ms flag instead, to use milliseconds across platforms.

Event Timeline

dberris created this revision.Oct 20 2017, 1:06 AM

@kubamracek -- if you don't mind having a look at this, I'm looking for thoughts/feedback on how we can address the "blockers":

  • Assembly for Darwin x86_64 and how we avoid the ELF'isms (do we need to implement darwin-specific assembly for MachO?)
  • Syscalls, testing, etc. -- whether we need to do anything special here for making it work on macOS.
kubamracek accepted this revision.Nov 2 2017, 9:02 AM

Hi and sorry for replying so late! All of the changes LGTM with a few nits.

Assembly for Darwin x86_64 and how we avoid the ELF'isms (do we need to implement darwin-specific assembly for MachO?)

This should be actually easily solvable by #include'ing sanitizer_common/sanitizer_asm.h and then using the macros from there (perhaps introducing some new macros or generalizing the existing ones). Take a look at what was done in lib/tsan/rtl/tsan_rtl_amd64.S. Names of symbols should use a macro like ASM_SYMBOL which will add an underscore on macOS. .type directives should use ASM_TYPE_FUNCTION. And so on. It should be possible to reuse almost all of the assembly instructions unchanged. I think I have an ugly old patch for this somewhere, I can send it to you if you want.

Syscalls, testing, etc. -- whether we need to do anything special here for making it work on macOS.

We should try to move most of the tests in the Linux directory to a common tests directory. I don't see anything particularly Linux-y there.

Regarding syscalls, I'm not sure I understand the problem. Is XRay doing any syscall interception or something like that?

compiler-rt/cmake/config-ix.cmake
419–425

Instead of this change, please do something similar like we do for ALL_LSAN_SUPPORTED_ARCH above (line 200).

compiler-rt/lib/xray/CMakeLists.txt
82

STATIC is okay for now, but we have much better experience with dynamic libraries for runtimes. Is there some reason to use a static library?

compiler-rt/test/xray/TestCases/Darwin/always-never-instrument.cc
12

Should this REQUIRES be here?

Similarly, in all the tests in the Linux/ directory, we should change REQUIRES: x86_64-linux to just REQUIRES: x86_64.

This revision is now accepted and ready to land.Nov 2 2017, 9:02 AM

Also, please make sure this builds and tests pass before actually landing this patch. FYI, there are bots that run on older macOS versions (10.11 for sure, probably even older).

dberris updated this revision to Diff 122210.Nov 9 2017, 2:17 AM
dberris marked an inline comment as done.
  • fixup: Use ASM macros for darwin assembly
  • fixup: support weak symbols for Darwin linkage

Hi and sorry for replying so late! All of the changes LGTM with a few nits.

All good, thanks for having a look!

Assembly for Darwin x86_64 and how we avoid the ELF'isms (do we need to implement darwin-specific assembly for MachO?)

This should be actually easily solvable by #include'ing sanitizer_common/sanitizer_asm.h and then using the macros from there (perhaps introducing some new macros or generalizing the existing ones). Take a look at what was done in lib/tsan/rtl/tsan_rtl_amd64.S. Names of symbols should use a macro like ASM_SYMBOL which will add an underscore on macOS. .type directives should use ASM_TYPE_FUNCTION. And so on. It should be possible to reuse almost all of the assembly instructions unchanged. I think I have an ugly old patch for this somewhere, I can send it to you if you want.

Thanks for the hints, that was easy enough!

Syscalls, testing, etc. -- whether we need to do anything special here for making it work on macOS.

We should try to move most of the tests in the Linux directory to a common tests directory. I don't see anything particularly Linux-y there.

Agreed. Let me make a few of those changes.

Regarding syscalls, I'm not sure I understand the problem. Is XRay doing any syscall interception or something like that?

Nope, just calling mmap and mprotect -- which should just be available on macOS. :)

compiler-rt/lib/xray/CMakeLists.txt
82

Let me try with a SHARED build, and report back.

compiler-rt/test/xray/TestCases/Darwin/always-never-instrument.cc
12

Not anymore, let me change that next.

dberris updated this revision to Diff 122229.Nov 9 2017, 5:42 AM
  • fixup: Use ASM macros for darwin assembly
  • fixup: support weak symbols for Darwin linkage
  • fixup: qualify symbols, use macros, limit weak symbols
  • fixup: move test cases from Linux up one directory
  • fixup: make clang link the needed runtime bits in osx
  • fixup: update tests to run on x86_64 on both Darwin and Linux

Got some good progress on finally being able to make this work... here's the current state:

  • When linking the final binary, the XRay runtime can't seem to find the __{start,stop}_xray_{fn_idx,instr_map} symbols. I've marked them weak, but they seem to either not be resolved when statically linking the binary. The dynamic lib version of the XRay runtime isn't quite ready yet, but I'm willing to try some things there.
  • There are also missing symbols from the sanitizer_common library that's linked to from the libclang_rt.xray_osx.a produced by the compiler-rt XRay build configuration.

For example, when we're building some of the tests, I see errors like:

********************
FAIL: XRay-x86_64-darwin :: TestCases/func-id-utils.cc (18 of 18)
******************** TEST 'XRay-x86_64-darwin :: TestCases/func-id-utils.cc' FAILED ********************
Script:
--
/Users/dberris/Source/llvm-project-build/./bin/clang --driver-mode=g++ -fxray-instrument -arch x86_64 -stdlib=libc++ -mmacosx-version-min=10.9 -isysroot /Applications/Xcode.
app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk  -std=c++11 /Users/dberris/Source/llvm-project/compiler-rt/test/xray/TestCases/func-id-utils.
cc -o /Users/dberris/Source/llvm-project-build/projects/compiler-rt/test/xray/X86_64DarwinConfig/TestCases/Output/func-id-utils.cc.tmp
XRAY_OPTIONS="patch_premain=false xray_naive_log=false"  /Users/dberris/Source/llvm-project-build/projects/compiler-rt/test/xray/X86_64DarwinConfig/TestCases/Output/func-id-
utils.cc.tmp
--
Exit Code: 1

Command Output (stderr):
--
Undefined symbols for architecture x86_64:
  "___sanitizer_symbolize_code", referenced from:
      __sanitizer::Symbolizer::PlatformInit() in libclang_rt.xray_osx.a(sanitizer_symbolizer_posix_libcdep.cc.o)
      __sanitizer::InternalSymbolizer::SymbolizePC(unsigned long, __sanitizer::SymbolizedStack*) in libclang_rt.xray_osx.a(sanitizer_symbolizer_posix_libcdep.cc.o)
  "___sanitizer_symbolize_data", referenced from:
      __sanitizer::Symbolizer::PlatformInit() in libclang_rt.xray_osx.a(sanitizer_symbolizer_posix_libcdep.cc.o)
      __sanitizer::InternalSymbolizer::SymbolizeData(unsigned long, __sanitizer::DataInfo*) in libclang_rt.xray_osx.a(sanitizer_symbolizer_posix_libcdep.cc.o)
  "___sanitizer_symbolize_demangle", referenced from:
      __sanitizer::InternalSymbolizer::Demangle(char const*) in libclang_rt.xray_osx.a(sanitizer_symbolizer_posix_libcdep.cc.o)
  "___sanitizer_symbolize_flush", referenced from:
      __sanitizer::InternalSymbolizer::Flush() in libclang_rt.xray_osx.a(sanitizer_symbolizer_posix_libcdep.cc.o)
  "___start_xray_fn_idx", referenced from:
      ___xray_init in libclang_rt.xray_osx.a(xray_init.cc.o)
  "___start_xray_instr_map", referenced from:
      ___xray_init in libclang_rt.xray_osx.a(xray_init.cc.o)
  "___stop_xray_fn_idx", referenced from:
      ___xray_init in libclang_rt.xray_osx.a(xray_init.cc.o)
  "___stop_xray_instr_map", referenced from:
      ___xray_init in libclang_rt.xray_osx.a(xray_init.cc.o)
ld: symbol(s) not found for architecture x86_64
clang-6.0: error: linker command failed with exit code 1 (use -v to see invocation)

--

Any further hints/thoughts on this would be great, @kubamracek (cc @pelikan and @echristo)

Thanks for working on this! Can we split the patch and land parts that are LGTM? It's getting a bit crowded here. I think the ASM changes should be a separate patch, and the test changes as well, probably.

When linking the final binary, the XRay runtime can't seem to find the __{start,stop}_xray_{fn_idx,instr_map} symbols. I've marked them weak, but they seem to either not be resolved when statically linking the binary. The dynamic lib version of the XRay runtime isn't quite ready yet, but I'm willing to try some things there.
There are also missing symbols from the sanitizer_common library that's linked to from the libclang_rt.xray_osx.a produced by the compiler-rt XRay build configuration.
Any further hints/thoughts on this would be great, @kubamracek (cc @pelikan and @echristo)

This is one of the reasons why a dynamic shared library works better. Using a dynamic library should solve this. What are the problems with that?

dberris planned changes to this revision.Nov 9 2017, 3:14 PM

When linking the final binary, the XRay runtime can't seem to find the __{start,stop}_xray_{fn_idx,instr_map} symbols. I've marked them weak, but they seem to either not be resolved when statically linking the binary. The dynamic lib version of the XRay runtime isn't quite ready yet, but I'm willing to try some things there.
There are also missing symbols from the sanitizer_common library that's linked to from the libclang_rt.xray_osx.a produced by the compiler-rt XRay build configuration.
Any further hints/thoughts on this would be great, @kubamracek (cc @pelikan and @echristo)

This is one of the reasons why a dynamic shared library works better. Using a dynamic library should solve this. What are the problems with that?

Nothing fundamentally wrong with doing that, except for the clang changes to link correctly (which I still need to experiment with). Let me go that route and report back.

I'll also split the patch up into smaller bits. The changes to the tests can be a separate change. I'll back those out and re-upload.

Thanks!

dberris updated this revision to Diff 122352.Nov 9 2017, 3:58 PM
dberris retitled this revision from [XRay] Initial XRay in Darwin Support to [XRay][darwin] Initial XRay in Darwin Support.
dberris edited the summary of this revision. (Show Details)
dberris removed subscribers: echristo, pelikan.

Re-title, back out test changes to a different patch.

This revision is now accepted and ready to land.Nov 9 2017, 3:58 PM
This revision was automatically updated to reflect the committed changes.
kubamracek added inline comments.Nov 9 2017, 9:56 PM
compiler-rt/trunk/lib/xray/xray_trampoline_x86_64.S
75 ↗(On Diff #122391)

Since we want to use ASM_TSAN_SYMBOL outside of TSan, can we rename it to just ASM_SYMBOL (or something like that)?

Landing now, will deal with the test and dynamic/

compiler-rt/trunk/lib/xray/xray_trampoline_x86_64.S
75 ↗(On Diff #122391)

Probably. I was thinking about doing that, but then ended up deciding against it.

I can make a change later to migrate all uses in compiler-rt (if someone doesn't beat me to it). :)

Reverted in rL317877 -- I'm going to try again next week instead.

dberris reopened this revision.Nov 19 2017, 2:29 AM

Hi @kubamracek -- do you know how to work around the lack of clock_gettime from the 10.11 SDK?

The build bots will complain again if this lands, and it'd be a real shame if we didn't get this working even just for 10.12. Is there something we can do in the CMake builds to ignore 10.11? Or maybe have an implementation of clock_gettime just for that platform?

This revision is now accepted and ready to land.Nov 19 2017, 2:29 AM

Can we just not use clock_gettime on Darwin and instead use mach_absolute_time?

dberris planned changes to this revision.Nov 19 2017, 2:12 PM

Can we just not use clock_gettime on Darwin and instead use mach_absolute_time?

That's a good suggestion. Let me make that change.

Thanks!

dberris updated this revision to Diff 123529.Nov 19 2017, 7:33 PM

Remove some uses of clock_gettime from XRay naive mode logging and some support libraries.

Up next should be the FDR mode calls to clock_gettime.

This revision is now accepted and ready to land.Nov 19 2017, 7:33 PM
dberris planned changes to this revision.Nov 19 2017, 8:24 PM

The FDR mode calls to clock_gettime needs a bit more attention, let me try and isolate those before attempting to land again.

Hi, can you split the patch and send individual changes as separate patches? It's getting hard to follow. And I think we should land the parts that are "safe to land", e.g. the ASM changes or some of the NFC whitespace changes. The Darwin-specific changes in tests can also be landed (but don't enable the tests on Darwin, yet).

And we should probably introduce files named xray_linux.cc and xray_mac.cc to contain platform-specific functions.

krytarowski added inline comments.
compiler-rt/lib/xray/xray_x86_64.cc
25 ↗(On Diff #123529)

Is it OK for you to call here internally malloc(3)? At least the NetBSD version calls it.

Hi, can you split the patch and send individual changes as separate patches? It's getting hard to follow. And I think we should land the parts that are "safe to land", e.g. the ASM changes or some of the NFC whitespace changes. The Darwin-specific changes in tests can also be landed (but don't enable the tests on Darwin, yet).

Yes, I'm going to be breaking this up into smaller parts -- just trying to see where it's going at this point.

I've just finally gotten to the point where I can get back to this again. :)

And we should probably introduce files named xray_linux.cc and xray_mac.cc to contain platform-specific functions.

I fully agree. That should happen in smaller steps.

Expect smaller reviews coming soon, from breaking this patch up. :D

compiler-rt/lib/xray/xray_x86_64.cc
25 ↗(On Diff #123529)

Good point. We should be caching this information earlier on in the process (i.e. before we start tracing) to avoid deadlocks in case we have an instrumented malloc implementation. Let me put a TODO or at least make sure we're calling this at a point that is safe (probably at initialisation time).

dberris updated this revision to Diff 124538.Nov 28 2017, 3:42 AM
dberris retitled this revision from [XRay][darwin] Initial XRay in Darwin Support to [XRay][compiler-rt][Darwin] Minimal XRay build support in Darwin.
dberris edited the summary of this revision. (Show Details)

Retitle and reduce patch to smaller bits.

This revision is now accepted and ready to land.Nov 28 2017, 3:42 AM
dberris updated this revision to Diff 124539.Nov 28 2017, 3:44 AM
dberris edited the summary of this revision. (Show Details)

Update description to not use tabs.

Landing this now and seeing whether there's fallout from the build bots.

I'm getting "multiple definition" errors on powerpc64le when linking the unit tests, for example XRayBufferQueueTest:

src/projects/compiler-rt/lib/xray/xray_utils.cc:34: multiple definition of `__xray::retryingWriteAll(int, char*, char*)'
src/projects/compiler-rt/lib/xray/xray_utils.cc:73: multiple definition of `__xray::readValueFromFile(char const*, long long*)'
src/projects/compiler-rt/lib/xray/xray_utils.cc:95: multiple definition of `__xray::getLogFD()'

to name a few of the errors.

(related note: Why aren't the unit tests rebuilt if the libclang_rt.xray-powerpc64le.a changes?!? After reverting this commit locally for testing, the unit test built just fine. After reapplying the test wasn't rebuilt and I saw no problems...)

I'm getting "multiple definition" errors on powerpc64le when linking the unit tests, for example XRayBufferQueueTest:

src/projects/compiler-rt/lib/xray/xray_utils.cc:34: multiple definition of `__xray::retryingWriteAll(int, char*, char*)'
src/projects/compiler-rt/lib/xray/xray_utils.cc:73: multiple definition of `__xray::readValueFromFile(char const*, long long*)'
src/projects/compiler-rt/lib/xray/xray_utils.cc:95: multiple definition of `__xray::getLogFD()'

to name a few of the errors.

Fixed in rL319241.

(related note: Why aren't the unit tests rebuilt if the libclang_rt.xray-powerpc64le.a changes?!? After reverting this commit locally for testing, the unit test built just fine. After reapplying the test wasn't rebuilt and I saw no problems...)

Yeah, that one I still haven't figured out yet. :/

dberris updated this revision to Diff 124717.Nov 29 2017, 4:19 AM
  • [XRay][compiler-rt][Darwin] Use dynamic initialisation as an alternative
dberris closed this revision.Nov 29 2017, 6:10 AM

Already commited; closing this revision out now.