| 1 | // RUN: mkdir -p %t-dir |
| 2 | // RUN: %clangxx -DSHARED %s -shared -o %t-dir/get_module_and_offset_for_pc.so -fPIC |
| 3 | // RUN: %clangxx -DSO_DIR=\"%t-dir\" -O0 %s -o %t |
| 4 | // RUN: %run %t 2>&1 | FileCheck %s |
| 5 | |
| 6 | // UNSUPPORTED: i386-darwin |
| 7 | // XFAIL: android |
| 8 | |
| 9 | // Tests __sanitizer_get_module_and_offset_for_pc. |
| 10 | |
| 11 | #include <assert.h> |
| 12 | #include <dlfcn.h> |
| 13 | #include <sanitizer/common_interface_defs.h> |
| 14 | #include <stdio.h> |
| 15 | |
| 16 | #ifdef SHARED |
| 17 | extern "C" { |
| 18 | int foo() { return 1; } |
| 19 | } |
| 20 | #else |
| 21 | |
| 22 | void Test(void *pc, const char *name) { |
| 23 | char module_name[1024]; |
| 24 | void *offset = 0; |
| 25 | int ok = __sanitizer_get_module_and_offset_for_pc( |
| 26 | pc, module_path: module_name, module_path_len: sizeof(module_name), pc_offset: &offset); |
| 27 | if (!ok) { |
| 28 | printf(format: "NOT FOUND %s: %p\n" , name, pc); |
| 29 | } else { |
| 30 | printf(format: "FOUND %s: %s %p\n" , name, module_name, offset); |
| 31 | } |
| 32 | } |
| 33 | |
| 34 | void TestCallerPc() { Test(pc: __builtin_return_address(0), name: "callerpc" ); } |
| 35 | |
| 36 | void TestDlsym() { |
| 37 | void *handle = dlopen(SO_DIR "/get_module_and_offset_for_pc.so" , RTLD_LAZY); |
| 38 | assert(handle); |
| 39 | void *foo = dlsym(handle: handle, name: "foo" ); |
| 40 | assert(foo); |
| 41 | Test(pc: foo, name: "foo" ); |
| 42 | dlclose(handle: handle); |
| 43 | } |
| 44 | |
| 45 | // Call __sanitizer_get_module_and_offset_for_pc lots of times |
| 46 | // to make sure it is not too slow. |
| 47 | void TestLoop() { |
| 48 | void *pc = __builtin_return_address(0); |
| 49 | char module_name[1024]; |
| 50 | void *offset; |
| 51 | for (int i = 0; i < 1000000; ++i) { |
| 52 | __sanitizer_get_module_and_offset_for_pc(pc, module_path: module_name, |
| 53 | module_path_len: sizeof(module_name), pc_offset: &offset); |
| 54 | } |
| 55 | } |
| 56 | |
| 57 | int main() { |
| 58 | Test(pc: 0, name: "null" ); |
| 59 | TestCallerPc(); |
| 60 | TestDlsym(); |
| 61 | TestLoop(); |
| 62 | } |
| 63 | #endif |
| 64 | // CHECK: NOT FOUND null: {{.*}} |
| 65 | // CHECK-NEXT: FOUND callerpc: {{.*}}/get_module_and_offset_for_pc.cpp.tmp {{.*}} |
| 66 | // CHECK-NEXT: FOUND foo: {{.*}}/get_module_and_offset_for_pc.so {{.*}} |
| 67 | |