1 // RUN: %clangxx_tsan %s -o %t
2 // RUN: %deflake %run %t 2>&1 | FileCheck %s
11 int __tsan_get_report_data(void *report
, const char **description
, int *count
,
12 int *stack_count
, int *mop_count
, int *loc_count
,
13 int *mutex_count
, int *thread_count
,
14 int *unique_tid_count
, void **sleep_trace
,
15 unsigned long trace_size
);
16 int __tsan_get_report_tag(void *report
, unsigned long *tag
);
17 int __tsan_get_report_mop(void *report
, unsigned long idx
, int *tid
, void **addr
,
18 int *size
, int *write
, int *atomic
, void **trace
,
19 unsigned long trace_size
);
22 __attribute__((no_sanitize("thread"), noinline
))
23 void ExternalWrite(void *addr
) {
24 void *kSwiftAccessRaceTag
= (void *)0x1;
25 __tsan_external_write(addr
, nullptr, kSwiftAccessRaceTag
);
28 int main(int argc
, char *argv
[]) {
29 barrier_init(&barrier
, 2);
30 fprintf(stderr
, "Start.\n");
33 void *opaque_object
= malloc(16);
34 std::thread
t1([opaque_object
] {
35 ExternalWrite(opaque_object
);
36 barrier_wait(&barrier
);
38 std::thread
t2([opaque_object
] {
39 barrier_wait(&barrier
);
40 ExternalWrite(opaque_object
);
42 // CHECK: WARNING: ThreadSanitizer: Swift access race
43 // CHECK: Modifying access of Swift variable at {{.*}} by thread {{.*}}
44 // CHECK: #0 ExternalWrite
45 // CHECK: Previous modifying access of Swift variable at {{.*}} by thread {{.*}}
46 // CHECK: #0 ExternalWrite
47 // CHECK: SUMMARY: ThreadSanitizer: Swift access race
51 fprintf(stderr
, "Done.\n");
54 extern "C" __attribute__((disable_sanitizer_instrumentation
)) void
55 __tsan_on_report(void *report
) {
56 const char *description
;
58 int stack_count
, mop_count
, loc_count
, mutex_count
, thread_count
,
60 void *sleep_trace
[16] = {0};
61 __tsan_get_report_data(report
, &description
, &count
, &stack_count
, &mop_count
,
62 &loc_count
, &mutex_count
, &thread_count
,
63 &unique_tid_count
, sleep_trace
, 16);
64 fprintf(stderr
, "report type = '%s', count = %d, mop_count = %d\n", description
, count
, mop_count
);
65 // CHECK: report type = 'external-race', count = 0, mop_count = 2
68 __tsan_get_report_tag(report
, &tag
);
69 fprintf(stderr
, "tag = %ld\n", tag
);
72 int tid
, size
, write
, atomic
;
74 void *trace
[16] = {0};
75 __tsan_get_report_mop(report
, /*idx=*/0, &tid
, &addr
, &size
, &write
, &atomic
,
77 fprintf(stderr
, "Racy write trace (1 of 2):\n");
78 for (int i
= 0; i
< 16 && trace
[i
]; i
++) {
80 dladdr(trace
[i
], &info
);
81 fprintf(stderr
, " %d: frame: %p, function: %p %s\n", i
, trace
[i
],
82 info
.dli_saddr
, info
.dli_sname
);
84 // Ensure ExternalWrite() function is top of trace
85 // CHECK: 0: frame: 0x{{[0-9a-z]+}}, function: 0x{{[0-9a-z]+}} _Z13ExternalWritePv
89 // CHECK: ThreadSanitizer: reported 1 warnings