• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
func1()13 void func1() {
14   mem = (char *)malloc(10);
15 }
16 
func2()17 void func2() {
18   free(mem);
19 }
20 
main()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