Index: compiler-rt/trunk/lib/tsan/rtl/tsan_libdispatch_mac.cc =================================================================== --- compiler-rt/trunk/lib/tsan/rtl/tsan_libdispatch_mac.cc +++ compiler-rt/trunk/lib/tsan/rtl/tsan_libdispatch_mac.cc @@ -219,7 +219,7 @@ #undef dispatch_once TSAN_INTERCEPTOR(void, dispatch_once, dispatch_once_t *predicate, dispatch_block_t block) { - SCOPED_TSAN_INTERCEPTOR(dispatch_once, predicate, block); + SCOPED_INTERCEPTOR_RAW(dispatch_once, predicate, block); atomic_uint32_t *a = reinterpret_cast(predicate); u32 v = atomic_load(a, memory_order_acquire); if (v == 0 && @@ -241,7 +241,7 @@ #undef dispatch_once_f TSAN_INTERCEPTOR(void, dispatch_once_f, dispatch_once_t *predicate, void *context, dispatch_function_t function) { - SCOPED_TSAN_INTERCEPTOR(dispatch_once_f, predicate, context, function); + SCOPED_INTERCEPTOR_RAW(dispatch_once_f, predicate, context, function); SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); WRAP(dispatch_once)(predicate, ^(void) { function(context); Index: compiler-rt/trunk/test/tsan/Darwin/dispatch_once_deadlock.mm =================================================================== --- compiler-rt/trunk/test/tsan/Darwin/dispatch_once_deadlock.mm +++ compiler-rt/trunk/test/tsan/Darwin/dispatch_once_deadlock.mm @@ -0,0 +1,41 @@ +// Check that calling dispatch_once from a report callback works. + +// RUN: %clang_tsan %s -o %t -framework Foundation +// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 not %run %t 2>&1 | FileCheck %s + +#import +#import + +long g = 0; +long h = 0; +void f() { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + g++; + }); + h++; +} + +extern "C" void __tsan_on_report() { + fprintf(stderr, "Report.\n"); + f(); +} + +int main() { + fprintf(stderr, "Hello world.\n"); + + f(); + + pthread_mutex_t mutex = {0}; + pthread_mutex_lock(&mutex); + + fprintf(stderr, "g = %ld.\n", g); + fprintf(stderr, "h = %ld.\n", h); + fprintf(stderr, "Done.\n"); +} + +// CHECK: Hello world. +// CHECK: Report. +// CHECK: g = 1 +// CHECK: h = 2 +// CHECK: Done.