diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interface_posix.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interface_posix.inc --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interface_posix.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interface_posix.inc @@ -11,4 +11,5 @@ INTERFACE_WEAK_FUNCTION(__sanitizer_symbolize_data) INTERFACE_WEAK_FUNCTION(__sanitizer_symbolize_demangle) INTERFACE_WEAK_FUNCTION(__sanitizer_symbolize_flush) +INTERFACE_WEAK_FUNCTION(__sanitizer_symbolize_set_demangle) INTERFACE_WEAK_FUNCTION(__sanitizer_symbolize_set_inline_frames) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc --- a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc @@ -179,6 +179,7 @@ "in core file.") COMMON_FLAG(bool, symbolize_inline_frames, true, "Print inlined frames in stacktraces. Defaults to true.") +COMMON_FLAG(bool, demangle, true, "Print demangled symbols.") COMMON_FLAG(bool, symbolize_vs_style, false, "Print file locations in Visual Studio style (e.g: " " file(10,42): ...") diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp @@ -274,10 +274,13 @@ const char* const kSymbolizerArch = "--default-arch=unknown"; #endif + const char *const demangle_flag = + common_flags()->demangle ? "--demangle" : "--no-demangle"; const char *const inline_flag = common_flags()->symbolize_inline_frames ? "--inlines" : "--no-inlines"; int i = 0; argv[i++] = path_to_binary; + argv[i++] = demangle_flag; argv[i++] = inline_flag; argv[i++] = kSymbolizerArch; argv[i++] = nullptr; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp @@ -213,9 +213,11 @@ const char *(&argv)[kArgVMax]) const override { int i = 0; argv[i++] = path_to_binary; + if (common_flags()->demangle) + argv[i++] = "-C"; if (common_flags()->symbolize_inline_frames) argv[i++] = "-i"; - argv[i++] = "-Cfe"; + argv[i++] = "-fe"; argv[i++] = module_name_; argv[i++] = nullptr; CHECK_LE(i, kArgVMax); @@ -328,12 +330,16 @@ SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE int __sanitizer_symbolize_demangle(const char *Name, char *Buffer, int MaxLength); SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE bool +__sanitizer_symbolize_set_demangle(bool Demangle); +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE bool __sanitizer_symbolize_set_inline_frames(bool InlineFrames); } // extern "C" class InternalSymbolizer final : public SymbolizerTool { public: static InternalSymbolizer *get(LowLevelAllocator *alloc) { + if (__sanitizer_symbolize_set_demangle) + CHECK(__sanitizer_symbolize_set_demangle(common_flags()->demangle)); if (__sanitizer_symbolize_set_inline_frames) CHECK(__sanitizer_symbolize_set_inline_frames( common_flags()->symbolize_inline_frames)); diff --git a/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp b/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp --- a/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp +++ b/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp @@ -18,12 +18,14 @@ #include "llvm/DebugInfo/Symbolize/Symbolize.h" static llvm::symbolize::LLVMSymbolizer *Symbolizer = nullptr; +static bool Demangle = true; static bool InlineFrames = true; static llvm::symbolize::LLVMSymbolizer *getDefaultSymbolizer() { if (Symbolizer) return Symbolizer; llvm::symbolize::LLVMSymbolizer::Options Opts; + Opts.Demangle = Demangle; Symbolizer = new llvm::symbolize::LLVMSymbolizer(Opts); return Symbolizer; } @@ -112,6 +114,14 @@ : 0; } +bool __sanitizer_symbolize_set_demangle(bool Value) { + // Must be called before LLVMSymbolizer created. + if (Symbolizer) + return false; + Demangle = Value; + return true; +} + bool __sanitizer_symbolize_set_inline_frames(bool Value) { InlineFrames = Value; return true; diff --git a/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh b/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh --- a/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh +++ b/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh @@ -159,6 +159,7 @@ SYMBOLIZER_API_LIST+=,__sanitizer_symbolize_data SYMBOLIZER_API_LIST+=,__sanitizer_symbolize_flush SYMBOLIZER_API_LIST+=,__sanitizer_symbolize_demangle +SYMBOLIZER_API_LIST+=,__sanitizer_symbolize_set_demangle SYMBOLIZER_API_LIST+=,__sanitizer_symbolize_set_inline_frames LIBCXX_ARCHIVE_DIR=$(dirname $(find $LIBCXX_BUILD -name libc++.a | head -n1)) diff --git a/compiler-rt/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt b/compiler-rt/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt --- a/compiler-rt/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt +++ b/compiler-rt/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt @@ -38,6 +38,7 @@ __sanitizer_symbolize_data T __sanitizer_symbolize_demangle T __sanitizer_symbolize_flush T +__sanitizer_symbolize_set_demangle T __sanitizer_symbolize_set_inline_frames T __strdup U __udivdi3 U diff --git a/compiler-rt/lib/sanitizer_common/weak_symbols.txt b/compiler-rt/lib/sanitizer_common/weak_symbols.txt --- a/compiler-rt/lib/sanitizer_common/weak_symbols.txt +++ b/compiler-rt/lib/sanitizer_common/weak_symbols.txt @@ -6,4 +6,5 @@ ___sanitizer_symbolize_data ___sanitizer_symbolize_demangle ___sanitizer_symbolize_flush +___sanitizer_symbolize_set_demangle ___sanitizer_symbolize_set_inline_frames diff --git a/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_demangle.cpp b/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_demangle.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_demangle.cpp @@ -0,0 +1,30 @@ +// RUN: %clangxx -O1 -fno-omit-frame-pointer %s -o %t +// RUN: %env_tool_opts=strip_path_prefix=/TestCases/ %run %t 2>&1 | FileCheck %s +// RUN: %env_tool_opts=strip_path_prefix=/TestCases/:demangle=0 %run %t 2>&1 | FileCheck %s --check-prefixes=NODEMANGLE +// RUN: %env_tool_opts=strip_path_prefix=/TestCases/:demangle=1 %run %t 2>&1 | FileCheck %s + +// XFAIL: darwin + +#include +#include +#include + +char buffer[10000]; + +__attribute__((noinline)) static void Symbolize() { + __sanitizer_symbolize_pc(__builtin_return_address(0), "%p %F %L", buffer, + sizeof(buffer)); + for (char *p = buffer; strlen(p); p += strlen(p) + 1) + printf("%s\n", p); +} + +struct Symbolizer { + __attribute__((noinline)) ~Symbolizer() { Symbolize(); } +}; + +// NODEMANGLE: in _ZN10SymbolizerD2Ev +// CHECK: in Symbolizer::~Symbolizer +int main() { + Symbolizer(); + return 0; +}