1 #include "test.h" 2 3 int Global; 4 5 void __attribute__((noinline)) foo1() { 6 Global = 42; 7 } 8 9 void __attribute__((noinline)) bar1() { 10 volatile int tmp = 42; (void)tmp; 11 foo1(); 12 } 13 14 void __attribute__((noinline)) foo2() { 15 volatile int v = Global; (void)v; 16 } 17 18 void __attribute__((noinline)) bar2() { 19 volatile int tmp = 42; (void)tmp; 20 foo2(); 21 } 22 23 void *Thread1(void *x) { 24 barrier_wait(&barrier); 25 bar1(); 26 return NULL; 27 } 28 29 void *Thread2(void *x) { 30 bar2(); 31 barrier_wait(&barrier); 32 return NULL; 33 } 34 35 void __attribute__((noinline)) StartThread(pthread_t *t, void *(*f)(void*)) { 36 pthread_create(t, NULL, f, NULL); 37 } 38 39 int main() { 40 barrier_init(&barrier, 2); 41 pthread_t t[2]; 42 StartThread(&t[0], Thread1); 43 StartThread(&t[1], Thread2); 44 pthread_join(t[0], NULL); 45 pthread_join(t[1], NULL); 46 return 0; 47 } 48 49 // RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t 2>&1 | FileCheck %s 50 51 // Also check that functions instrumentation can be configured by either driver 52 // or legacy flags: 53 54 // RUN: %clangxx_tsan -O1 %s -o %t -fno-sanitize-thread-func-entry-exit && %deflake %run %t 2>&1 \ 55 // RUN: | FileCheck --check-prefix=CHECK-FUNC-ENTRY-EXIT-OFF %s 56 // RUN: %clangxx_tsan -O1 %s -o %t -mllvm -tsan-instrument-func-entry-exit=0 && %deflake %run %t 2>&1 \ 57 // RUN: | FileCheck --check-prefix=CHECK-FUNC-ENTRY-EXIT-OFF %s 58 59 // CHECK: WARNING: ThreadSanitizer: data race 60 // CHECK-NEXT: Write of size 4 at {{.*}} by thread T1: 61 // CHECK-NEXT: #0 foo1{{.*}} {{.*}}simple_stack.c:6{{(:10)?}} ({{.*}}) 62 // CHECK-NEXT: #1 bar1{{.*}} {{.*}}simple_stack.c:11{{(:3)?}} ({{.*}}) 63 // CHECK-NEXT: #2 Thread1{{.*}} {{.*}}simple_stack.c:25{{(:3)?}} ({{.*}}) 64 // CHECK: Previous read of size 4 at {{.*}} by thread T2: 65 // CHECK-NEXT: #0 foo2{{.*}} {{.*}}simple_stack.c:15{{(:20)?}} ({{.*}}) 66 // CHECK-NEXT: #1 bar2{{.*}} {{.*}}simple_stack.c:20{{(:3)?}} ({{.*}}) 67 // CHECK-NEXT: #2 Thread2{{.*}} {{.*}}simple_stack.c:30{{(:3)?}} ({{.*}}) 68 // CHECK: Thread T1 (tid={{.*}}, running) created by main thread at: 69 // CHECK-NEXT: #0 pthread_create {{.*}} ({{.*}}) 70 // CHECK-NEXT: #1 StartThread{{.*}} {{.*}}simple_stack.c:36{{(:3)?}} ({{.*}}) 71 // CHECK-NEXT: #2 main{{.*}} {{.*}}simple_stack.c:42{{(:3)?}} ({{.*}}) 72 // CHECK: Thread T2 ({{.*}}) created by main thread at: 73 // CHECK-NEXT: #0 pthread_create {{.*}} ({{.*}}) 74 // CHECK-NEXT: #1 StartThread{{.*}} {{.*}}simple_stack.c:36{{(:3)?}} ({{.*}}) 75 // CHECK-NEXT: #2 main{{.*}} {{.*}}simple_stack.c:43{{(:3)?}} ({{.*}}) 76 77 // CHECK-FUNC-ENTRY-EXIT-OFF: WARNING: ThreadSanitizer: data race 78 // CHECK-FUNC-ENTRY-EXIT-OFF-NEXT: Write of size 4 at {{.*}} by thread T1: 79 // CHECK-FUNC-ENTRY-EXIT-OFF-NEXT: #0 foo1{{.*}} {{.*}}simple_stack.c:6{{(:10)?}} ({{.*}}) 80 // CHECK-FUNC-ENTRY-EXIT-OFF: Previous read of size 4 at {{.*}} by thread T2: 81 // CHECK-FUNC-ENTRY-EXIT-OFF-NEXT: #0 foo2{{.*}} {{.*}}simple_stack.c:15{{(:20)?}} ({{.*}}) 82 // CHECK-FUNC-ENTRY-EXIT-OFF: Thread T1 (tid={{.*}}, running) created by main thread at: 83 // CHECK-FUNC-ENTRY-EXIT-OFF-NEXT: #0 pthread_create {{.*}} ({{.*}}) 84 // CHECK-FUNC-ENTRY-EXIT-OFF: Thread T2 ({{.*}}) created by main thread at: 85 // CHECK-FUNC-ENTRY-EXIT-OFF-NEXT: #0 pthread_create {{.*}} ({{.*}}) 86