diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h index f8351393d0e6..5a15a3fe5715 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h @@ -74,7 +74,9 @@ bool IsSymbolizerAvailable(); void FlushSymbolizer(); // releases internal caches (if any) // Attempts to demangle the provided C++ mangled name. -const char *Demangle(const char *Name); +const char *Demangle(const char *name); +// Attempts to demangle the name via __cxa_demangle from __cxxabiv1. +const char *DemangleCXXABI(const char *name); // Starts external symbolizer program in a subprocess. Sanitizer communicates // with external symbolizer via pipes. diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_itanium.cc b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_itanium.cc index e20fb91f0eb5..93a26e634cff 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_itanium.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_itanium.cc @@ -27,18 +27,18 @@ namespace __cxxabiv1 { SANITIZER_WEAK_ATTRIBUTE; } -const char *__sanitizer::Demangle(const char *MangledName) { +const char *__sanitizer::DemangleCXXABI(const char *name) { // FIXME: __cxa_demangle aggressively insists on allocating memory. // There's not much we can do about that, short of providing our // own demangler (libc++abi's implementation could be adapted so that // it does not allocate). For now, we just call it anyway, and we leak // the returned value. if (__cxxabiv1::__cxa_demangle) - if (const char *Demangled = - __cxxabiv1::__cxa_demangle(MangledName, 0, 0, 0)) - return Demangled; + if (const char *demangled_name = + __cxxabiv1::__cxa_demangle(name, 0, 0, 0)) + return demangled_name; - return MangledName; + return name; } #endif // SANITIZER_MAC || SANITIZER_LINUX diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc index 2f32257b8a5c..2588dd19cf59 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc @@ -190,6 +190,9 @@ bool __sanitizer_symbolize_data(const char *ModuleName, u64 ModuleOffset, char *Buffer, int MaxLength); SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_symbolize_flush(); +SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE +void __sanitizer_symbolize_demangle(const char *Name, char *Buffer, + int MaxLength); } // extern "C" class InternalSymbolizer { @@ -218,10 +221,21 @@ class InternalSymbolizer { __sanitizer_symbolize_flush(); } + const char *Demangle(const char *name) { + if (__sanitizer_symbolize_demangle) { + char *res = static_cast(InternalAlloc(kMaxDemangledNameSize)); + internal_memset(res, 0, kMaxDemangledNameSize); + __sanitizer_symbolize_demangle(name, res, kMaxDemangledNameSize); + return res; + } + return name; + } + private: InternalSymbolizer() { } static const int kBufferSize = 16 * 1024; + static const int kMaxDemangledNameSize = 1024; char buffer_[kBufferSize]; }; #else // SANITIZER_SUPPORTS_WEAK_HOOKS @@ -232,8 +246,8 @@ class InternalSymbolizer { char *SendCommand(bool is_data, const char *module_name, uptr module_offset) { return 0; } - void Flush() { - } + void Flush() { } + const char *Demangle(const char *name) { return name; } }; #endif // SANITIZER_SUPPORTS_WEAK_HOOKS @@ -345,6 +359,12 @@ class Symbolizer { external_symbolizer_->Flush(); } + const char *Demangle(const char *name) { + if (IsSymbolizerAvailable() && internal_symbolizer_ != 0) + return internal_symbolizer_->Demangle(name); + return DemangleCXXABI(name); + } + private: char *SendCommand(bool is_data, const char *module_name, uptr module_offset) { // First, try to use internal symbolizer. @@ -451,4 +471,8 @@ void FlushSymbolizer() { symbolizer.Flush(); } +const char *Demangle(const char *name) { + return symbolizer.Demangle(name); +} + } // namespace __sanitizer