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