1 // Check that dispatch_once() is always intercepted. 2 3 // RUN: %clang_tsan %s -o %t 4 // RUN: not %env_tsan_opts=ignore_noninstrumented_modules=0 %run %t 2>&1 | FileCheck %s 5 6 #include <dispatch/dispatch.h> 7 8 #include <pthread.h> 9 #include <stdio.h> 10 11 #include "../test.h" 12 13 long g = 0; 14 long h = 0; 15 16 __attribute__((disable_sanitizer_instrumentation)) 17 void f() { 18 static dispatch_once_t onceToken; 19 dispatch_once(&onceToken, ^{ 20 g++; 21 }); 22 h++; 23 } 24 25 __attribute__((disable_sanitizer_instrumentation)) 26 void __tsan_on_report() { 27 fprintf(stderr, "Report.\n"); 28 29 // Without these annotations this test deadlocks for COMPILER_RT_DEBUG=ON 30 // builds. Conceptually, the TSan runtime does not support reentrancy from 31 // runtime callbacks, but the main goal here is just to check that 32 // dispatch_once() is always intercepted. 33 AnnotateIgnoreSyncBegin(__FILE__, __LINE__); 34 f(); 35 AnnotateIgnoreSyncEnd(__FILE__, __LINE__); 36 } 37 38 int main() { 39 fprintf(stderr, "Hello world.\n"); 40 41 f(); 42 43 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 44 pthread_mutex_unlock(&mutex); // Unlock of an unlocked mutex 45 46 fprintf(stderr, "g = %ld.\n", g); 47 fprintf(stderr, "h = %ld.\n", h); 48 fprintf(stderr, "Done.\n"); 49 } 50 51 // CHECK: Hello world. 52 // CHECK: Report. 53 // CHECK: g = 1 54 // CHECK: h = 2 55 // CHECK: Done. 56