Index: lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.h =================================================================== --- lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.h +++ lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.h @@ -28,17 +28,16 @@ namespace __sanitizer { -class LibbacktraceSymbolizer { +class LibbacktraceSymbolizer : public SymbolizerTool { public: static LibbacktraceSymbolizer *get(LowLevelAllocator *alloc); - SymbolizedStack *SymbolizeCode(uptr addr, const char *module_name, - uptr module_offset); + bool SymbolizePC(uptr addr, SymbolizedStack *stack) override; - bool SymbolizeData(uptr addr, DataInfo *info); + bool SymbolizeData(uptr addr, DataInfo *info) override; // May return NULL if demangling failed. - static char *Demangle(const char *name, bool always_alloc = false); + const char *Demangle(const char *name) override; private: explicit LibbacktraceSymbolizer(void *state) : state_(state) {} Index: lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc =================================================================== --- lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc +++ lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc @@ -33,6 +33,8 @@ namespace __sanitizer { +char *DemangleAlloc(const char *name, bool always_alloc); + #if SANITIZER_LIBBACKTRACE namespace { @@ -86,8 +88,7 @@ struct SymbolizeCodeCallbackArg { SymbolizedStack *first; SymbolizedStack *last; - const char *module_name; - uptr module_offset; + uptr frames_symbolized; void append(SymbolizedStack *f) { if (last != nullptr) { @@ -98,6 +99,20 @@ last = f; } } + + AddressInfo *get_new_frame(uintptr_t addr) { + SymbolizedStack *cur = last; + if (frames_symbolized > 0) { + cur = SymbolizedStack::New(addr); + AddressInfo *info = &cur->info; + info->FillAddressAndModuleInfo(addr, first->info.module, + first->info.module_offset); + append(cur); + } else { + CHECK_EQ(addr, cur->info.address); + } + return &cur->info; + } }; extern "C" { @@ -106,15 +121,12 @@ const char *function) { SymbolizeCodeCallbackArg *cdata = (SymbolizeCodeCallbackArg *)vdata; if (function) { - SymbolizedStack *cur = SymbolizedStack::New(addr); - cdata->append(cur); - AddressInfo *info = &cur->info; - info->FillAddressAndModuleInfo(addr, cdata->module_name, - cdata->module_offset); - info->function = LibbacktraceSymbolizer::Demangle(function, true); + AddressInfo *info = cdata->get_new_frame(addr); + info->function = DemangleAlloc(function, /*always_alloc*/ true); if (filename) info->file = internal_strdup(filename); info->line = lineno; + cdata->frames_symbolized++; } return 0; } @@ -123,12 +135,9 @@ const char *symname, uintptr_t, uintptr_t) { SymbolizeCodeCallbackArg *cdata = (SymbolizeCodeCallbackArg *)vdata; if (symname) { - SymbolizedStack *cur = SymbolizedStack::New(addr); - cdata->append(cur); - AddressInfo *info = &cur->info; - info->FillAddressAndModuleInfo(addr, cdata->module_name, - cdata->module_offset); - info->function = LibbacktraceSymbolizer::Demangle(symname, true); + AddressInfo *info = cdata->get_new_frame(addr); + info->function = DemangleAlloc(symname, /*always_alloc*/ true); + cdata->frames_symbolized++; } } @@ -136,7 +145,7 @@ uintptr_t symval, uintptr_t symsize) { DataInfo *info = (DataInfo *)vdata; if (symname && symval) { - info->name = LibbacktraceSymbolizer::Demangle(symname, true); + info->name = DemangleAlloc(symname, /*always_alloc*/ true); info->start = symval; info->size = symsize; } @@ -156,21 +165,18 @@ return new(*alloc) LibbacktraceSymbolizer(state); } -SymbolizedStack *LibbacktraceSymbolizer::SymbolizeCode(uptr addr, - const char *module_name, - uptr module_offset) { +bool LibbacktraceSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) { SymbolizeCodeCallbackArg data; - data.first = nullptr; - data.last = nullptr; - data.module_name = module_name; - data.module_offset = module_offset; + data.first = stack; + data.last = stack; + data.frames_symbolized = 0; backtrace_pcinfo((backtrace_state *)state_, addr, SymbolizeCodePCInfoCallback, ErrorCallback, &data); - if (data.first) - return data.first; + if (data.frames_symbolized > 0) + return true; backtrace_syminfo((backtrace_state *)state_, addr, SymbolizeCodeCallback, ErrorCallback, &data); - return data.first; + return true; } bool LibbacktraceSymbolizer::SymbolizeData(uptr addr, DataInfo *info) { @@ -185,11 +191,9 @@ return 0; } -SymbolizedStack *LibbacktraceSymbolizer::SymbolizeCode(uptr addr, - const char *module_name, - uptr module_offset) { +bool LibbacktraceSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) { (void)state_; - return nullptr; + return false; } bool LibbacktraceSymbolizer::SymbolizeData(uptr addr, DataInfo *info) { @@ -198,7 +202,7 @@ #endif // SANITIZER_LIBBACKTRACE -char *LibbacktraceSymbolizer::Demangle(const char *name, bool always_alloc) { +char *DemangleAlloc(const char *name, bool always_alloc) { #if SANITIZER_LIBBACKTRACE && SANITIZER_CP_DEMANGLE if (char *demangled = CplusV3Demangle(name)) return demangled; @@ -208,4 +212,8 @@ return 0; } +const char *LibbacktraceSymbolizer::Demangle(const char *name) { + return DemangleAlloc(name, /*always_alloc*/ false); +} + } // namespace __sanitizer Index: lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc =================================================================== --- lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc +++ lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc @@ -569,16 +569,15 @@ uptr module_offset; if (!FindModuleNameAndOffsetForAddress(addr, &module_name, &module_offset)) return SymbolizedStack::New(addr); + // Always fill data about module name and offset. + SymbolizedStack *res = SymbolizedStack::New(addr); + res->info.FillAddressAndModuleInfo(addr, module_name, module_offset); // First, try to use libbacktrace symbolizer (if it's available). if (libbacktrace_symbolizer_ != 0) { mu_.CheckLocked(); - if (SymbolizedStack *res = libbacktrace_symbolizer_->SymbolizeCode( - addr, module_name, module_offset)) + if (libbacktrace_symbolizer_->SymbolizePC(addr, res)) return res; } - // Always fill data about module name and offset. - SymbolizedStack *res = SymbolizedStack::New(addr); - res->info.FillAddressAndModuleInfo(addr, module_name, module_offset); if (SymbolizerTool *tool = GetSymbolizerTool()) { SymbolizerScope sym_scope(this); tool->SymbolizePC(addr, res);