[compiler-rt] 01cea39 - [sanitizer_common] Support stripping interceptor prefixes in RenderFrame()

Marco Elver via llvm-commits llvm-commits at lists.llvm.org
Thu May 25 03:01:47 PDT 2023


Author: Marco Elver
Date: 2023-05-25T12:01:10+02:00
New Revision: 01cea39f8e11012ac96b36ef60bfaf2f3b64320b

URL: https://github.com/llvm/llvm-project/commit/01cea39f8e11012ac96b36ef60bfaf2f3b64320b
DIFF: https://github.com/llvm/llvm-project/commit/01cea39f8e11012ac96b36ef60bfaf2f3b64320b.diff

LOG: [sanitizer_common] Support stripping interceptor prefixes in RenderFrame()

Rather than having every tool pass the right interceptor prefix, just
move this logic into RenderFrame().

Note that currently there are a few cases where due to aliasing the
intercepted function -> interceptor, the unwinder sees the intercepted
function - however this is never guaranteed. In a later change this
becomes more apparent, and other non-tsan sanitizer tests would fail as
well. By making the default RenderFrame() strip interceptor prefixes, we
don't rely on the linker aliasing preferences.

Reviewed By: dvyukov, vitalybuka, MaskRay

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

Added: 
    

Modified: 
    compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp
    compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.h
    compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cpp
    compiler-rt/lib/tsan/rtl/tsan_report.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp
index 2d0eccc1602ab..ce9f24a9b61c7 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp
@@ -19,12 +19,23 @@ namespace __sanitizer {
 // sanitizer_symbolizer_markup.cpp implements these 
diff erently.
 #if !SANITIZER_SYMBOLIZER_MARKUP
 
-static const char *StripFunctionName(const char *function, const char *prefix) {
-  if (!function) return nullptr;
-  if (!prefix) return function;
-  uptr prefix_len = internal_strlen(prefix);
-  if (0 == internal_strncmp(function, prefix, prefix_len))
-    return function + prefix_len;
+// Strip interceptor prefixes from function name.
+static const char *StripFunctionName(const char *function) {
+  if (!function)
+    return nullptr;
+  auto try_strip = [function](const char *prefix) -> const char * {
+    const uptr prefix_len = internal_strlen(prefix);
+    if (!internal_strncmp(function, prefix, prefix_len))
+      return function + prefix_len;
+    return nullptr;
+  };
+  if (SANITIZER_APPLE) {
+    if (const char *s = try_strip("wrap_"))
+      return s;
+  } else {
+    if (const char *s = try_strip("__interceptor_"))
+      return s;
+  }
   return function;
 }
 
@@ -121,7 +132,7 @@ static const char kDefaultFormat[] = "    #%n %p %F %L";
 
 void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
                  uptr address, const AddressInfo *info, bool vs_style,
-                 const char *strip_path_prefix, const char *strip_func_prefix) {
+                 const char *strip_path_prefix) {
   // info will be null in the case where symbolization is not needed for the
   // given format. This ensures that the code below will get a hard failure
   // rather than print incorrect information in case RenderNeedsSymbolization
@@ -157,8 +168,8 @@ void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
       MaybeBuildIdToBuffer(*info, /*PrefixSpace=*/false, buffer);
       break;
     case 'f':
-      buffer->append("%s", DemangleFunctionName(StripFunctionName(
-                               info->function, strip_func_prefix)));
+      buffer->append("%s",
+                     DemangleFunctionName(StripFunctionName(info->function)));
       break;
     case 'q':
       buffer->append("0x%zx", info->function_offset != AddressInfo::kUnknown
@@ -178,8 +189,8 @@ void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
     case 'F':
       // Function name and offset, if file is unknown.
       if (info->function) {
-        buffer->append("in %s", DemangleFunctionName(StripFunctionName(
-                                    info->function, strip_func_prefix)));
+        buffer->append("in %s",
+                       DemangleFunctionName(StripFunctionName(info->function)));
         if (!info->file && info->function_offset != AddressInfo::kUnknown)
           buffer->append("+0x%zx", info->function_offset);
       }

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.h b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.h
index 96119b2ee9e9f..457e3215da4b0 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.h
@@ -26,8 +26,7 @@ namespace __sanitizer {
 // 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.
+// source files and modules.
 // Here's the full list of available placeholders:
 //   %% - represents a '%' character;
 //   %n - frame number (copy of frame_no);
@@ -48,8 +47,7 @@ namespace __sanitizer {
 //   %M - prints module basename and offset, if it is known, or PC.
 void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
                  uptr address, const AddressInfo *info, bool vs_style,
-                 const char *strip_path_prefix = "",
-                 const char *strip_func_prefix = "");
+                 const char *strip_path_prefix = "");
 
 bool RenderNeedsSymbolization(const char *format);
 

diff  --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cpp
index ce75f8372a190..62b34cd78aba8 100644
--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cpp
+++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cpp
@@ -12,6 +12,7 @@
 #include "sanitizer_common/sanitizer_stacktrace_printer.h"
 
 #include "gtest/gtest.h"
+#include "interception/interception.h"
 
 namespace __sanitizer {
 
@@ -71,7 +72,7 @@ TEST(SanitizerStacktracePrinter, RenderFrame) {
   info.address = 0x400000;
   info.module = internal_strdup("/path/to/my/module");
   info.module_offset = 0x200;
-  info.function = internal_strdup("function_foo");
+  info.function = internal_strdup("foo");
   info.function_offset = 0x100;
   info.file = internal_strdup("/path/to/my/source");
   info.line = 10;
@@ -83,11 +84,24 @@ TEST(SanitizerStacktracePrinter, RenderFrame) {
               "%% Frame:%n PC:%p Module:%m ModuleOffset:%o "
               "Function:%f FunctionOffset:%q Source:%s Line:%l "
               "Column:%c",
-              frame_no, info.address, &info, false, "/path/to/", "function_");
+              frame_no, info.address, &info, false, "/path/to/");
   EXPECT_STREQ("% Frame:42 PC:0x400000 Module:my/module ModuleOffset:0x200 "
                "Function:foo FunctionOffset:0x100 Source:my/source Line:10 "
                "Column:5",
                str.data());
+
+  str.clear();
+  // Check that RenderFrame() strips interceptor prefixes.
+  info.function = internal_strdup(SANITIZER_STRINGIFY(WRAP(bar)));
+  RenderFrame(&str,
+              "%% Frame:%n PC:%p Module:%m ModuleOffset:%o "
+              "Function:%f FunctionOffset:%q Source:%s Line:%l "
+              "Column:%c",
+              frame_no, info.address, &info, false, "/path/to/");
+  EXPECT_STREQ("% Frame:42 PC:0x400000 Module:my/module ModuleOffset:0x200 "
+               "Function:bar FunctionOffset:0x100 Source:my/source Line:10 "
+               "Column:5",
+               str.data());
   info.Clear();
   str.clear();
 

diff  --git a/compiler-rt/lib/tsan/rtl/tsan_report.cpp b/compiler-rt/lib/tsan/rtl/tsan_report.cpp
index 9b03adc16b996..7c8d1253a3ec8 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_report.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_report.cpp
@@ -98,12 +98,6 @@ static const char *ReportTypeString(ReportType typ, uptr tag) {
   UNREACHABLE("missing case");
 }
 
-#if SANITIZER_APPLE
-static const char *const kInterposedFunctionPrefix = "wrap_";
-#else
-static const char *const kInterposedFunctionPrefix = "__interceptor_";
-#endif
-
 void PrintStack(const ReportStack *ent) {
   if (ent == 0 || ent->frames == 0) {
     Printf("    [failed to restore the stack]\n\n");
@@ -115,7 +109,7 @@ void PrintStack(const ReportStack *ent) {
     RenderFrame(&res, common_flags()->stack_trace_format, i,
                 frame->info.address, &frame->info,
                 common_flags()->symbolize_vs_style,
-                common_flags()->strip_path_prefix, kInterposedFunctionPrefix);
+                common_flags()->strip_path_prefix);
     Printf("%s\n", res.data());
   }
   Printf("\n");


        


More information about the llvm-commits mailing list