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