From e2aa5b2ace432d24be067044a333128514b46faf Mon Sep 17 00:00:00 2001 From: Francis Ricci Date: Mon, 2 Oct 2017 14:30:58 +0000 Subject: [PATCH] Add support for custom loaders to the sanitizer symbolizer Summary: Adds a fallback mode to procmaps when the symbolizer fails to locate a module for a given address by using dl_iterate_phdr. Reviewers: kubamracek, rnk, vitalybuka, eugenis Reviewed By: eugenis Subscribers: srhines, llvm-commits Differential Revision: https://reviews.llvm.org/D37269 llvm-svn: 314671 --- compiler-rt/lib/sanitizer_common/sanitizer_common.h | 1 + compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc | 11 +++++++++++ compiler-rt/lib/sanitizer_common/sanitizer_mac.cc | 2 ++ compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h | 1 + .../lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc | 5 +++++ compiler-rt/lib/sanitizer_common/sanitizer_win.cc | 4 +++- 6 files changed, 23 insertions(+), 1 deletion(-) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h index 11ee590..ee5eca5 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -730,6 +730,7 @@ class ListOfModules { ListOfModules() : initialized(false) {} ~ListOfModules() { clear(); } void init(); + void fallbackInit(); // Uses fallback init if available, otherwise clears const LoadedModule *begin() const { return modules_.begin(); } LoadedModule *begin() { return modules_.begin(); } const LoadedModule *end() const { return modules_.end(); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc index 0f42087..c25b561 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc @@ -488,6 +488,17 @@ void ListOfModules::init() { } } +// When a custom loader is used, dl_iterate_phdr may not contain the full +// list of modules. Allow callers to fall back to using procmaps. +void ListOfModules::fallbackInit() { + if (!requiresProcmaps()) { + clearOrInit(); + procmapsInit(&modules_); + } else { + clear(); + } +} + // getrusage does not give us the current RSS, only the max RSS. // Still, this is better than nothing if /proc/self/statm is not available // for some reason, e.g. due to a sandbox. diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc index cd63cb4..9fead91 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc @@ -416,6 +416,8 @@ void ListOfModules::init() { memory_mapping.DumpListOfModules(&modules_); } +void ListOfModules::fallbackInit() { clear(); } + static HandleSignalMode GetHandleSignalModeImpl(int signum) { switch (signum) { case SIGABRT: diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h index 9558712..208362d 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h @@ -152,6 +152,7 @@ class Symbolizer final { uptr *module_offset, ModuleArch *module_arch); ListOfModules modules_; + ListOfModules fallback_modules_; // If stale, need to reload the modules before looking up addresses. bool modules_fresh_; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc index 37ac12c..a4bab66 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc @@ -165,6 +165,7 @@ bool Symbolizer::FindModuleNameAndOffsetForAddress(uptr address, void Symbolizer::RefreshModules() { modules_.init(); + fallback_modules_.fallbackInit(); RAW_CHECK(modules_.size() > 0); modules_fresh_ = true; } @@ -198,6 +199,10 @@ const LoadedModule *Symbolizer::FindModuleForAddress(uptr address) { if (module) return module; } #endif + + if (fallback_modules_.size()) { + module = SearchForModule(fallback_modules_, address); + } return module; } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cc b/compiler-rt/lib/sanitizer_common/sanitizer_win.cc index 84065aa..f1a74d3 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cc @@ -583,7 +583,9 @@ void ListOfModules::init() { modules_.push_back(cur_module); } UnmapOrDie(hmodules, modules_buffer_size); -}; +} + +void ListOfModules::fallbackInit() { clear(); } // We can't use atexit() directly at __asan_init time as the CRT is not fully // initialized at this point. Place the functions into a vector and use -- 2.7.4