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