[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