]>
Commit | Line | Data |
---|---|---|
5bcae85e SL |
1 | // RUN: %clangxx_tsan -O1 %s -o %t |
2 | // RUN: %deflake %run %t 2>&1 | FileCheck %s | |
3 | ||
4 | #include <pthread.h> | |
5 | #include <stdio.h> | |
6 | #include <stdlib.h> | |
7 | #include <string.h> | |
8 | ||
9 | #include "test.h" | |
10 | ||
11 | extern "C" { | |
12 | void __tsan_on_report(void *report); | |
13 | void *__tsan_get_current_report(); | |
14 | int __tsan_get_report_data(void *report, const char **description, int *count, | |
15 | int *stack_count, int *mop_count, int *loc_count, | |
16 | int *mutex_count, int *thread_count, | |
17 | int *unique_tid_count, void **sleep_trace, | |
18 | unsigned long trace_size); | |
19 | int __tsan_get_report_mop(void *report, unsigned long idx, int *tid, | |
20 | void **addr, int *size, int *write, int *atomic, | |
21 | void **trace, unsigned long trace_size); | |
22 | int __tsan_get_report_thread(void *report, unsigned long idx, int *tid, | |
23 | unsigned long *os_id, int *running, | |
24 | const char **name, int *parent_tid, void **trace, | |
25 | unsigned long trace_size); | |
26 | } | |
27 | ||
28 | long my_global; | |
29 | ||
30 | void *Thread(void *a) { | |
31 | barrier_wait(&barrier); | |
32 | my_global = 42; | |
33 | return NULL; | |
34 | } | |
35 | ||
36 | int main() { | |
37 | barrier_init(&barrier, 2); | |
38 | fprintf(stderr, "&my_global = %p\n", &my_global); | |
39 | // CHECK: &my_global = [[GLOBAL:0x[0-9a-f]+]] | |
40 | pthread_t t; | |
41 | pthread_create(&t, 0, Thread, 0); | |
42 | my_global = 41; | |
43 | barrier_wait(&barrier); | |
44 | pthread_join(t, 0); | |
45 | fprintf(stderr, "Done.\n"); | |
46 | } | |
47 | ||
48 | void __tsan_on_report(void *report) { | |
49 | fprintf(stderr, "__tsan_on_report(%p)\n", report); | |
50 | fprintf(stderr, "__tsan_get_current_report() = %p\n", | |
51 | __tsan_get_current_report()); | |
52 | // CHECK: __tsan_on_report([[REPORT:0x[0-9a-f]+]]) | |
53 | // CHECK: __tsan_get_current_report() = [[REPORT]] | |
54 | ||
55 | const char *description; | |
56 | int count; | |
57 | int stack_count, mop_count, loc_count, mutex_count, thread_count, | |
58 | unique_tid_count; | |
59 | void *sleep_trace[16] = {0}; | |
60 | __tsan_get_report_data(report, &description, &count, &stack_count, &mop_count, | |
61 | &loc_count, &mutex_count, &thread_count, | |
62 | &unique_tid_count, sleep_trace, 16); | |
63 | fprintf(stderr, "report type = '%s', count = %d\n", description, count); | |
64 | // CHECK: report type = 'data-race', count = 0 | |
65 | ||
66 | fprintf(stderr, "mop_count = %d\n", mop_count); | |
67 | // CHECK: mop_count = 2 | |
68 | ||
69 | int tid; | |
70 | void *addr; | |
71 | int size, write, atomic; | |
72 | void *trace[16] = {0}; | |
73 | ||
74 | __tsan_get_report_mop(report, 0, &tid, &addr, &size, &write, &atomic, trace, | |
75 | 16); | |
76 | fprintf(stderr, "tid = %d, addr = %p, size = %d, write = %d, atomic = %d\n", | |
77 | tid, addr, size, write, atomic); | |
78 | // CHECK: tid = 1, addr = [[GLOBAL]], size = 8, write = 1, atomic = 0 | |
79 | fprintf(stderr, "trace[0] = %p, trace[1] = %p\n", trace[0], trace[1]); | |
80 | // CHECK: trace[0] = 0x{{[0-9a-f]+}}, trace[1] = {{0x0|\(nil\)|\(null\)}} | |
81 | ||
82 | __tsan_get_report_mop(report, 1, &tid, &addr, &size, &write, &atomic, trace, | |
83 | 16); | |
84 | fprintf(stderr, "tid = %d, addr = %p, size = %d, write = %d, atomic = %d\n", | |
85 | tid, addr, size, write, atomic); | |
86 | // CHECK: tid = 0, addr = [[GLOBAL]], size = 8, write = 1, atomic = 0 | |
87 | fprintf(stderr, "trace[0] = %p, trace[1] = %p\n", trace[0], trace[1]); | |
88 | // CHECK: trace[0] = 0x{{[0-9a-f]+}}, trace[1] = {{0x0|\(nil\)|\(null\)}} | |
89 | ||
90 | fprintf(stderr, "thread_count = %d\n", thread_count); | |
91 | // CHECK: thread_count = 2 | |
92 | ||
93 | unsigned long os_id; | |
94 | int running; | |
95 | const char *name; | |
96 | int parent_tid; | |
97 | ||
98 | __tsan_get_report_thread(report, 0, &tid, &os_id, &running, &name, &parent_tid, trace, 16); | |
99 | fprintf(stderr, "tid = %d\n", tid); | |
100 | // CHECK: tid = 1 | |
101 | ||
102 | __tsan_get_report_thread(report, 1, &tid, &os_id, &running, &name, &parent_tid, trace, 16); | |
103 | fprintf(stderr, "tid = %d\n", tid); | |
104 | // CHECK: tid = 0 | |
105 | } | |
106 | ||
107 | // CHECK: Done. | |
108 | // CHECK: ThreadSanitizer: reported 1 warnings |