[compiler-rt] r288711 - [sanitizers] __sanitizer_get_module_and_offset_for_pc interface function

Mike Aizatsky via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 5 13:45:14 PST 2016


Author: aizatsky
Date: Mon Dec  5 15:45:14 2016
New Revision: 288711

URL: http://llvm.org/viewvc/llvm-project?rev=288711&view=rev
Log:
[sanitizers] __sanitizer_get_module_and_offset_for_pc interface function

Summary: The function computes full module name and coverts pc into offset.

Reviewers: kcc

Subscribers: kubabrecka

Differential Revision: https://reviews.llvm.org/D26820

Added:
    compiler-rt/trunk/test/sanitizer_common/TestCases/get_module_and_offset_for_pc.cc
Modified:
    compiler-rt/trunk/include/sanitizer/common_interface_defs.h
    compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc

Modified: compiler-rt/trunk/include/sanitizer/common_interface_defs.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/sanitizer/common_interface_defs.h?rev=288711&r1=288710&r2=288711&view=diff
==============================================================================
--- compiler-rt/trunk/include/sanitizer/common_interface_defs.h (original)
+++ compiler-rt/trunk/include/sanitizer/common_interface_defs.h Mon Dec  5 15:45:14 2016
@@ -182,6 +182,13 @@ extern "C" {
   void __sanitizer_finish_switch_fiber(void *fake_stack_save,
                                        const void **bottom_old,
                                        size_t *size_old);
+
+  // Get full module name and calculate pc offset within it.
+  // Returns 1 if pc belongs to some module, 0 if module was not found.
+  int __sanitizer_get_module_and_offset_for_pc(void *pc, char *module_path,
+                                               size_t module_path_len,
+                                               void **pc_offset);
+
 #ifdef __cplusplus
 }  // extern "C"
 #endif

Modified: compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc?rev=288711&r1=288710&r2=288711&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc Mon Dec  5 15:45:14 2016
@@ -366,6 +366,7 @@ INTERFACE_FUNCTION(__sanitizer_verify_co
 INTERFACE_FUNCTION(__sanitizer_install_malloc_and_free_hooks)
 INTERFACE_FUNCTION(__sanitizer_start_switch_fiber)
 INTERFACE_FUNCTION(__sanitizer_finish_switch_fiber)
+INTERFACE_FUNCTION(__sanitizer_get_module_and_offset_for_pc)
 
 // TODO(timurrrr): Add more interface functions on the as-needed basis.
 

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc?rev=288711&r1=288710&r2=288711&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc Mon Dec  5 15:45:14 2016
@@ -82,6 +82,21 @@ void BufferedStackTrace::Unwind(u32 max_
   }
 }
 
+static int GetModuleAndOffsetForPc(uptr pc, char *module_name,
+                                   uptr module_name_len, uptr *pc_offset) {
+  const char *found_module_name = nullptr;
+  bool ok = Symbolizer::GetOrInit()->GetModuleNameAndOffsetForPC(
+      pc, &found_module_name, pc_offset);
+
+  if (!ok) return false;
+
+  if (module_name && module_name_len) {
+    internal_strncpy(module_name, found_module_name, module_name_len);
+    module_name[module_name_len - 1] = '\x00';
+  }
+  return true;
+}
+
 }  // namespace __sanitizer
 using namespace __sanitizer;
 
@@ -117,4 +132,11 @@ void __sanitizer_symbolize_global(uptr d
   internal_strncpy(out_buf, data_desc.data(), out_buf_size);
   out_buf[out_buf_size - 1] = 0;
 }
+
+SANITIZER_INTERFACE_ATTRIBUTE
+int __sanitizer_get_module_and_offset_for_pc( // NOLINT
+    uptr pc, char *module_name, uptr module_name_len, uptr *pc_offset) {
+  return __sanitizer::GetModuleAndOffsetForPc(pc, module_name, module_name_len,
+                                              pc_offset);
+}
 }  // extern "C"

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc?rev=288711&r1=288710&r2=288711&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc Mon Dec  5 15:45:14 2016
@@ -55,7 +55,7 @@ const char *DemangleCXXABI(const char *n
   // own demangler (libc++abi's implementation could be adapted so that
   // it does not allocate). For now, we just call it anyway, and we leak
   // the returned value.
-  if (__cxxabiv1::__cxa_demangle)
+  if (&__cxxabiv1::__cxa_demangle)
     if (const char *demangled_name =
           __cxxabiv1::__cxa_demangle(name, 0, 0, 0))
       return demangled_name;

Added: compiler-rt/trunk/test/sanitizer_common/TestCases/get_module_and_offset_for_pc.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/sanitizer_common/TestCases/get_module_and_offset_for_pc.cc?rev=288711&view=auto
==============================================================================
--- compiler-rt/trunk/test/sanitizer_common/TestCases/get_module_and_offset_for_pc.cc (added)
+++ compiler-rt/trunk/test/sanitizer_common/TestCases/get_module_and_offset_for_pc.cc Mon Dec  5 15:45:14 2016
@@ -0,0 +1,63 @@
+// RUN: %clangxx -DSHARED %s -shared -o %T/get_module_and_offset_for_pc.so -fPIC
+// RUN: %clangxx -DSO_DIR=\"%T\" -O0 %s -ldl -o %t
+// RUN: %run %t 2>&1 | FileCheck %s
+// UNSUPPORTED: i386-darwin
+//
+// Tests __sanitizer_get_module_and_offset_for_pc.
+
+#include <assert.h>
+#include <dlfcn.h>
+#include <sanitizer/common_interface_defs.h>
+#include <stdio.h>
+
+#ifdef SHARED
+extern "C" {
+int foo() { return 1; }
+}
+#else
+
+void Test(void *pc, const char *name) {
+  char module_name[1024];
+  void *offset;
+  int ok = __sanitizer_get_module_and_offset_for_pc(
+      pc, module_name, sizeof(module_name), &offset);
+  if (!ok) {
+    printf("NOT FOUND %s: %p\n", name, pc);
+  } else {
+    printf("FOUND %s: %s %p\n", name, module_name, offset);
+  }
+}
+
+void TestCallerPc() { Test(__builtin_return_address(0), "callerpc"); }
+
+void TestDlsym() {
+  void *handle = dlopen(SO_DIR "/get_module_and_offset_for_pc.so", RTLD_LAZY);
+  assert(handle);
+  void *foo = dlsym(handle, "foo");
+  assert(foo);
+  Test(foo, "foo");
+  dlclose(handle);
+}
+
+// Call __sanitizer_get_module_and_offset_for_pc lots of times
+// to make sure it is not too slow.
+void TestLoop() {
+  void *pc = __builtin_return_address(0);
+  char module_name[1024];
+  void *offset;
+  for (int i = 0; i < 1000000; ++i) {
+    __sanitizer_get_module_and_offset_for_pc(pc, module_name,
+                                             sizeof(module_name), &offset);
+  }
+}
+
+int main() {
+  Test(0, "null");
+  TestCallerPc();
+  TestDlsym();
+  TestLoop();
+}
+#endif
+// CHECK: NOT FOUND null: (nil)
+// CHECK-NEXT: FOUND callerpc: {{.*}}/get_module_and_offset_for_pc.cc.tmp {{.*}}
+// CHECK-NEXT: FOUND foo: {{.*}}/get_module_and_offset_for_pc.so {{.*}}




More information about the llvm-commits mailing list