1// RUN: %clangxx_tsan %s -o %t
2// RUN: %deflake %run %t 2>&1 | FileCheck %s
3
4#include <dlfcn.h>
5#include <thread>
6
7#import "../test.h"
8
9
10extern "C" {
11int __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);
16int __tsan_get_report_tag(void *report, unsigned long *tag);
17int __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);
20}
21
22__attribute__((no_sanitize("thread"), noinline))
23void ExternalWrite(void *addr) {
24 void *kSwiftAccessRaceTag = (void *)0x1;
25 __tsan_external_write(addr, caller_pc: nullptr, tag: kSwiftAccessRaceTag);
26}
27
28int main(int argc, char *argv[]) {
29 barrier_init(barrier: &barrier, count: 2);
30 fprintf(stderr, format: "Start.\n");
31 // CHECK: Start.
32
33 void *opaque_object = malloc(size: 16);
34 std::thread t1([opaque_object] {
35 ExternalWrite(opaque_object);
36 barrier_wait(&barrier);
37 });
38 std::thread t2([opaque_object] {
39 barrier_wait(&barrier);
40 ExternalWrite(opaque_object);
41 });
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
48 t1.join();
49 t2.join();
50
51 fprintf(stderr, format: "Done.\n");
52}
53
54extern "C" __attribute__((disable_sanitizer_instrumentation)) void
55__tsan_on_report(void *report) {
56 const char *description;
57 int count;
58 int stack_count, mop_count, loc_count, mutex_count, thread_count,
59 unique_tid_count;
60 void *sleep_trace[16] = {0};
61 __tsan_get_report_data(report, description: &description, count: &count, stack_count: &stack_count, mop_count: &mop_count,
62 loc_count: &loc_count, mutex_count: &mutex_count, thread_count: &thread_count,
63 unique_tid_count: &unique_tid_count, sleep_trace, trace_size: 16);
64 fprintf(stderr, format: "report type = '%s', count = %d, mop_count = %d\n", description, count, mop_count);
65 // CHECK: report type = 'external-race', count = 0, mop_count = 2
66
67 unsigned long tag;
68 __tsan_get_report_tag(report, tag: &tag);
69 fprintf(stderr, format: "tag = %ld\n", tag);
70 // CHECK: tag = 1
71
72 int tid, size, write, atomic;
73 void *addr;
74 void *trace[16] = {0};
75 __tsan_get_report_mop(report, /*idx=*/0, tid: &tid, addr: &addr, size: &size, write: &write, atomic: &atomic,
76 trace, trace_size: 16);
77 fprintf(stderr, format: "Racy write trace (1 of 2):\n");
78 for (int i = 0; i < 16 && trace[i]; i++) {
79 Dl_info info;
80 dladdr(address: trace[i], info: &info);
81 fprintf(stderr, format: " %d: frame: %p, function: %p %s\n", i, trace[i],
82 info.dli_saddr, info.dli_sname);
83 }
84 // Ensure ExternalWrite() function is top of trace
85 // CHECK: 0: frame: 0x{{[0-9a-z]+}}, function: 0x{{[0-9a-z]+}} _Z13ExternalWritePv
86}
87
88// CHECK: Done.
89// CHECK: ThreadSanitizer: reported 1 warnings
90

source code of compiler-rt/test/tsan/Darwin/external-swift-debugging.cpp