Index: lib/sanitizer_common/sanitizer_symbolizer.h =================================================================== --- lib/sanitizer_common/sanitizer_symbolizer.h +++ lib/sanitizer_common/sanitizer_symbolizer.h @@ -140,13 +140,6 @@ bool FindModuleNameAndOffsetForAddress(uptr address, const char **module_name, uptr *module_offset); LoadedModule *FindModuleForAddress(uptr address); - // FIXME: get rid of this virtual method, just use GetListOfModules directly. - // The only reason we don't do it right away is that GetListOfModules is - // currently implemented in a libcdep file. - virtual uptr PlatformGetListOfModules(LoadedModule *modules, - uptr max_modules) { - UNIMPLEMENTED(); - } LoadedModule modules_[kMaxNumberOfModules]; uptr n_modules_; // If stale, need to reload the modules before looking up addresses. Index: lib/sanitizer_common/sanitizer_symbolizer.cc =================================================================== --- lib/sanitizer_common/sanitizer_symbolizer.cc +++ lib/sanitizer_common/sanitizer_symbolizer.cc @@ -95,44 +95,6 @@ return last_match_; } -bool Symbolizer::FindModuleNameAndOffsetForAddress(uptr address, - const char **module_name, - uptr *module_offset) { - LoadedModule *module = FindModuleForAddress(address); - if (module == 0) - return false; - *module_name = module->full_name(); - *module_offset = address - module->base_address(); - return true; -} - -LoadedModule *Symbolizer::FindModuleForAddress(uptr address) { - bool modules_were_reloaded = false; - if (!modules_fresh_) { - for (uptr i = 0; i < n_modules_; i++) - modules_[i].clear(); - n_modules_ = PlatformGetListOfModules(modules_, kMaxNumberOfModules); - CHECK_GT(n_modules_, 0); - CHECK_LT(n_modules_, kMaxNumberOfModules); - modules_fresh_ = true; - modules_were_reloaded = true; - } - for (uptr i = 0; i < n_modules_; i++) { - if (modules_[i].containsAddress(address)) { - return &modules_[i]; - } - } - // Reload the modules and look up again, if we haven't tried it yet. - if (!modules_were_reloaded) { - // FIXME: set modules_fresh_ from dlopen()/dlclose() interceptors. - // It's too aggressive to reload the list of modules each time we fail - // to find a module for a given address. - modules_fresh_ = false; - return FindModuleForAddress(address); - } - return 0; -} - Symbolizer::Symbolizer(IntrusiveList tools) : module_names_(&mu_), n_modules_(0), modules_fresh_(false), tools_(tools), start_hook_(0), end_hook_(0) {} @@ -148,80 +110,4 @@ sym_->end_hook_(); } -SymbolizedStack *Symbolizer::SymbolizePC(uptr addr) { - BlockingMutexLock l(&mu_); - const char *module_name; - uptr module_offset; - SymbolizedStack *res = SymbolizedStack::New(addr); - if (!FindModuleNameAndOffsetForAddress(addr, &module_name, &module_offset)) - return res; - // Always fill data about module name and offset. - res->info.FillModuleInfo(module_name, module_offset); - for (auto iter = Iterator(&tools_); iter.hasNext();) { - auto *tool = iter.next(); - SymbolizerScope sym_scope(this); - if (tool->SymbolizePC(addr, res)) { - return res; - } - } - return res; -} - -bool Symbolizer::SymbolizeData(uptr addr, DataInfo *info) { - BlockingMutexLock l(&mu_); - const char *module_name; - uptr module_offset; - if (!FindModuleNameAndOffsetForAddress(addr, &module_name, &module_offset)) - return false; - info->Clear(); - info->module = internal_strdup(module_name); - info->module_offset = module_offset; - for (auto iter = Iterator(&tools_); iter.hasNext();) { - auto *tool = iter.next(); - SymbolizerScope sym_scope(this); - if (tool->SymbolizeData(addr, info)) { - return true; - } - } - return true; -} - -bool Symbolizer::GetModuleNameAndOffsetForPC(uptr pc, const char **module_name, - uptr *module_address) { - BlockingMutexLock l(&mu_); - const char *internal_module_name = nullptr; - if (!FindModuleNameAndOffsetForAddress(pc, &internal_module_name, - module_address)) - return false; - - if (module_name) - *module_name = module_names_.GetOwnedCopy(internal_module_name); - return true; -} - -void Symbolizer::Flush() { - BlockingMutexLock l(&mu_); - for (auto iter = Iterator(&tools_); iter.hasNext();) { - auto *tool = iter.next(); - SymbolizerScope sym_scope(this); - tool->Flush(); - } -} - -const char *Symbolizer::Demangle(const char *name) { - BlockingMutexLock l(&mu_); - for (auto iter = Iterator(&tools_); iter.hasNext();) { - auto *tool = iter.next(); - SymbolizerScope sym_scope(this); - if (const char *demangled = tool->Demangle(name)) - return demangled; - } - return PlatformDemangle(name); -} - -void Symbolizer::PrepareForSandboxing() { - BlockingMutexLock l(&mu_); - PlatformPrepareForSandboxing(); -} - } // namespace __sanitizer Index: lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc =================================================================== --- lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc +++ lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc @@ -60,6 +60,121 @@ return prefix_end; } +SymbolizedStack *Symbolizer::SymbolizePC(uptr addr) { + BlockingMutexLock l(&mu_); + const char *module_name; + uptr module_offset; + SymbolizedStack *res = SymbolizedStack::New(addr); + if (!FindModuleNameAndOffsetForAddress(addr, &module_name, &module_offset)) + return res; + // Always fill data about module name and offset. + res->info.FillModuleInfo(module_name, module_offset); + for (auto iter = Iterator(&tools_); iter.hasNext();) { + auto *tool = iter.next(); + SymbolizerScope sym_scope(this); + if (tool->SymbolizePC(addr, res)) { + return res; + } + } + return res; +} + +bool Symbolizer::SymbolizeData(uptr addr, DataInfo *info) { + BlockingMutexLock l(&mu_); + const char *module_name; + uptr module_offset; + if (!FindModuleNameAndOffsetForAddress(addr, &module_name, &module_offset)) + return false; + info->Clear(); + info->module = internal_strdup(module_name); + info->module_offset = module_offset; + for (auto iter = Iterator(&tools_); iter.hasNext();) { + auto *tool = iter.next(); + SymbolizerScope sym_scope(this); + if (tool->SymbolizeData(addr, info)) { + return true; + } + } + return true; +} + +bool Symbolizer::GetModuleNameAndOffsetForPC(uptr pc, const char **module_name, + uptr *module_address) { + BlockingMutexLock l(&mu_); + const char *internal_module_name = nullptr; + if (!FindModuleNameAndOffsetForAddress(pc, &internal_module_name, + module_address)) + return false; + + if (module_name) + *module_name = module_names_.GetOwnedCopy(internal_module_name); + return true; +} + +void Symbolizer::Flush() { + BlockingMutexLock l(&mu_); + for (auto iter = Iterator(&tools_); iter.hasNext();) { + auto *tool = iter.next(); + SymbolizerScope sym_scope(this); + tool->Flush(); + } +} + +const char *Symbolizer::Demangle(const char *name) { + BlockingMutexLock l(&mu_); + for (auto iter = Iterator(&tools_); iter.hasNext();) { + auto *tool = iter.next(); + SymbolizerScope sym_scope(this); + if (const char *demangled = tool->Demangle(name)) + return demangled; + } + return PlatformDemangle(name); +} + +void Symbolizer::PrepareForSandboxing() { + BlockingMutexLock l(&mu_); + PlatformPrepareForSandboxing(); +} + +bool Symbolizer::FindModuleNameAndOffsetForAddress(uptr address, + const char **module_name, + uptr *module_offset) { + LoadedModule *module = FindModuleForAddress(address); + if (module == 0) + return false; + *module_name = module->full_name(); + *module_offset = address - module->base_address(); + return true; +} + +LoadedModule *Symbolizer::FindModuleForAddress(uptr address) { + bool modules_were_reloaded = false; + if (!modules_fresh_) { + for (uptr i = 0; i < n_modules_; i++) + modules_[i].clear(); + n_modules_ = + GetListOfModules(modules_, kMaxNumberOfModules, /* filter */ nullptr); + CHECK_GT(n_modules_, 0); + CHECK_LT(n_modules_, kMaxNumberOfModules); + modules_fresh_ = true; + modules_were_reloaded = true; + } + for (uptr i = 0; i < n_modules_; i++) { + if (modules_[i].containsAddress(address)) { + return &modules_[i]; + } + } + // Reload the modules and look up again, if we haven't tried it yet. + if (!modules_were_reloaded) { + // FIXME: set modules_fresh_ from dlopen()/dlclose() interceptors. + // It's too aggressive to reload the list of modules each time we fail + // to find a module for a given address. + modules_fresh_ = false; + return FindModuleForAddress(address); + } + return 0; +} + Symbolizer *Symbolizer::GetOrInit() { SpinMutexLock l(&init_mu_); if (symbolizer_) 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 @@ -355,11 +355,6 @@ : Symbolizer(tools) {} private: - uptr PlatformGetListOfModules(LoadedModule *modules, - uptr max_modules) override { - return ::GetListOfModules(modules, max_modules, /* filter */ nullptr); - } - const char *PlatformDemangle(const char *name) override { return DemangleCXXABI(name); } Index: lib/sanitizer_common/sanitizer_symbolizer_win.cc =================================================================== --- lib/sanitizer_common/sanitizer_symbolizer_win.cc +++ lib/sanitizer_common/sanitizer_symbolizer_win.cc @@ -136,10 +136,6 @@ : Symbolizer(tools) {} private: - uptr PlatformGetListOfModules(LoadedModule *modules, - uptr max_modules) override { - return ::GetListOfModules(modules, max_modules, /* filter */ nullptr); - } const char *PlatformDemangle(const char *name) override { return name; } void PlatformPrepareForSandboxing() override { } };