| 1 | // This test case checks for an old bug when using plug-ins that caused |
| 2 | // the stack numbering to be incorrect. |
| 3 | // UNSUPPORTED: android |
| 4 | // UNSUPPORTED: ios |
| 5 | |
| 6 | // RUN: %clangxx_asan -O0 -g %s -o %t |
| 7 | // RUN: %env_asan_opts=symbolize=0 not %run %t DUMMY_ARG > %t.asan_report 2>&1 |
| 8 | // RUN: %asan_symbolize --log-level debug --log-dest %t_debug_log_output.txt -l %t.asan_report --plugins %S/plugin_wrong_frame_number_bug.py > %t.asan_report_sym |
| 9 | // RUN: FileCheck --input-file=%t.asan_report_sym %s |
| 10 | |
| 11 | #include <stdlib.h> |
| 12 | |
| 13 | int* p; |
| 14 | extern "C" { |
| 15 | |
| 16 | void bug() { |
| 17 | free(ptr: p); |
| 18 | } |
| 19 | |
| 20 | void foo(bool call_bug) { |
| 21 | if (call_bug) |
| 22 | bug(); |
| 23 | } |
| 24 | |
| 25 | // This indirection exists so that the call stack |
| 26 | // is reliably large enough. |
| 27 | void do_access_impl() { |
| 28 | *p = 42; |
| 29 | } |
| 30 | |
| 31 | void do_access() { |
| 32 | do_access_impl(); |
| 33 | } |
| 34 | |
| 35 | int main(int argc, char** argv) { |
| 36 | p = (int*) malloc(size: sizeof(p)); |
| 37 | foo(call_bug: argc > 1); |
| 38 | do_access(); |
| 39 | free(ptr: p); |
| 40 | return 0; |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | // Check that the numbering of the stackframes is correct. |
| 45 | |
| 46 | // CHECK: AddressSanitizer: heap-use-after-free |
| 47 | // CHECK-NEXT: WRITE of size |
| 48 | // CHECK-NEXT: #0 0x{{[0-9a-fA-F]+}} |
| 49 | // CHECK-NEXT: #1 0x{{[0-9a-fA-F]+}} in do_access |
| 50 | // CHECK-NEXT: #2 0x{{[0-9a-fA-F]+}} in main |
| 51 | |