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