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