xref: /llvm-project/compiler-rt/test/tsan/debug_alloc_stack.cpp (revision 52ebd8d0577e07be9c25b56656d1974a84c40bf7)
1 // RUN: %clangxx_tsan -O0 %s -o %t
2 // RUN: env %env_tsan_opts=stack_trace_format=DEFAULT %deflake %run %t 2>&1 | FileCheck %s
3 
4 #include "test.h"
5 #include <pthread.h>
6 #include <stdint.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 
10 #ifndef __APPLE__
11 #include <sys/types.h>
12 #endif
13 
14 extern "C" int __tsan_get_alloc_stack(void *addr, void **trace, size_t size,
15                                       int *thread_id, uint64_t *os_id);
16 
17 char *mem;
18 void alloc_func() { mem = (char *)malloc(10); }
19 
20 void *AllocThread(void *context) {
21   uint64_t tid;
22 #ifdef __APPLE__
23   pthread_threadid_np(NULL, &tid);
24 #else
25   tid = gettid();
26 #endif
27   fprintf(stderr, "alloc stack thread os id = 0x%llx\n", tid);
28   // CHECK: alloc stack thread os id = [[THREAD_OS_ID:0x[0-9a-f]+]]
29   alloc_func();
30   return NULL;
31 }
32 
33 void *RaceThread(void *context) {
34   *mem = 'a';
35   barrier_wait(&barrier);
36   return NULL;
37 }
38 
39 int main() {
40   pthread_t t;
41   barrier_init(&barrier, 2);
42 
43   pthread_create(&t, NULL, AllocThread, NULL);
44   pthread_join(t, NULL);
45 
46   void *trace[100];
47   size_t num_frames = 100;
48   int thread_id;
49   uint64_t thread_os_id;
50   num_frames =
51       __tsan_get_alloc_stack(mem, trace, num_frames, &thread_id, &thread_os_id);
52 
53   fprintf(stderr, "alloc stack retval %s\n",
54           (num_frames > 0 && num_frames < 10) ? "ok" : "");
55   // CHECK: alloc stack retval ok
56   fprintf(stderr, "thread id = %d\n", thread_id);
57   // CHECK: thread id = 1
58   fprintf(stderr, "thread os id = 0x%llx\n", thread_os_id);
59   // CHECK: thread os id = [[THREAD_OS_ID]]
60   fprintf(stderr, "%p\n", trace[0]);
61   // CHECK: 0x{{0*}}[[ALLOC_FRAME_0:[0-9a-f]+]]
62   fprintf(stderr, "%p\n", trace[1]);
63   // CHECK: 0x{{0*}}[[ALLOC_FRAME_1:[0-9a-f]+]]
64   fprintf(stderr, "%p\n", trace[2]);
65   // CHECK: 0x{{0*}}[[ALLOC_FRAME_2:[0-9a-f]+]]
66 
67   pthread_create(&t, NULL, RaceThread, NULL);
68   barrier_wait(&barrier);
69   mem[0] = 'b';
70   pthread_join(t, NULL);
71 
72   free(mem);
73 
74   return 0;
75 }
76 
77 // CHECK: WARNING: ThreadSanitizer: data race
78 // CHECK: Location is heap block of size 10 at {{.*}} allocated by thread T1
79 // CHECK: #0 0x{{0*}}[[ALLOC_FRAME_0]]
80 // CHECK: #1 0x{{0*}}[[ALLOC_FRAME_1]] in alloc_func
81 // CHECK: #2 0x{{0*}}[[ALLOC_FRAME_2]] in AllocThread
82