diff options
Diffstat (limited to 'test/tsan/debug_alloc_stack.cc')
-rw-r--r-- | test/tsan/debug_alloc_stack.cc | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/test/tsan/debug_alloc_stack.cc b/test/tsan/debug_alloc_stack.cc new file mode 100644 index 0000000000000..303c103206f8e --- /dev/null +++ b/test/tsan/debug_alloc_stack.cc @@ -0,0 +1,84 @@ +// RUN: %clangxx_tsan -O0 %s -o %t +// RUN: env %env_tsan_opts=stack_trace_format=DEFAULT %deflake %run %t 2>&1 | FileCheck %s + +// Until I figure out how to make this test work on Linux +// REQUIRES: system-darwin + +#include "test.h" +#include <pthread.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +#ifndef __APPLE__ +#include <sys/types.h> +#endif + +extern "C" int __tsan_get_alloc_stack(void *addr, void **trace, size_t size, + int *thread_id, void *os_id); + +char *mem; +void alloc_func() { mem = (char *)malloc(10); } + +void *AllocThread(void *context) { + uint64_t tid; +#ifdef __APPLE__ + pthread_threadid_np(NULL, &tid); +#else + tid = gettid(); +#endif + fprintf(stderr, "alloc stack thread os id = 0x%llx\n", tid); + // CHECK: alloc stack thread os id = [[THREAD_OS_ID:0x[0-9a-f]+]] + alloc_func(); + return NULL; +} + +void *RaceThread(void *context) { + *mem = 'a'; + barrier_wait(&barrier); + return NULL; +} + +int main() { + pthread_t t; + barrier_init(&barrier, 2); + + pthread_create(&t, NULL, AllocThread, NULL); + pthread_join(t, NULL); + + void *trace[100]; + size_t num_frames = 100; + int thread_id; + void *thread_os_id; + num_frames = + __tsan_get_alloc_stack(mem, trace, num_frames, &thread_id, &thread_os_id); + + fprintf(stderr, "alloc stack retval %s\n", + (num_frames > 0 && num_frames < 10) ? "ok" : ""); + // CHECK: alloc stack retval ok + fprintf(stderr, "thread id = %d\n", thread_id); + // CHECK: thread id = 1 + fprintf(stderr, "thread os id = 0x%llx\n", (uint64_t)thread_os_id); + // CHECK: thread os id = [[THREAD_OS_ID]] + fprintf(stderr, "%p\n", trace[0]); + // CHECK: [[ALLOC_FRAME_0:0x[0-9a-f]+]] + fprintf(stderr, "%p\n", trace[1]); + // CHECK: [[ALLOC_FRAME_1:0x[0-9a-f]+]] + fprintf(stderr, "%p\n", trace[2]); + // CHECK: [[ALLOC_FRAME_2:0x[0-9a-f]+]] + + pthread_create(&t, NULL, RaceThread, NULL); + barrier_wait(&barrier); + mem[0] = 'b'; + pthread_join(t, NULL); + + free(mem); + + return 0; +} + +// CHECK: WARNING: ThreadSanitizer: data race +// CHECK: Location is heap block of size 10 at {{.*}} allocated by thread T1 +// CHECK: #0 [[ALLOC_FRAME_0]] +// CHECK: #1 [[ALLOC_FRAME_1]] in alloc_func +// CHECK: #2 [[ALLOC_FRAME_2]] in AllocThread |