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  // 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