[compiler-rt] r221409 - [Sanitizer] Introduce generic stack frame rendering machinery

Alexey Samsonov vonosmas at gmail.com
Wed Nov 5 14:44:36 PST 2014


Author: samsonov
Date: Wed Nov  5 16:44:36 2014
New Revision: 221409

URL: http://llvm.org/viewvc/llvm-project?rev=221409&view=rev
Log:
[Sanitizer] Introduce generic stack frame rendering machinery

Summary:
This commit introduces function __sanitizer::RenderFrame()
that allows to render the contents of AddressInfo (essentially, symbolized stack frame)
using the custom format string. This function can be used to
implement stack frame formatting for both ThreadSanitizer and
generic StackTrace::Print(), used in another places. This paves the
way towards allowing user to control the format of stack frames,
obtaining them in any format he desires, and/or enforcing the consistent
output from all sanitizers.

Test Plan: compiler-rt test suite

Reviewers: kcc

Reviewed By: kcc

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D6140

Added:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_printer.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_printer.h
    compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc
Modified:
    compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc
    compiler-rt/trunk/lib/sanitizer_common/tests/CMakeLists.txt
    compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_common_test.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc
    compiler-rt/trunk/lib/ubsan/ubsan_diag.cc

Modified: compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt?rev=221409&r1=221408&r2=221409&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt Wed Nov  5 16:44:36 2014
@@ -22,6 +22,7 @@ set(SANITIZER_SOURCES
   sanitizer_procmaps_mac.cc
   sanitizer_stackdepot.cc
   sanitizer_stacktrace.cc
+  sanitizer_stacktrace_printer.cc
   sanitizer_suppressions.cc
   sanitizer_symbolizer.cc
   sanitizer_symbolizer_libbacktrace.cc
@@ -82,6 +83,7 @@ set(SANITIZER_HEADERS
   sanitizer_stackdepot.h
   sanitizer_stackdepotbase.h
   sanitizer_stacktrace.h
+  sanitizer_stacktrace_printer.h
   sanitizer_stoptheworld.h
   sanitizer_suppressions.h
   sanitizer_symbolizer.h

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc?rev=221409&r1=221408&r2=221409&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc Wed Nov  5 16:44:36 2014
@@ -163,25 +163,6 @@ const char *StripModuleName(const char *
   return module;
 }
 
-void PrintSourceLocation(InternalScopedString *buffer, const char *file,
-                         int line, int column) {
-  CHECK(file);
-  buffer->append("%s",
-                 StripPathPrefix(file, common_flags()->strip_path_prefix));
-  if (line > 0) {
-    buffer->append(":%d", line);
-    if (column > 0)
-      buffer->append(":%d", column);
-  }
-}
-
-void PrintModuleAndOffset(InternalScopedString *buffer, const char *module,
-                          uptr offset) {
-  buffer->append("(%s+0x%zx)",
-                 StripPathPrefix(module, common_flags()->strip_path_prefix),
-                 offset);
-}
-
 void ReportErrorSummary(const char *error_message) {
   if (!common_flags()->print_summary)
     return;

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h?rev=221409&r1=221408&r2=221409&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h Wed Nov  5 16:44:36 2014
@@ -174,10 +174,6 @@ const char *StripPathPrefix(const char *
                             const char *strip_file_prefix);
 // Strip the directories from the module name.
 const char *StripModuleName(const char *module);
-void PrintSourceLocation(InternalScopedString *buffer, const char *file,
-                         int line, int column);
-void PrintModuleAndOffset(InternalScopedString *buffer,
-                          const char *module, uptr offset);
 
 // OS
 void DisableCoreDumperIfNecessary();

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=221409&r1=221408&r2=221409&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc Wed Nov  5 16:44:36 2014
@@ -12,22 +12,22 @@
 //===----------------------------------------------------------------------===//
 
 #include "sanitizer_common.h"
+#include "sanitizer_placement_new.h"
 #include "sanitizer_stacktrace.h"
+#include "sanitizer_stacktrace_printer.h"
 #include "sanitizer_symbolizer.h"
 
 namespace __sanitizer {
 
-static void PrintStackFramePrefix(InternalScopedString *buffer, uptr frame_num,
-                                  uptr pc) {
-  buffer->append("    #%zu 0x%zx", frame_num, pc);
-}
-
 void StackTrace::Print() const {
   if (trace == nullptr || size == 0) {
     Printf("    <empty stack>\n\n");
     return;
   }
-  InternalScopedBuffer<AddressInfo> addr_frames(64);
+  const int kMaxAddrFrames = 64;
+  InternalScopedBuffer<AddressInfo> addr_frames(kMaxAddrFrames);
+  for (uptr i = 0; i < kMaxAddrFrames; i++)
+    new(&addr_frames[i]) AddressInfo();
   InternalScopedString frame_desc(GetPageSizeCached() * 2);
   uptr frame_num = 0;
   for (uptr i = 0; i < size && trace[i]; i++) {
@@ -35,31 +35,16 @@ void StackTrace::Print() const {
     // addresses of the next instructions after the call.
     uptr pc = GetPreviousInstructionPc(trace[i]);
     uptr addr_frames_num = Symbolizer::GetOrInit()->SymbolizePC(
-        pc, addr_frames.data(), addr_frames.size());
+        pc, addr_frames.data(), kMaxAddrFrames);
     if (addr_frames_num == 0) {
-      frame_desc.clear();
-      PrintStackFramePrefix(&frame_desc, frame_num++, pc);
-      frame_desc.append(" (<unknown module>)");
-      Printf("%s\n", frame_desc.data());
-      continue;
+      addr_frames[0].address = pc;
+      addr_frames_num = 1;
     }
     for (uptr j = 0; j < addr_frames_num; j++) {
       AddressInfo &info = addr_frames[j];
       frame_desc.clear();
-      PrintStackFramePrefix(&frame_desc, frame_num++, pc);
-      if (info.function) {
-        frame_desc.append(" in %s", info.function);
-        // Print offset in function if we don't know the source file.
-        if (!info.file && info.function_offset != AddressInfo::kUnknown)
-          frame_desc.append("+0x%zx", info.function_offset);
-      }
-      if (info.file) {
-        frame_desc.append(" ");
-        PrintSourceLocation(&frame_desc, info.file, info.line, info.column);
-      } else if (info.module) {
-        frame_desc.append(" ");
-        PrintModuleAndOffset(&frame_desc, info.module, info.module_offset);
-      }
+      RenderFrame(&frame_desc, "DEFAULT", frame_num++, info,
+                  common_flags()->strip_path_prefix);
       Printf("%s\n", frame_desc.data());
       info.Clear();
     }

Added: compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_printer.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_printer.cc?rev=221409&view=auto
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_printer.cc (added)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_printer.cc Wed Nov  5 16:44:36 2014
@@ -0,0 +1,132 @@
+//===-- sanitizer_common.cc -----------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is shared between sanitizers' run-time libraries.
+//
+//===----------------------------------------------------------------------===//
+#include "sanitizer_stacktrace_printer.h"
+
+namespace __sanitizer {
+
+static const char *StripFunctionName(const char *function, const char *prefix) {
+  if (function == 0) return 0;
+  if (prefix == 0) return function;
+  uptr prefix_len = internal_strlen(prefix);
+  if (0 == internal_strncmp(function, prefix, prefix_len))
+    return function + prefix_len;
+  return function;
+}
+
+static const char kDefaultFormat[] = "    #%n %p %F %L";
+
+void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
+                 const AddressInfo &info, const char *strip_path_prefix,
+                 const char *strip_func_prefix) {
+  if (0 == internal_strcmp(format, "DEFAULT"))
+    format = kDefaultFormat;
+  for (const char *p = format; *p != '\0'; p++) {
+    if (*p != '%') {
+      buffer->append("%c", *p);
+      continue;
+    }
+    p++;
+    switch (*p) {
+    case '%':
+      buffer->append("%%");
+      break;
+    // Frame number and all fields of AddressInfo structure.
+    case 'n':
+      buffer->append("%zu", frame_no);
+      break;
+    case 'p':
+      buffer->append("0x%zx", info.address);
+      break;
+    case 'm':
+      buffer->append("%s", StripPathPrefix(info.module, strip_path_prefix));
+      break;
+    case 'o':
+      buffer->append("0x%zx", info.module_offset);
+      break;
+    case 'f':
+      buffer->append("%s", StripFunctionName(info.function, strip_func_prefix));
+      break;
+    case 'q':
+      buffer->append("0x%zx", info.function_offset != AddressInfo::kUnknown
+                                  ? info.function_offset
+                                  : 0x0);
+      break;
+    case 's':
+      buffer->append("%s", StripPathPrefix(info.file, strip_path_prefix));
+      break;
+    case 'l':
+      buffer->append("%d", info.line);
+      break;
+    case 'c':
+      buffer->append("%d", info.column);
+      break;
+    // Smarter special cases.
+    case 'F':
+      // Function name and offset, if file is unknown.
+      if (info.function) {
+        buffer->append("in %s",
+                       StripFunctionName(info.function, strip_func_prefix));
+        if (!info.file && info.function_offset != AddressInfo::kUnknown)
+          buffer->append("+0x%zx", info.function_offset);
+      }
+      break;
+    case 'S':
+      // File/line information.
+      RenderSourceLocation(buffer, info.file, info.line, info.column,
+                           strip_path_prefix);
+      break;
+    case 'L':
+      // Source location, or module location.
+      if (info.file) {
+        RenderSourceLocation(buffer, info.file, info.line, info.column,
+                             strip_path_prefix);
+      } else if (info.module) {
+        RenderModuleLocation(buffer, info.module, info.module_offset,
+                             strip_path_prefix);
+      } else {
+        buffer->append("(<unknown module>)");
+      }
+      break;
+    case 'M':
+      // Module basename and offset, or PC.
+      if (info.module)
+        buffer->append("(%s+%p)", StripModuleName(info.module),
+                       (void *)info.module_offset);
+      else
+        buffer->append("(%p)", (void *)info.address);
+      break;
+    default:
+      Report("Unsupported specifier in stack frame format: %c (0x%zx)!\n",
+             *p, *p);
+      Die();
+    }
+  }
+}
+
+void RenderSourceLocation(InternalScopedString *buffer, const char *file,
+                          int line, int column, const char *strip_path_prefix) {
+  buffer->append("%s", StripPathPrefix(file, strip_path_prefix));
+  if (line > 0) {
+    buffer->append(":%d", line);
+    if (column > 0)
+      buffer->append(":%d", column);
+  }
+}
+
+void RenderModuleLocation(InternalScopedString *buffer, const char *module,
+                          uptr offset, const char *strip_path_prefix) {
+  buffer->append("(%s+0x%zx)", StripPathPrefix(module, strip_path_prefix),
+                 offset);
+}
+
+}  // namespace __sanitizer

Added: compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_printer.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_printer.h?rev=221409&view=auto
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_printer.h (added)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace_printer.h Wed Nov  5 16:44:36 2014
@@ -0,0 +1,62 @@
+//===-- sanitizer_stacktrace_printer.h --------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is shared between sanitizers' run-time libraries.
+//
+//===----------------------------------------------------------------------===//
+#ifndef SANITIZER_STACKTRACE_PRINTER_H
+#define SANITIZER_STACKTRACE_PRINTER_H
+
+#include "sanitizer_common.h"
+#include "sanitizer_symbolizer.h"
+
+namespace __sanitizer {
+
+// Render the contents of "info" structure, which represents the contents of
+// stack frame "frame_no" and appends it to the "buffer". "format" is a
+// string with placeholders, which is copied to the output with
+// placeholders substituted with the contents of "info". For example,
+// format string
+//   "  frame %n: function %F at %S"
+// will be turned into
+//   "  frame 10: function foo::bar() at my/file.cc:10"
+// You may additionally pass "strip_path_prefix" to strip prefixes of paths to
+// source files and modules, and "strip_func_prefix" to strip prefixes of
+// function names.
+// Here's the full list of available placeholders:
+//   %% - represents a '%' character;
+//   %n - frame number (copy of frame_no);
+//   %p - PC in hex format;
+//   %m - path to module (binary or shared object);
+//   %o - offset in the module in hex format;
+//   %f - function name;
+//   %q - offset in the function in hex format (*if available*);
+//   %s - path to source file;
+//   %l - line in the source file;
+//   %c - column in the source file;
+//   %F - if function is known to be <foo>, prints "in <foo>", possibly
+//        followed by the offset in this function, but only if source file
+//        is unknown;
+//   %S - prints file/line/column information;
+//   %L - prints location information: file/line/column, if it is known, or
+//        module+offset if it is known, or (<unknown module>) string.
+//   %M - prints module basename and offset, if it is known, or PC.
+void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
+                 const AddressInfo &info, const char *strip_path_prefix = "",
+                 const char *strip_func_prefix = "");
+
+void RenderSourceLocation(InternalScopedString *buffer, const char *file,
+                          int line, int column, const char *strip_path_prefix);
+
+void RenderModuleLocation(InternalScopedString *buffer, const char *module,
+                          uptr offset, const char *strip_path_prefix);
+
+}  // namespace __sanitizer
+
+#endif  // SANITIZER_STACKTRACE_PRINTER_H

Modified: compiler-rt/trunk/lib/sanitizer_common/tests/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/tests/CMakeLists.txt?rev=221409&r1=221408&r2=221409&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/tests/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/sanitizer_common/tests/CMakeLists.txt Wed Nov  5 16:44:36 2014
@@ -21,6 +21,7 @@ set(SANITIZER_UNITTESTS
   sanitizer_printf_test.cc
   sanitizer_procmaps_test.cc
   sanitizer_stackdepot_test.cc
+  sanitizer_stacktrace_printer_test.cc
   sanitizer_stacktrace_test.cc
   sanitizer_stoptheworld_test.cc
   sanitizer_suppressions_test.cc

Modified: compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_common_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_common_test.cc?rev=221409&r1=221408&r2=221409&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_common_test.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_common_test.cc Wed Nov  5 16:44:36 2014
@@ -226,40 +226,4 @@ TEST(SanitizerCommon, InternalScopedStri
   EXPECT_STREQ("012345678", str.data());
 }
 
-TEST(SanitizerCommon, PrintSourceLocation) {
-  InternalScopedString str(128);
-  PrintSourceLocation(&str, "/dir/file.cc", 10, 5);
-  EXPECT_STREQ("/dir/file.cc:10:5", str.data());
-
-  str.clear();
-  PrintSourceLocation(&str, "/dir/file.cc", 11, 0);
-  EXPECT_STREQ("/dir/file.cc:11", str.data());
-
-  str.clear();
-  PrintSourceLocation(&str, "/dir/file.cc", 0, 0);
-  EXPECT_STREQ("/dir/file.cc", str.data());
-
-  // Check that we strip file prefix if necessary.
-  const char *old_strip_path_prefix = common_flags()->strip_path_prefix;
-  common_flags()->strip_path_prefix = "/dir/";
-  str.clear();
-  PrintSourceLocation(&str, "/dir/file.cc", 10, 5);
-  EXPECT_STREQ("file.cc:10:5", str.data());
-  common_flags()->strip_path_prefix = old_strip_path_prefix;
-}
-
-TEST(SanitizerCommon, PrintModuleAndOffset) {
-  InternalScopedString str(128);
-  PrintModuleAndOffset(&str, "/dir/exe", 0x123);
-  EXPECT_STREQ("(/dir/exe+0x123)", str.data());
-
-  // Check that we strip file prefix if necessary.
-  const char *old_strip_path_prefix = common_flags()->strip_path_prefix;
-  common_flags()->strip_path_prefix = "/dir/";
-  str.clear();
-  PrintModuleAndOffset(&str, "/dir/exe", 0x123);
-  EXPECT_STREQ("(exe+0x123)", str.data());
-  common_flags()->strip_path_prefix = old_strip_path_prefix;
-}
-
 }  // namespace __sanitizer

Added: compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc?rev=221409&view=auto
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc (added)
+++ compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc Wed Nov  5 16:44:36 2014
@@ -0,0 +1,122 @@
+//===-- sanitizer_common_printer_test.cc ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of sanitizer_common test suite.
+//
+//===----------------------------------------------------------------------===//
+#include "sanitizer_common/sanitizer_stacktrace_printer.h"
+
+#include "gtest/gtest.h"
+
+namespace __sanitizer {
+
+TEST(SanitizerStacktracePrinter, RenderSourceLocation) {
+  InternalScopedString str(128);
+  RenderSourceLocation(&str, "/dir/file.cc", 10, 5, "");
+  EXPECT_STREQ("/dir/file.cc:10:5", str.data());
+
+  str.clear();
+  RenderSourceLocation(&str, "/dir/file.cc", 11, 0, "");
+  EXPECT_STREQ("/dir/file.cc:11", str.data());
+
+  str.clear();
+  RenderSourceLocation(&str, "/dir/file.cc", 0, 0, "");
+  EXPECT_STREQ("/dir/file.cc", str.data());
+
+  str.clear();
+  RenderSourceLocation(&str, "/dir/file.cc", 10, 5, "/dir/");
+  EXPECT_STREQ("file.cc:10:5", str.data());
+}
+
+TEST(SanitizerStacktracePrinter, RenderModuleLocation) {
+  InternalScopedString str(128);
+  RenderModuleLocation(&str, "/dir/exe", 0x123, "");
+  EXPECT_STREQ("(/dir/exe+0x123)", str.data());
+
+  // Check that we strip file prefix if necessary.
+  str.clear();
+  RenderModuleLocation(&str, "/dir/exe", 0x123, "/dir/");
+  EXPECT_STREQ("(exe+0x123)", str.data());
+}
+
+TEST(SanitizerStacktracePrinter, RenderFrame) {
+  int frame_no = 42;
+  AddressInfo info;
+  info.address = 0x400000;
+  info.module = internal_strdup("/path/to/my/module");
+  info.module_offset = 0x200;
+  info.function = internal_strdup("function_foo");
+  info.function_offset = 0x100;
+  info.file = internal_strdup("/path/to/my/source");
+  info.line = 10;
+  info.column = 5;
+  InternalScopedString str(256);
+
+  // Dump all the AddressInfo fields.
+  RenderFrame(&str, "%% Frame:%n PC:%p Module:%m ModuleOffset:%o "
+                    "Function:%f FunctionOffset:%q Source:%s Line:%l "
+                    "Column:%c",
+              frame_no, info, "/path/to/", "function_");
+  EXPECT_STREQ("% Frame:42 PC:0x400000 Module:my/module ModuleOffset:0x200 "
+               "Function:foo FunctionOffset:0x100 Source:my/source Line:10 "
+               "Column:5",
+               str.data());
+  info.Clear();
+  str.clear();
+
+  // Test special format specifiers.
+  info.address = 0x400000;
+  RenderFrame(&str, "%M", frame_no, info);
+  EXPECT_NE(nullptr, internal_strstr(str.data(), "400000"));
+  str.clear();
+
+  RenderFrame(&str, "%L", frame_no, info);
+  EXPECT_STREQ("(<unknown module>)", str.data());
+  str.clear();
+
+  info.module = internal_strdup("/path/to/module");
+  info.module_offset = 0x200;
+  RenderFrame(&str, "%M", frame_no, info);
+  EXPECT_NE(nullptr, internal_strstr(str.data(), "(module+0x"));
+  EXPECT_NE(nullptr, internal_strstr(str.data(), "200"));
+  str.clear();
+
+  RenderFrame(&str, "%L", frame_no, info);
+  EXPECT_STREQ("(/path/to/module+0x200)", str.data());
+  str.clear();
+
+  info.function = internal_strdup("my_function");
+  RenderFrame(&str, "%F", frame_no, info);
+  EXPECT_STREQ("in my_function", str.data());
+  str.clear();
+
+  info.function_offset = 0x100;
+  RenderFrame(&str, "%F %S", frame_no, info);
+  EXPECT_STREQ("in my_function+0x100 <null>", str.data());
+  str.clear();
+
+  info.file = internal_strdup("my_file");
+  RenderFrame(&str, "%F %S", frame_no, info);
+  EXPECT_STREQ("in my_function my_file", str.data());
+  str.clear();
+
+  info.line = 10;
+  RenderFrame(&str, "%F %S", frame_no, info);
+  EXPECT_STREQ("in my_function my_file:10", str.data());
+  str.clear();
+
+  info.column = 5;
+  RenderFrame(&str, "%S %L", frame_no, info);
+  EXPECT_STREQ("my_file:10:5 my_file:10:5", str.data());
+  str.clear();
+
+  info.Clear();
+}
+
+}  // namespace __sanitizer

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc?rev=221409&r1=221408&r2=221409&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc Wed Nov  5 16:44:36 2014
@@ -15,6 +15,7 @@
 #include "tsan_rtl.h"
 #include "sanitizer_common/sanitizer_placement_new.h"
 #include "sanitizer_common/sanitizer_report_decorator.h"
+#include "sanitizer_common/sanitizer_stacktrace_printer.h"
 
 namespace __tsan {
 
@@ -112,34 +113,16 @@ static const char *ReportTypeString(Repo
   return "";
 }
 
-static const char *StripFunctionName(const char *function, const char *prefix) {
-  if (function == 0) return 0;
-  if (prefix == 0) return function;
-  uptr prefix_len = internal_strlen(prefix);
-  if (0 == internal_strncmp(function, prefix, prefix_len))
-    return function + prefix_len;
-  return function;
-}
-
 void PrintStack(const ReportStack *ent) {
   if (ent == 0) {
     Printf("    [failed to restore the stack]\n\n");
     return;
   }
   for (int i = 0; ent; ent = ent->next, i++) {
-    const AddressInfo &info = ent->info;
-    Printf("    #%d %s %s:%d", i,
-           StripFunctionName(info.function, "__interceptor_"),
-           StripPathPrefix(info.file, common_flags()->strip_path_prefix),
-           info.line);
-    if (info.column)
-      Printf(":%d", info.column);
-    if (info.module && info.module_offset) {
-      Printf(" (%s+%p)\n", StripModuleName(info.module),
-             (void *)info.module_offset);
-    } else {
-      Printf(" (%p)\n", (void *)info.address);
-    }
+    InternalScopedString res(2 * GetPageSizeCached());
+    RenderFrame(&res, "    #%n %f %S %M", i, ent->info,
+                common_flags()->strip_path_prefix, "__interceptor_");
+    Printf("%s\n", res.data());
   }
   Printf("\n");
 }

Modified: compiler-rt/trunk/lib/ubsan/ubsan_diag.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_diag.cc?rev=221409&r1=221408&r2=221409&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_diag.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_diag.cc Wed Nov  5 16:44:36 2014
@@ -16,6 +16,7 @@
 #include "ubsan_flags.h"
 #include "sanitizer_common/sanitizer_report_decorator.h"
 #include "sanitizer_common/sanitizer_stacktrace.h"
+#include "sanitizer_common/sanitizer_stacktrace_printer.h"
 #include "sanitizer_common/sanitizer_symbolizer.h"
 #include <stdio.h>
 
@@ -129,14 +130,16 @@ static void renderLocation(Location Loc)
     if (SLoc.isInvalid())
       LocBuffer.append("<unknown>");
     else
-      PrintSourceLocation(&LocBuffer, SLoc.getFilename(), SLoc.getLine(),
-                          SLoc.getColumn());
+      RenderSourceLocation(&LocBuffer, SLoc.getFilename(), SLoc.getLine(),
+                           SLoc.getColumn(), common_flags()->strip_path_prefix);
     break;
   }
-  case Location::LK_Module:
-    PrintModuleAndOffset(&LocBuffer, Loc.getModuleLocation().getModuleName(),
-                         Loc.getModuleLocation().getOffset());
+  case Location::LK_Module: {
+    ModuleLocation MLoc = Loc.getModuleLocation();
+    RenderModuleLocation(&LocBuffer, MLoc.getModuleName(), MLoc.getOffset(),
+                         common_flags()->strip_path_prefix);
     break;
+  }
   case Location::LK_Memory:
     LocBuffer.append("%p", Loc.getMemoryLocation());
     break;





More information about the llvm-commits mailing list