xref: /llvm-project/compiler-rt/test/asan/TestCases/debug_report.cpp (revision 53a81d4d26f0409de8a0655d7af90f2bea222a12)
1673dc3d4SNico Weber // Checks that the ASan debugging API for getting report information
2673dc3d4SNico Weber // returns correct values.
3673dc3d4SNico Weber // RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
4673dc3d4SNico Weber 
5673dc3d4SNico Weber #include <sanitizer/asan_interface.h>
6673dc3d4SNico Weber #include <stdio.h>
7673dc3d4SNico Weber #include <stdlib.h>
8673dc3d4SNico Weber 
9673dc3d4SNico Weber int main() {
10673dc3d4SNico Weber   // Disable stderr buffering. Needed on Windows.
11673dc3d4SNico Weber   setvbuf(stderr, NULL, _IONBF, 0);
12673dc3d4SNico Weber 
13673dc3d4SNico Weber   char *heap_ptr = (char *)malloc(10);
14673dc3d4SNico Weber   free(heap_ptr);
15673dc3d4SNico Weber   int present = __asan_report_present();
16673dc3d4SNico Weber   fprintf(stderr, "%s\n", (present == 0) ? "no report" : "");
17673dc3d4SNico Weber   // CHECK: no report
18673dc3d4SNico Weber   heap_ptr[0] = 'A'; // BOOM
19673dc3d4SNico Weber   return 0;
20673dc3d4SNico Weber }
21673dc3d4SNico Weber 
22*9faa623dSMartin Storsjö // If we use %p with MS CRTs, it comes out all upper case. Use %08x to get
23673dc3d4SNico Weber // lowercase hex.
24*9faa623dSMartin Storsjö #ifdef _WIN32
25673dc3d4SNico Weber # ifdef _WIN64
26673dc3d4SNico Weber #  define PTR_FMT "0x%08llx"
27673dc3d4SNico Weber # else
28673dc3d4SNico Weber #  define PTR_FMT "0x%08x"
29673dc3d4SNico Weber # endif
30673dc3d4SNico Weber // Solaris libc omits the leading 0x.
31673dc3d4SNico Weber #elif defined(__sun__) && defined(__svr4__)
32673dc3d4SNico Weber # define PTR_FMT "0x%p"
33673dc3d4SNico Weber #else
34673dc3d4SNico Weber # define PTR_FMT "%p"
35673dc3d4SNico Weber #endif
36673dc3d4SNico Weber 
370aefc946SRoy Sundahl // Required for dyld macOS 12.0+
380aefc946SRoy Sundahl #if (__APPLE__)
390aefc946SRoy Sundahl __attribute__((weak))
400aefc946SRoy Sundahl #endif
410aefc946SRoy Sundahl extern "C" void
420aefc946SRoy Sundahl __asan_on_error() {
43673dc3d4SNico Weber   int present = __asan_report_present();
44673dc3d4SNico Weber   void *pc = __asan_get_report_pc();
45673dc3d4SNico Weber   void *bp = __asan_get_report_bp();
46673dc3d4SNico Weber   void *sp = __asan_get_report_sp();
47673dc3d4SNico Weber   void *addr = __asan_get_report_address();
48673dc3d4SNico Weber   int is_write = __asan_get_report_access_type();
49673dc3d4SNico Weber   size_t access_size = __asan_get_report_access_size();
50673dc3d4SNico Weber   const char *description = __asan_get_report_description();
51673dc3d4SNico Weber 
52673dc3d4SNico Weber   fprintf(stderr, "%s\n", (present == 1) ? "report" : "");
53673dc3d4SNico Weber   // CHECK: report
54673dc3d4SNico Weber   fprintf(stderr, "pc: " PTR_FMT "\n", pc);
55673dc3d4SNico Weber   // CHECK: pc: 0x[[PC:[0-9a-f]+]]
56673dc3d4SNico Weber   fprintf(stderr, "bp: " PTR_FMT "\n", bp);
57673dc3d4SNico Weber   // CHECK: bp: 0x[[BP:[0-9a-f]+]]
58673dc3d4SNico Weber   fprintf(stderr, "sp: " PTR_FMT "\n", sp);
59673dc3d4SNico Weber   // CHECK: sp: 0x[[SP:[0-9a-f]+]]
60673dc3d4SNico Weber   fprintf(stderr, "addr: " PTR_FMT "\n", addr);
61673dc3d4SNico Weber   // CHECK: addr: 0x[[ADDR:[0-9a-f]+]]
62673dc3d4SNico Weber   fprintf(stderr, "type: %s\n", (is_write ? "write" : "read"));
63673dc3d4SNico Weber   // CHECK: type: write
64673dc3d4SNico Weber   fprintf(stderr, "access_size: %ld\n", access_size);
65673dc3d4SNico Weber   // CHECK: access_size: 1
66673dc3d4SNico Weber   fprintf(stderr, "description: %s\n", description);
67673dc3d4SNico Weber   // CHECK: description: heap-use-after-free
68673dc3d4SNico Weber }
69673dc3d4SNico Weber 
70673dc3d4SNico Weber // CHECK: AddressSanitizer: heap-use-after-free on address {{0x0*}}[[ADDR]] at pc {{0x0*}}[[PC]] bp {{0x0*}}[[BP]] sp {{0x0*}}[[SP]]
71673dc3d4SNico Weber // CHECK: WRITE of size 1 at {{0x0*}}[[ADDR]] thread T0
72