Index: compiler-rt/lib/tsan/rtl/tsan_interceptors.cc =================================================================== --- compiler-rt/lib/tsan/rtl/tsan_interceptors.cc +++ compiler-rt/lib/tsan/rtl/tsan_interceptors.cc @@ -228,6 +228,16 @@ libignore()->OnLibraryLoaded(0); } +// The following two hooks can be used by for cooperative scheduling when +// locking. +#ifdef TSAN_EXTERNAL_HOOKS +void OnCxaGuardAcquireEnter(); +void OnCxaGuardAcquireExit(); +#else +SANITIZER_WEAK_CXX_DEFAULT_IMPL void OnCxaGuardAcquireEnter() {} +SANITIZER_WEAK_CXX_DEFAULT_IMPL void OnCxaGuardAcquireExit() {} +#endif + } // namespace __tsan static ThreadSignalContext *SigCtx(ThreadState *thr) { @@ -866,6 +876,8 @@ // Used in thread-safe function static initialization. STDCXX_INTERCEPTOR(int, __cxa_guard_acquire, atomic_uint32_t *g) { SCOPED_INTERCEPTOR_RAW(__cxa_guard_acquire, g); + OnCxaGuardAcquireEnter(); + auto on_exit = at_scope_exit(&OnCxaGuardAcquireExit); for (;;) { u32 cmp = atomic_load(g, memory_order_acquire); if (cmp == 0) { Index: compiler-rt/test/tsan/Linux/cxa_guard_acquire.cc =================================================================== --- /dev/null +++ compiler-rt/test/tsan/Linux/cxa_guard_acquire.cc @@ -0,0 +1,23 @@ +// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s + +#include + +namespace __tsan { + +void OnCxaGuardAcquireEnter() { printf("Enter __cxa_guard_acquire\n"); } + +void OnCxaGuardAcquireExit() { printf("Exit __cxa_guard_acquire\n"); } + +} // namespace __tsan + +int main(int argc, char **argv) { + // CHECK: Enter main + printf("Enter main\n"); + // CHECK-NEXT: Enter __cxa_guard_acquire + // CHECK-NEXT: Exit __cxa_guard_acquire + static int s = argc; + (void)s; + // CHECK-NEXT: Exit main + printf("Exit main\n"); + return 0; +}