summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.cc')
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.cc51
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)
OpenPOWER on IntegriCloud