Index: lib/tsan/rtl/tsan_interceptors.h =================================================================== --- lib/tsan/rtl/tsan_interceptors.h +++ lib/tsan/rtl/tsan_interceptors.h @@ -26,6 +26,13 @@ (void)pc; \ /**/ +#define UNSCOPED_INTERCEPTOR_RAW(func, ...) \ + ThreadState *thr = cur_thread(); \ + (void)thr; \ + const uptr pc = StackTrace::GetCurrentPc(); \ + (void)pc; \ +/**/ + #define SCOPED_TSAN_INTERCEPTOR(func, ...) \ SCOPED_INTERCEPTOR_RAW(func, __VA_ARGS__); \ if (REAL(func) == 0) { \ @@ -36,6 +43,16 @@ return REAL(func)(__VA_ARGS__); \ /**/ +#define UNSCOPED_TSAN_INTERCEPTOR(func, ...) \ + UNSCOPED_INTERCEPTOR_RAW(func, __VA_ARGS__); \ + if (REAL(func) == 0) { \ + Report("FATAL: ThreadSanitizer: failed to intercept %s\n", #func); \ + Die(); \ + } \ + if (thr->ignore_interceptors || thr->in_ignored_lib) \ + return REAL(func)(__VA_ARGS__); \ +/**/ + #define TSAN_INTERCEPTOR(ret, func, ...) INTERCEPTOR(ret, func, __VA_ARGS__) #if SANITIZER_FREEBSD Index: lib/tsan/rtl/tsan_libdispatch_mac.cc =================================================================== --- lib/tsan/rtl/tsan_libdispatch_mac.cc +++ lib/tsan/rtl/tsan_libdispatch_mac.cc @@ -79,7 +79,7 @@ } static void dispatch_callback_wrap_acquire(void *param) { - SCOPED_INTERCEPTOR_RAW(dispatch_async_f_callback_wrap); + UNSCOPED_INTERCEPTOR_RAW(dispatch_async_f_callback_wrap); tsan_block_context_t *context = (tsan_block_context_t *)param; Acquire(thr, pc, context->object_to_acquire); // In serial queues, work items can be executed on different threads, we need @@ -98,7 +98,7 @@ #define DISPATCH_INTERCEPT_B(name) \ TSAN_INTERCEPTOR(void, name, dispatch_queue_t q, dispatch_block_t block) { \ - SCOPED_TSAN_INTERCEPTOR(name, q, block); \ + UNSCOPED_TSAN_INTERCEPTOR(name, q, block); \ dispatch_block_t heap_block = Block_copy(block); \ tsan_block_context_t *new_context = \ AllocContext(thr, pc, q, heap_block, &invoke_and_release_block); \ @@ -109,7 +109,7 @@ #define DISPATCH_INTERCEPT_F(name) \ TSAN_INTERCEPTOR(void, name, dispatch_queue_t q, void *context, \ dispatch_function_t work) { \ - SCOPED_TSAN_INTERCEPTOR(name, q, context, work); \ + UNSCOPED_TSAN_INTERCEPTOR(name, q, context, work); \ tsan_block_context_t *new_context = \ AllocContext(thr, pc, q, context, work); \ Release(thr, pc, (uptr)new_context); \ @@ -144,7 +144,7 @@ #undef dispatch_once TSAN_INTERCEPTOR(void, dispatch_once, dispatch_once_t *predicate, dispatch_block_t block) { - SCOPED_TSAN_INTERCEPTOR(dispatch_once, predicate, block); + UNSCOPED_TSAN_INTERCEPTOR(dispatch_once, predicate, block); atomic_uint32_t *a = reinterpret_cast(predicate); u32 v = atomic_load(a, memory_order_acquire); if (v == 0 && @@ -164,7 +164,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); + UNSCOPED_TSAN_INTERCEPTOR(dispatch_once_f, predicate, context, function); WRAP(dispatch_once)(predicate, ^(void) { function(context); }); @@ -172,14 +172,14 @@ TSAN_INTERCEPTOR(long_t, dispatch_semaphore_signal, dispatch_semaphore_t dsema) { - SCOPED_TSAN_INTERCEPTOR(dispatch_semaphore_signal, dsema); + UNSCOPED_TSAN_INTERCEPTOR(dispatch_semaphore_signal, dsema); Release(thr, pc, (uptr)dsema); return REAL(dispatch_semaphore_signal)(dsema); } TSAN_INTERCEPTOR(long_t, dispatch_semaphore_wait, dispatch_semaphore_t dsema, dispatch_time_t timeout) { - SCOPED_TSAN_INTERCEPTOR(dispatch_semaphore_wait, dsema, timeout); + UNSCOPED_TSAN_INTERCEPTOR(dispatch_semaphore_wait, dsema, timeout); long_t result = REAL(dispatch_semaphore_wait)(dsema, timeout); if (result == 0) Acquire(thr, pc, (uptr)dsema); return result; @@ -187,21 +187,21 @@ TSAN_INTERCEPTOR(long_t, dispatch_group_wait, dispatch_group_t group, dispatch_time_t timeout) { - SCOPED_TSAN_INTERCEPTOR(dispatch_group_wait, group, timeout); + UNSCOPED_TSAN_INTERCEPTOR(dispatch_group_wait, group, timeout); long_t result = REAL(dispatch_group_wait)(group, timeout); if (result == 0) Acquire(thr, pc, (uptr)group); return result; } TSAN_INTERCEPTOR(void, dispatch_group_leave, dispatch_group_t group) { - SCOPED_TSAN_INTERCEPTOR(dispatch_group_leave, group); + UNSCOPED_TSAN_INTERCEPTOR(dispatch_group_leave, group); Release(thr, pc, (uptr)group); REAL(dispatch_group_leave)(group); } TSAN_INTERCEPTOR(void, dispatch_group_async, dispatch_group_t group, dispatch_queue_t queue, dispatch_block_t block) { - SCOPED_TSAN_INTERCEPTOR(dispatch_group_async, group, queue, block); + UNSCOPED_TSAN_INTERCEPTOR(dispatch_group_async, group, queue, block); dispatch_retain(group); dispatch_group_enter(group); WRAP(dispatch_async)(queue, ^(void) { @@ -214,7 +214,8 @@ TSAN_INTERCEPTOR(void, dispatch_group_async_f, dispatch_group_t group, dispatch_queue_t queue, void *context, dispatch_function_t work) { - SCOPED_TSAN_INTERCEPTOR(dispatch_group_async_f, group, queue, context, work); + UNSCOPED_TSAN_INTERCEPTOR(dispatch_group_async_f, group, queue, context, + work); dispatch_retain(group); dispatch_group_enter(group); WRAP(dispatch_async)(queue, ^(void) { @@ -226,7 +227,7 @@ TSAN_INTERCEPTOR(void, dispatch_group_notify, dispatch_group_t group, dispatch_queue_t q, dispatch_block_t block) { - SCOPED_TSAN_INTERCEPTOR(dispatch_group_notify, group, q, block); + UNSCOPED_TSAN_INTERCEPTOR(dispatch_group_notify, group, q, block); dispatch_block_t heap_block = Block_copy(block); tsan_block_context_t *new_context = AllocContext(thr, pc, q, heap_block, &invoke_and_release_block); @@ -238,7 +239,7 @@ TSAN_INTERCEPTOR(void, dispatch_group_notify_f, dispatch_group_t group, dispatch_queue_t q, void *context, dispatch_function_t work) { - SCOPED_TSAN_INTERCEPTOR(dispatch_group_notify_f, group, q, context, work); + UNSCOPED_TSAN_INTERCEPTOR(dispatch_group_notify_f, group, q, context, work); tsan_block_context_t *new_context = AllocContext(thr, pc, q, context, work); new_context->object_to_acquire = (uptr)group; Release(thr, pc, (uptr)group);