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#if _WIN64
9#define PTR "%llx"
10#else
11#define PTR "%lx"
12#endif
13
14#include <sanitizer/asan_interface.h>
15#include <stdio.h>
16#include <stdlib.h>
17
18char *mem;
19void func1() {
20 mem = (char *)malloc(size: 10);
21}
22
23void func2() {
24 free(ptr: mem);
25}
26
27int main() {
28 // Disable stderr buffering. Needed on Windows.
29 setvbuf(stderr, NULL, _IONBF, n: 0);
30
31 func1();
32 func2();
33
34 void *trace[100];
35 size_t num_frames = 100;
36 int thread_id;
37 num_frames = __asan_get_alloc_stack(addr: mem, trace, size: num_frames, thread_id: &thread_id);
38
39 fprintf(stderr, format: "alloc stack retval %s\n", (num_frames > 0 && num_frames < 10)
40 ? "ok" : "");
41 // CHECK: alloc stack retval ok
42 fprintf(stderr, format: "thread id = %d\n", thread_id);
43 // CHECK: thread id = 0
44 fprintf(stderr, format: "0x" PTR "\n", trace[0]);
45 // CHECK: [[ALLOC_FRAME_0:0x[0-9a-f]+]]
46 fprintf(stderr, format: "0x" PTR "\n", trace[1]);
47 // CHECK: [[ALLOC_FRAME_1:0x[0-9a-f]+]]
48
49 num_frames = 100;
50 num_frames = __asan_get_free_stack(addr: mem, trace, size: num_frames, thread_id: &thread_id);
51
52 fprintf(stderr, format: "free stack retval %s\n", (num_frames > 0 && num_frames < 10)
53 ? "ok" : "");
54 // CHECK: free stack retval ok
55 fprintf(stderr, format: "thread id = %d\n", thread_id);
56 // CHECK: thread id = 0
57 fprintf(stderr, format: "0x" PTR "\n", trace[0]);
58 // CHECK: [[FREE_FRAME_0:0x[0-9a-f]+]]
59 fprintf(stderr, format: "0x" PTR "\n", trace[1]);
60 // CHECK: [[FREE_FRAME_1:0x[0-9a-f]+]]
61
62 mem[0] = 'A'; // BOOM
63
64 // CHECK: ERROR: AddressSanitizer: heap-use-after-free
65 // CHECK: WRITE of size 1 at 0x{{.*}}
66 // CHECK: freed by thread T0 here:
67 // CHECK: #0 [[FREE_FRAME_0]]
68 // CHECK: #1 [[FREE_FRAME_1]]
69 // CHECK: previously allocated by thread T0 here:
70 // CHECK: #0 [[ALLOC_FRAME_0]]
71 // CHECK: #1 [[ALLOC_FRAME_1]]
72
73 return 0;
74}
75

source code of compiler-rt/test/asan/TestCases/debug_stacks.cpp