1 | // RUN: %clangxx_tsan -O0 %s -o %t |
2 | // RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-RACE |
3 | // Test size larger than clear_shadow_mmap_threshold, which is handled differently. |
4 | // RUN: not %run %t - 262144 2>&1 | FileCheck %s --check-prefix=CHECK-RACE |
5 | // RUN: %run %t ignore 2>&1 | FileCheck %s --check-prefix=CHECK-IGNORE |
6 | |
7 | #include <sys/mman.h> |
8 | #include <string.h> |
9 | #include <assert.h> |
10 | #include <atomic> |
11 | |
12 | #include "test.h" |
13 | |
14 | // Use atomic to ensure we do not have a race for the pointer value itself. We |
15 | // only want to check races in the mmap'd memory to isolate the test that mmap |
16 | // respects ignore annotations. |
17 | std::atomic<int*> global_p; |
18 | |
19 | void mmap_ignored(bool ignore, size_t size) { |
20 | if (ignore) AnnotateIgnoreWritesBegin(__FILE__, __LINE__); |
21 | void *p = |
22 | mmap(addr: 0, len: size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, fd: -1, offset: 0); |
23 | if (ignore) AnnotateIgnoreWritesEnd(__FILE__, __LINE__); |
24 | |
25 | // Use relaxed to retain the race between the mmap call and the memory write |
26 | global_p.store((int *)p, std::memory_order_relaxed); |
27 | barrier_wait(barrier: &barrier); |
28 | } |
29 | |
30 | void *WriteToMemory(void *unused) { |
31 | barrier_wait(barrier: &barrier); |
32 | global_p[0] = 7; |
33 | return 0; |
34 | } |
35 | |
36 | // Create race between allocating (mmap) and writing memory |
37 | int main(int argc, const char *argv[]) { |
38 | bool ignore = (argc > 1) && (strcmp(s1: argv[1], s2: "ignore" ) == 0); |
39 | size_t size = argc > 2 ? atoi(nptr: argv[2]) : sysconf(_SC_PAGESIZE); |
40 | |
41 | barrier_init(barrier: &barrier, count: 2); |
42 | pthread_t t; |
43 | pthread_create(newthread: &t, attr: 0, start_routine: WriteToMemory, arg: 0); |
44 | mmap_ignored(ignore, size); |
45 | pthread_join(th: t, thread_return: 0); |
46 | |
47 | assert(global_p[0] == 7); |
48 | printf(format: "OK\n" ); |
49 | return 0; |
50 | } |
51 | |
52 | // CHECK-RACE: WARNING: ThreadSanitizer: data race |
53 | // CHECK-RACE: OK |
54 | // CHECK-IGNORE-NOT: WARNING: ThreadSanitizer: data race |
55 | // CHECK-IGNORE: OK |
56 | |