-
Notifications
You must be signed in to change notification settings - Fork 12.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[tsan] Implement __tsan_get_alloc_stack and __tsan_locate_address to …
…query pointer types and allocation stacks of heap pointers In ASan, we have __asan_locate_address and __asan_get_alloc_stack, which is used in LLDB/Xcode to show the allocation backtrace for a heap memory object. This patch implements the same for TSan. Differential Revision: https://reviews.llvm.org/D27656 llvm-svn: 290119
- Loading branch information
1 parent
dd46b52
commit 1187cbd
Showing
5 changed files
with
212 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// RUN: %clangxx_tsan -O0 %s -o %t | ||
// RUN: env %env_tsan_opts=stack_trace_format=DEFAULT %deflake %run %t 2>&1 | FileCheck %s | ||
|
||
#include "test.h" | ||
#include <pthread.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
#if !__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; | ||
#if __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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// RUN: %clangxx_tsan -O0 %s -o %t | ||
// RUN: %run %t 2>&1 | FileCheck %s | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
extern "C" const char * | ||
__tsan_locate_address(void *addr, char *name, size_t name_size, | ||
void **region_address_ptr, size_t *region_size_ptr); | ||
|
||
long global_var; | ||
|
||
int main() { | ||
long stack_var; | ||
void *heap_var = malloc(10); | ||
|
||
fprintf(stderr, "stack_var = %p\n", &stack_var); | ||
fprintf(stderr, "global_var = %p\n", &global_var); | ||
fprintf(stderr, "heap_var = %p\n", heap_var); | ||
// CHECK: stack_var = [[STACK_VAR:0x[0-9a-f]+]] | ||
// CHECK: global_var = [[GLOBAL_VAR:0x[0-9a-f]+]] | ||
// CHECK: heap_var = [[HEAP_VAR:0x[0-9a-f]+]] | ||
|
||
const char *type; | ||
char name[128]; | ||
void *start; | ||
size_t size; | ||
type = __tsan_locate_address(&stack_var, name, 128, &start, &size); | ||
fprintf(stderr, "type: %s\n", type); | ||
// CHECK: type: stack | ||
|
||
type = __tsan_locate_address(&global_var, name, 128, &start, &size); | ||
fprintf(stderr, "type: %s, name = %s, start = %p, size = %zu\n", type, name, | ||
start, size); | ||
// CHECK: type: global, name = global_var, start = [[GLOBAL_VAR]], size = 8 | ||
|
||
type = __tsan_locate_address(heap_var, name, 128, &start, &size); | ||
fprintf(stderr, "type: %s, start = %p, size = %zu\n", type, start, size); | ||
// CHECK: type: heap, start = [[HEAP_VAR]], size = 10 | ||
|
||
free(heap_var); | ||
return 0; | ||
} |