1 // Check that the stack trace debugging API works and returns correct 2 // malloc and free stacks. 3 // RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s 4 5 // FIXME: Figure out why allocation/free stack traces may be too short on ARM. 6 // REQUIRES: stable-runtime 7 8 #include <sanitizer/asan_interface.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 12 char *mem; 13 void func1() { 14 mem = (char *)malloc(10); 15 } 16 17 void func2() { 18 free(mem); 19 } 20 21 int main() { 22 // Disable stderr buffering. Needed on Windows. 23 setvbuf(stderr, NULL, _IONBF, 0); 24 25 func1(); 26 func2(); 27 28 void *trace[100]; 29 size_t num_frames = 100; 30 int thread_id; 31 num_frames = __asan_get_alloc_stack(mem, trace, num_frames, &thread_id); 32 33 fprintf(stderr, "alloc stack retval %s\n", (num_frames > 0 && num_frames < 10) 34 ? "ok" : ""); 35 // CHECK: alloc stack retval ok 36 fprintf(stderr, "thread id = %d\n", thread_id); 37 // CHECK: thread id = 0 38 fprintf(stderr, "0x%lx\n", trace[0]); 39 // CHECK: [[ALLOC_FRAME_0:0x[0-9a-f]+]] 40 fprintf(stderr, "0x%lx\n", trace[1]); 41 // CHECK: [[ALLOC_FRAME_1:0x[0-9a-f]+]] 42 43 num_frames = 100; 44 num_frames = __asan_get_free_stack(mem, trace, num_frames, &thread_id); 45 46 fprintf(stderr, "free stack retval %s\n", (num_frames > 0 && num_frames < 10) 47 ? "ok" : ""); 48 // CHECK: free stack retval ok 49 fprintf(stderr, "thread id = %d\n", thread_id); 50 // CHECK: thread id = 0 51 fprintf(stderr, "0x%lx\n", trace[0]); 52 // CHECK: [[FREE_FRAME_0:0x[0-9a-f]+]] 53 fprintf(stderr, "0x%lx\n", trace[1]); 54 // CHECK: [[FREE_FRAME_1:0x[0-9a-f]+]] 55 56 mem[0] = 'A'; // BOOM 57 58 // CHECK: ERROR: AddressSanitizer: heap-use-after-free 59 // CHECK: WRITE of size 1 at 0x{{.*}} 60 // CHECK: freed by thread T0 here: 61 // CHECK: #0 [[FREE_FRAME_0]] 62 // CHECK: #1 [[FREE_FRAME_1]] 63 // CHECK: previously allocated by thread T0 here: 64 // CHECK: #0 [[ALLOC_FRAME_0]] 65 // CHECK: #1 [[ALLOC_FRAME_1]] 66 67 return 0; 68 } 69