Index: lib/sanitizer_common/sanitizer_symbolizer_internal.h =================================================================== --- lib/sanitizer_common/sanitizer_symbolizer_internal.h +++ lib/sanitizer_common/sanitizer_symbolizer_internal.h @@ -28,6 +28,8 @@ class SymbolizerTool { public: + SymbolizerTool *next; + // Can't declare pure virtual functions in sanitizer runtimes: // __cxa_pure_virtual might be unavailable. 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 @@ -350,8 +350,11 @@ class POSIXSymbolizer : public Symbolizer { public: - explicit POSIXSymbolizer(SymbolizerTool *symbolizer_tool) - : Symbolizer(), symbolizer_tool_(symbolizer_tool) {} + explicit POSIXSymbolizer() : Symbolizer() {} + + void AppendSymbolizerTool(SymbolizerTool *tool) { + tools_.push_back(tool); + } SymbolizedStack *SymbolizePC(uptr addr) override { BlockingMutexLock l(&mu_); @@ -362,9 +365,12 @@ return res; // Always fill data about module name and offset. res->info.FillModuleInfo(module_name, module_offset); - if (symbolizer_tool_) { + for (auto iter = Iterator(&tools_); iter.hasNext();) { + auto *tool = iter.next(); SymbolizerScope sym_scope(this); - symbolizer_tool_->SymbolizePC(addr, res); + if (tool->SymbolizePC(addr, res)) { + break; + } } return res; } @@ -379,9 +385,12 @@ info->Clear(); info->module = internal_strdup(module_name); info->module_offset = module_offset; - if (symbolizer_tool_) { + for (auto iter = Iterator(&tools_); iter.hasNext();) { + auto *tool = iter.next(); SymbolizerScope sym_scope(this); - symbolizer_tool_->SymbolizeData(addr, info); + if (tool->SymbolizeData(addr, info)) { + break; + } } return true; } @@ -393,22 +402,24 @@ } bool CanReturnFileLineInfo() override { - return symbolizer_tool_ != nullptr; + return !tools_.empty(); } void Flush() override { BlockingMutexLock l(&mu_); - if (symbolizer_tool_) { + for (auto iter = Iterator(&tools_); iter.hasNext();) { + auto *tool = iter.next(); SymbolizerScope sym_scope(this); - symbolizer_tool_->Flush(); + tool->Flush(); } } const char *Demangle(const char *name) override { BlockingMutexLock l(&mu_); - if (symbolizer_tool_) { + for (auto iter = Iterator(&tools_); iter.hasNext();) { + auto *tool = iter.next(); SymbolizerScope sym_scope(this); - if (const char *demangled = symbolizer_tool_->Demangle(name)) + if (const char *demangled = tool->Demangle(name)) return demangled; } return DemangleCXXABI(name); @@ -472,7 +483,8 @@ bool modules_fresh_; BlockingMutex mu_; - SymbolizerTool *const symbolizer_tool_; // Leaked. + typedef IntrusiveList::Iterator Iterator; + IntrusiveList tools_; }; static SymbolizerTool *ChooseSymbolizer(LowLevelAllocator *allocator) { @@ -507,8 +519,11 @@ } Symbolizer *Symbolizer::PlatformInit() { - return new(symbolizer_allocator_) - POSIXSymbolizer(ChooseSymbolizer(&symbolizer_allocator_)); + POSIXSymbolizer *symbolizer = new(symbolizer_allocator_) POSIXSymbolizer(); + if (SymbolizerTool *tool = ChooseSymbolizer(&symbolizer_allocator_)) { + symbolizer->AppendSymbolizerTool(tool); + } + return symbolizer; } } // namespace __sanitizer