diff options
Diffstat (limited to 'compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.cc')
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.cc | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.cc b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.cc index 5664543a7f1..88bd2f8d896 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.cc @@ -95,8 +95,47 @@ const char *Symbolizer::ModuleNameOwner::GetOwnedCopy(const char *str) { 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<SymbolizerTool> tools) - : module_names_(&mu_), tools_(tools), start_hook_(0), end_hook_(0) {} + : module_names_(&mu_), n_modules_(0), modules_fresh_(false), tools_(tools), + start_hook_(0), end_hook_(0) {} Symbolizer::SymbolizerScope::SymbolizerScope(const Symbolizer *sym) : sym_(sym) { @@ -114,8 +153,7 @@ SymbolizedStack *Symbolizer::SymbolizePC(uptr addr) { const char *module_name; uptr module_offset; SymbolizedStack *res = SymbolizedStack::New(addr); - if (!PlatformFindModuleNameAndOffsetForAddress(addr, &module_name, - &module_offset)) + if (!FindModuleNameAndOffsetForAddress(addr, &module_name, &module_offset)) return res; // Always fill data about module name and offset. res->info.FillModuleInfo(module_name, module_offset); @@ -133,8 +171,7 @@ bool Symbolizer::SymbolizeData(uptr addr, DataInfo *info) { BlockingMutexLock l(&mu_); const char *module_name; uptr module_offset; - if (!PlatformFindModuleNameAndOffsetForAddress(addr, &module_name, - &module_offset)) + if (!FindModuleNameAndOffsetForAddress(addr, &module_name, &module_offset)) return false; info->Clear(); info->module = internal_strdup(module_name); @@ -153,8 +190,8 @@ bool Symbolizer::GetModuleNameAndOffsetForPC(uptr pc, const char **module_name, uptr *module_address) { BlockingMutexLock l(&mu_); const char *internal_module_name = nullptr; - if (!PlatformFindModuleNameAndOffsetForAddress(pc, &internal_module_name, - module_address)) + if (!FindModuleNameAndOffsetForAddress(pc, &internal_module_name, + module_address)) return false; if (module_name) |