[compiler-rt] 303d278 - [tsan] Fix pthread_once() on Mac OS X

Marco Elver via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 19 04:19:11 PDT 2021


Author: Marco Elver
Date: 2021-08-19T13:17:45+02:00
New Revision: 303d278ad2fa9bb8caf5beaac7374ea0773dc2fe

URL: https://github.com/llvm/llvm-project/commit/303d278ad2fa9bb8caf5beaac7374ea0773dc2fe
DIFF: https://github.com/llvm/llvm-project/commit/303d278ad2fa9bb8caf5beaac7374ea0773dc2fe.diff

LOG: [tsan] Fix pthread_once() on Mac OS X

Change 636428c727cd enabled BlockingRegion hooks for pthread_once().
Unfortunately this seems to cause crashes on Mac OS X which uses
pthread_once() from locations that seem to result in crashes:

| ThreadSanitizer:DEADLYSIGNAL
| ==31465==ERROR: ThreadSanitizer: stack-overflow on address 0x7ffee73fffd8 (pc 0x00010807fd2a bp 0x7ffee7400050 sp 0x7ffee73fffb0 T93815)
|     #0 __tsan::MetaMap::GetSync(__tsan::ThreadState*, unsigned long, unsigned long, bool, bool) tsan_sync.cpp:195 (libclang_rt.tsan_osx_dynamic.dylib:x86_64+0x78d2a)
|     #1 __tsan::MutexPreLock(__tsan::ThreadState*, unsigned long, unsigned long, unsigned int) tsan_rtl_mutex.cpp:143 (libclang_rt.tsan_osx_dynamic.dylib:x86_64+0x6cefc)
|     #2 wrap_pthread_mutex_lock sanitizer_common_interceptors.inc:4240 (libclang_rt.tsan_osx_dynamic.dylib:x86_64+0x3dae0)
|     #3 flockfile <null>:2 (libsystem_c.dylib:x86_64+0x38a69)
|     #4 puts <null>:2 (libsystem_c.dylib:x86_64+0x3f69b)
|     #5 wrap_puts sanitizer_common_interceptors.inc (libclang_rt.tsan_osx_dynamic.dylib:x86_64+0x34d83)
|     #6 __tsan::OnPotentiallyBlockingRegionBegin() cxa_guard_acquire.cpp:8 (foo:x86_64+0x100000e48)
|     #7 wrap_pthread_once tsan_interceptors_posix.cpp:1512 (libclang_rt.tsan_osx_dynamic.dylib:x86_64+0x2f6e6)

>From the stack trace it can be seen that the caller is unknown, and the
resulting stack-overflow seems to indicate that whoever the caller is
does not have enough stack space or otherwise is running in a limited
environment not yet ready for full instrumentation.

Fix it by reverting behaviour on Mac OS X to not call BlockingRegion
hooks from pthread_once().

Reported-by: azharudd

Reviewed By: glider

Differential Revision: https://reviews.llvm.org/D108305

Added: 
    

Modified: 
    compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
index af0073726765..ec3a548f05aa 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
@@ -855,9 +855,15 @@ constexpr u32 kGuardDone = 1;
 constexpr u32 kGuardRunning = 1 << 16;
 constexpr u32 kGuardWaiter = 1 << 17;
 
-static int guard_acquire(ThreadState *thr, uptr pc, atomic_uint32_t *g) {
-  OnPotentiallyBlockingRegionBegin();
-  auto on_exit = at_scope_exit(&OnPotentiallyBlockingRegionEnd);
+static int guard_acquire(ThreadState *thr, uptr pc, atomic_uint32_t *g,
+                         bool blocking_hooks = true) {
+  if (blocking_hooks)
+    OnPotentiallyBlockingRegionBegin();
+  auto on_exit = at_scope_exit([blocking_hooks] {
+    if (blocking_hooks)
+      OnPotentiallyBlockingRegionEnd();
+  });
+
   for (;;) {
     u32 cmp = atomic_load(g, memory_order_acquire);
     if (cmp == kGuardInit) {
@@ -1509,7 +1515,9 @@ TSAN_INTERCEPTOR(int, pthread_once, void *o, void (*f)()) {
   else
     a = static_cast<atomic_uint32_t*>(o);
 
-  if (guard_acquire(thr, pc, a)) {
+  // Mac OS X appears to use pthread_once() where calling BlockingRegion hooks
+  // result in crashes due to too little stack space.
+  if (guard_acquire(thr, pc, a, !SANITIZER_MAC)) {
     (*f)();
     guard_release(thr, pc, a);
   }


        


More information about the llvm-commits mailing list