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 | int __tsan_get_report_loc(void *report, unsigned long idx, const char **type, |
14 | void **addr, void **start, |
15 | unsigned long *size, int *tid, int *fd, |
16 | int *suppressable, void **trace, |
17 | unsigned long trace_size); |
18 | int __tsan_get_report_loc_object_type(void *report, unsigned long idx, |
19 | const char **object_type); |
20 | } |
21 | |
22 | void *Thread(void *arg) { |
23 | barrier_wait(barrier: &barrier); |
24 | *((long *)arg) = 42; |
25 | return NULL; |
26 | } |
27 | |
28 | int main() { |
29 | barrier_init(barrier: &barrier, count: 2); |
30 | void *tag = __tsan_external_register_tag(object_type: "MyObject" ); |
31 | long *obj = (long *)malloc(size: sizeof(long)); |
32 | fprintf(stderr, format: "obj = %p\n" , obj); |
33 | // CHECK: obj = [[ADDR:0x[0-9a-f]+]] |
34 | __tsan_external_assign_tag(addr: obj, tag); |
35 | |
36 | pthread_t t; |
37 | pthread_create(newthread: &t, attr: 0, start_routine: Thread, arg: obj); |
38 | *obj = 41; |
39 | barrier_wait(barrier: &barrier); |
40 | pthread_join(th: t, thread_return: 0); |
41 | fprintf(stderr, format: "Done.\n" ); |
42 | return 0; |
43 | } |
44 | |
45 | // Required for dyld macOS 12.0+ |
46 | #if (__APPLE__) |
47 | __attribute__((weak)) |
48 | #endif |
49 | __attribute__((disable_sanitizer_instrumentation)) |
50 | extern "C" void |
51 | __tsan_on_report(void *report) { |
52 | const char *type; |
53 | void *addr; |
54 | void *start; |
55 | unsigned long size; |
56 | int tid, fd, suppressable; |
57 | void *trace[16] = {0}; |
58 | __tsan_get_report_loc(report, idx: 0, type: &type, addr: &addr, start: &start, size: &size, tid: &tid, fd: &fd, |
59 | suppressable: &suppressable, trace, trace_size: 16); |
60 | fprintf(stderr, format: "type = %s, start = %p, size = %ld\n" , type, start, size); |
61 | // CHECK: type = heap, start = [[ADDR]], size = 8 |
62 | |
63 | const char *object_type; |
64 | __tsan_get_report_loc_object_type(report, idx: 0, object_type: &object_type); |
65 | fprintf(stderr, format: "object_type = %s\n" , object_type); |
66 | // CHECK: object_type = MyObject |
67 | } |
68 | |
69 | // CHECK: Done. |
70 | // CHECK: ThreadSanitizer: reported 1 warnings |
71 | |