[sanitizer-coverage] Add interface for coverage symbolization 42/128842/11
authorDmitriy Nikiforov <d.nikiforov@partner.samsung.com>
Thu, 11 May 2017 14:24:59 +0000 (17:24 +0300)
committerDmitriy Nikiforov <d.nikiforov@partner.samsung.com>
Tue, 23 May 2017 10:01:49 +0000 (13:01 +0300)
libsanitizer/
* sanitizer_common/sanitizer_stacktrace_libcdep.cc:
(__sanitizer_symbolize_pc): New function.
(__sanitizer_get_module_and_offset_for_pc): New function.
* include/sanitizer/common_interface_defs.h
(__sanitizer_symbolize_pc): Likewise.
(__sanitizer_get_module_and_offset_for_pc): Likewise.
* sanitizer_common/sanitizer_interface_internal.h
(__sanitizer_get_module_and_offset_for_pc): Likewise.

Partially backported from LLVM mainline r281886, r279780, r288711,
r281668, r281015, r289498. Also, fixed argument names in declarations of
__sanitizer_get_module_and_offset_for_pc().

Change-Id: I3722eb8d3e1cd07b6b862f1a4421517b32b22c5a
Signed-off-by: Dmitriy Nikiforov <d.nikiforov@partner.samsung.com>
libsanitizer/include/sanitizer/common_interface_defs.h
libsanitizer/sanitizer_common/sanitizer_interface_internal.h
libsanitizer/sanitizer_common/sanitizer_stacktrace_libcdep.cc

index 35463e0..a6b16a6 100644 (file)
@@ -112,6 +112,13 @@ extern "C" {
   // Print the stack trace leading to this call. Useful for debugging user code.
   void __sanitizer_print_stack_trace();
 
+  // Symbolizes the supplied 'pc' using the format string 'fmt'.
+  // Outputs at most 'out_buf_size' bytes into 'out_buf'.
+  // The format syntax is described in
+  // lib/sanitizer_common/sanitizer_stacktrace_printer.h.
+  void __sanitizer_symbolize_pc(void *pc, const char *fmt, char *out_buf,
+                                size_t out_buf_size);
+
   // Sets the callback to be called right before death on error.
   // Passing 0 will unset the callback.
   void __sanitizer_set_death_callback(void (*callback)(void));
@@ -126,6 +133,12 @@ extern "C" {
                                     const void *s2, size_t n);
   void __sanitizer_weak_hook_strncmp(void *called_pc, const char *s1,
                                     const char *s2, size_t n);
+
+  // 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_name,
+                                               size_t module_name_len,
+                                               void **pc_offset);
 #ifdef __cplusplus
 }  // extern "C"
 #endif
index 0547f99..9d2d3d0 100644 (file)
@@ -54,6 +54,12 @@ extern "C" {
   SANITIZER_INTERFACE_ATTRIBUTE
   const void *__sanitizer_contiguous_container_find_bad_address(
       const void *beg, const void *mid, const void *end);
+
+  SANITIZER_INTERFACE_ATTRIBUTE
+  int __sanitizer_get_module_and_offset_for_pc(__sanitizer::uptr pc,
+                                               char *module_name,
+                                               __sanitizer::uptr module_name_len,
+                                               __sanitizer::uptr *pc_offset);
   } // extern "C"
 
 #endif  // SANITIZER_INTERFACE_INTERNAL_H
index addf44f..0bdf65f 100644 (file)
@@ -71,4 +71,51 @@ void BufferedStackTrace::Unwind(u32 max_depth, uptr pc, uptr bp, void *context,
   }
 }
 
+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;
+
+extern "C" {
+SANITIZER_INTERFACE_ATTRIBUTE
+void __sanitizer_symbolize_pc(uptr pc, const char *fmt, char *out_buf,
+                              uptr out_buf_size) {
+  if (!out_buf_size)
+    return;
+  pc = StackTrace::GetPreviousInstructionPc(pc);
+  SymbolizedStack *frame = Symbolizer::GetOrInit()->SymbolizePC(pc);
+  if (!frame) {
+    internal_strncpy(out_buf, "<can't symbolize>", out_buf_size);
+    out_buf[out_buf_size - 1] = 0;
+    return;
+  }
+  InternalScopedString frame_desc(GetPageSizeCached());
+  RenderFrame(&frame_desc, fmt, 0, frame->info,
+              common_flags()->symbolize_vs_style,
+              common_flags()->strip_path_prefix);
+  internal_strncpy(out_buf, frame_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"