1 | // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s |
2 | |
3 | #include "test.h" |
4 | |
5 | extern "C" { |
6 | void __tsan_on_report(void *report); |
7 | void *__tsan_get_current_report(); |
8 | int __tsan_get_report_data(void *report, const char **description, int *count, |
9 | int *stack_count, int *mop_count, int *loc_count, |
10 | int *mutex_count, int *thread_count, |
11 | int *unique_tid_count, void **sleep_trace, |
12 | unsigned long trace_size); |
13 | int __tsan_get_report_stack(void *report, unsigned long idx, void **trace, |
14 | unsigned long trace_size); |
15 | int __tsan_get_report_mutex(void *report, unsigned long idx, uint64_t *mutex_id, |
16 | void **addr, int *destroyed, void **trace, |
17 | unsigned long trace_size); |
18 | } |
19 | |
20 | int main() { |
21 | int m = 0; |
22 | fprintf(stderr, format: "&m = %p\n" , &m); |
23 | // CHECK: &m = [[MUTEX:0x[0-9a-f]+]] |
24 | AnnotateRWLockReleased(__FILE__, __LINE__, m: &m, is_w: 1); |
25 | fprintf(stderr, format: "Done.\n" ); |
26 | return 0; |
27 | } |
28 | |
29 | // Required for dyld macOS 12.0+ |
30 | #if (__APPLE__) |
31 | __attribute__((weak)) |
32 | #endif |
33 | __attribute__((disable_sanitizer_instrumentation)) extern "C" void |
34 | __tsan_on_report(void *report) { |
35 | fprintf(stderr, format: "__tsan_on_report(%p)\n" , report); |
36 | fprintf(stderr, format: "__tsan_get_current_report() = %p\n" , |
37 | __tsan_get_current_report()); |
38 | // CHECK: __tsan_on_report([[REPORT:0x[0-9a-f]+]]) |
39 | // CHECK: __tsan_get_current_report() = [[REPORT]] |
40 | |
41 | const char *description; |
42 | int count; |
43 | int stack_count, mop_count, loc_count, mutex_count, thread_count, |
44 | unique_tid_count; |
45 | void *sleep_trace[16] = {0}; |
46 | __tsan_get_report_data(report, description: &description, count: &count, stack_count: &stack_count, mop_count: &mop_count, |
47 | loc_count: &loc_count, mutex_count: &mutex_count, thread_count: &thread_count, |
48 | unique_tid_count: &unique_tid_count, sleep_trace, trace_size: 16); |
49 | |
50 | fprintf(stderr, format: "stack_count = %d\n" , stack_count); |
51 | // CHECK: stack_count = 1 |
52 | |
53 | fprintf(stderr, format: "mutex_count = %d\n" , mutex_count); |
54 | // CHECK: mutex_count = 1 |
55 | |
56 | void *trace[16] = {0}; |
57 | __tsan_get_report_stack(report, idx: 0, trace, trace_size: 16); |
58 | |
59 | fprintf(stderr, format: "trace[0] = %p, trace[1] = %p, trace[2] = %p\n" , trace[0], |
60 | trace[1], trace[2]); |
61 | // CHECK: trace[0] = 0x{{[0-9a-f]+}}, trace[1] = 0x{{[0-9a-f]+}}, trace[2] = |
62 | // {{0x0|\(nil\)|\(null\)}} |
63 | |
64 | uint64_t mutex_id; |
65 | void *addr; |
66 | int destroyed; |
67 | __tsan_get_report_mutex(report, idx: 0, mutex_id: &mutex_id, addr: &addr, destroyed: &destroyed, trace, trace_size: 16); |
68 | fprintf(stderr, format: "addr = %p, destroyed = %d\n" , addr, destroyed); |
69 | // CHECK: addr = [[MUTEX]], destroyed = 0 |
70 | fprintf(stderr, format: "trace[0] = %p, trace[1] = %p, trace[2] = %p\n" , trace[0], |
71 | trace[1], trace[2]); |
72 | // CHECK: trace[0] = 0x{{[0-9a-f]+}}, trace[1] = 0x{{[0-9a-f]+}}, trace[2] = |
73 | // {{0x0|\(nil\)|\(null\)}} |
74 | } |
75 | |
76 | // CHECK: Done. |
77 | // CHECK: ThreadSanitizer: reported 1 warnings |
78 | |