// Check that dispatch_once() is always intercepted. // RUN: %clang_tsan %s -o %t // RUN: not %env_tsan_opts=ignore_noninstrumented_modules=0 %run %t 2>&1 | FileCheck %s #include #include #include #include "../test.h" long g = 0; long h = 0; __attribute__((disable_sanitizer_instrumentation)) void f() { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ g++; }); h++; } // Required for dyld macOS 12.0+ #if (__APPLE__) __attribute__((weak)) #endif __attribute__((disable_sanitizer_instrumentation)) extern void __tsan_on_report() { fprintf(stderr, "Report.\n"); // Without these annotations this test deadlocks for COMPILER_RT_DEBUG=ON // builds. Conceptually, the TSan runtime does not support reentrancy from // runtime callbacks, but the main goal here is just to check that // dispatch_once() is always intercepted. AnnotateIgnoreSyncBegin(__FILE__, __LINE__); f(); AnnotateIgnoreSyncEnd(__FILE__, __LINE__); } int main() { fprintf(stderr, "Hello world.\n"); f(); pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_unlock(&mutex); // Unlock of an unlocked 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.