1 | // RUN: %clangxx_dfsan %s -fno-exceptions -o %t && %run %t |
2 | // RUN: %clangxx_dfsan -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 %s -fno-exceptions -o %t && %run %t |
3 | // |
4 | // Use -fno-exceptions to turn off exceptions to avoid instrumenting |
5 | // __cxa_begin_catch, std::terminate and __gxx_personality_v0. |
6 | // |
7 | // TODO: Support builtin atomics. For example, https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html |
8 | // DFSan instrumentation pass cannot identify builtin callsites yet. |
9 | |
10 | #include <sanitizer/dfsan_interface.h> |
11 | |
12 | #include <assert.h> |
13 | #include <atomic> |
14 | #include <pthread.h> |
15 | |
16 | std::atomic<int> atomic_i{0}; |
17 | |
18 | struct arg_struct { |
19 | size_t index; |
20 | dfsan_origin origin; |
21 | }; |
22 | |
23 | static void *ThreadFn(void *arg) { |
24 | if (((arg_struct *)arg)->index % 2) { |
25 | int i = 10; |
26 | dfsan_set_label(label: 8, addr: (void *)&i, size: sizeof(i)); |
27 | atomic_i.store(i, std::memory_order_relaxed); |
28 | return 0; |
29 | } |
30 | int j = atomic_i.load(); |
31 | assert(dfsan_get_label(j) == 0 || dfsan_get_label(j) == 2); |
32 | #ifdef ORIGIN_TRACKING |
33 | if (dfsan_get_label(j) == 2) |
34 | assert(dfsan_get_init_origin(&j) == ((arg_struct *)arg)->origin); |
35 | #endif |
36 | return 0; |
37 | } |
38 | |
39 | int main(void) { |
40 | int i = 10; |
41 | dfsan_set_label(label: 2, addr: (void *)&i, size: sizeof(i)); |
42 | #ifdef ORIGIN_TRACKING |
43 | dfsan_origin origin = dfsan_get_origin(i); |
44 | #endif |
45 | atomic_i.store(i, std::memory_order_relaxed); |
46 | const int kNumThreads = 24; |
47 | pthread_t t[kNumThreads]; |
48 | arg_struct args[kNumThreads]; |
49 | for (int i = 0; i < kNumThreads; ++i) { |
50 | args[i].index = i; |
51 | #ifdef ORIGIN_TRACKING |
52 | args[i].origin = origin; |
53 | #endif |
54 | pthread_create(newthread: &t[i], attr: 0, start_routine: ThreadFn, arg: (void *)(args + i)); |
55 | } |
56 | for (int i = 0; i < kNumThreads; ++i) |
57 | pthread_join(th: t[i], thread_return: 0); |
58 | return 0; |
59 | } |
60 | |