This patch series implements ThreadSanitizer support for SystemZ.
Patches 1-3 make the necessary common code adjustments, patches 4-7
implement various bits, and patch 8 actually enables it. golang
support is currently missing and will be submitted separately.
Details
- Reviewers
kcc dvyukov uweigand - Commits
- rG9bf2e7eeebbd: [TSan] Add SystemZ SANITIZER_GO support
rGe34078f121a5: [TSan] Enable SystemZ support
rG937242cecc13: [TSan] Adjust tests for SystemZ
rGbd77f742d656: [TSan] Intercept __tls_get_addr_internal and __tls_get_offset on SystemZ
rGb17673816d7f: [TSan] Disable __TSAN_HAS_INT128 on SystemZ
rG402fc790eb48: [TSan] Add SystemZ longjmp support
rG96a29df0b166: [TSan] Define C/C++ address ranges for SystemZ
rGfab044045b63: [TSan] Define PTHREAD_ABI_BASE for SystemZ
rGd5c34ee5b666: [TSan] Build ignore_lib{0,1,5} tests with -fno-builtin
rG3845f2cd940b: [TSan] Use zeroext for function parameters
rGcadbb9241627: [TSan] Align thread_registry_placeholder
rG54128b73f833: [sanitizer] Force TLS allocation on s390
rGacf0a6428681: [sanitizer] Fix __sanitizer_kernel_sigset_t endianness issue
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Some solid work here.
I only have a question re mmap handling.
compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp | ||
---|---|---|
781 ↗ | (On Diff #357214) | TSan runtime is supposed to mprotect all ranges that are inaccessible to the application. How does it happen that kernel still returns such an address? Do we fail to mprotect all ranges on s390? If so should that be fixed instead? |
- Reserve the address space "tail" in the "[TSan] Define C/C++ address ranges for SystemZ" patch.
- Drop the "[TSan] Simulate OOM in mmap_interceptor()" patch.
- Group "[TSan] Use zeroext for function parameters" with the common code patches.
compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp | ||
---|---|---|
781 ↗ | (On Diff #357214) | The common code in CheckAndProtect() didn't mprotect the address space "tail" - I've added a special case for that. |
Regarding the openmp test failures: I tried check-openmp on a x86_64 machine, and they occur both with and without this patch series, so must be unrelated.
See inline comments ... otherwise the SystemZ platform-specific parts look good to me.
compiler-rt/lib/tsan/rtl/tsan_platform_posix.cpp | ||
---|---|---|
123 ↗ | (On Diff #357889) | Did you test this on older kernels without 5-level page table support? I believe the allocation / mprotect may fail on those ... |
compiler-rt/lib/tsan/rtl/tsan_rtl_s390x.S | ||
22 ↗ | (On Diff #357889) | Do we need CFI for r2/r3 ? Those are call-clobbered any cannot be unwound normally anyway ... |
compiler-rt/lib/tsan/rtl/tsan_platform_posix.cpp | ||
---|---|---|
123 ↗ | (On Diff #357889) | No, not really. Would it make sense to probe here? E.g. first try 0xfffffffffffff000, then 0x20000000000000. Or is there a way to query user_addr_max() / TASK_SIZE_MAX / TASK_SIZE? |
compiler-rt/lib/tsan/rtl/tsan_rtl_s390x.S | ||
22 ↗ | (On Diff #357889) | I'm not quite sure, but glibc does this (e.g. in sysdeps/s390/s390-64/dl-trampoline.h), so I figured I'll do this here as well just in case. |
compiler-rt/lib/tsan/rtl/tsan_platform_posix.cpp | ||
---|---|---|
123 ↗ | (On Diff #357889) | I don't know of any way to query this. You can simply do the allocation in stages (first to the top of the three-pagetable range, then four, then five), and ignore failures. As an unfortunate side effect this will force the kernel to allocate five levels of page tables even when unnecessary, but I don't think there's anything we can do about that. |
compiler-rt/lib/tsan/rtl/tsan_rtl_s390x.S | ||
22 ↗ | (On Diff #357889) | Huh. Well I guess it doesn't hurt either way. |
compiler-rt/lib/tsan/rtl/tsan_platform_posix.cpp | ||
---|---|---|
123 ↗ | (On Diff #357889) | 3-level page table limit is quite below the application range defined in this series (0x40000000000 < 0xc00000000000). Are there any relevant kernels that do not support 4-level page tables? I tried to search the git history, and it looks as if even 2.6 ones have it. |
compiler-rt/lib/tsan/rtl/tsan_platform_posix.cpp | ||
---|---|---|
123 ↗ | (On Diff #357889) | Ah, right. Yes, we can certainly assume 4-level support at this point. |
Based on Ulrich's feedback I tested the series on RHEL7, which, in
addition to an old kernel, contains an old glibc and an old toolchain.
This uncovered a few extra issues, which are fixed here:
- Call __tls_get_offset() in order to force TLS allocation.
- Align thread_registry_placeholder.
- Protect the address space "tail" in two steps: until the 4-level page table boundary (this must succeed) and then until the 5-level page table boundary (this may fail).
Also, the Go support is finally working
(https://github.com/iii-i/go/tree/tsan-s390x), so, since we need to
make another round anyway, I've included the LLVM part here as well.