From 1ea789be4f8a6a54b46e36fe8a0eed020b7a93ca Mon Sep 17 00:00:00 2001 From: Francis Ricci Date: Tue, 26 Sep 2017 16:12:56 +0000 Subject: Invalidate symbolizer module list from dlopen/dlclose interceptors Summary: The module list should only be invalidated by dlopen and dlclose, so the symbolizer should only re-generate it when we've hit one of those functions. Reviewers: kubamracek, rnk, vitalybuka Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D37268 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@314219 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/sanitizer_common/sanitizer_common_interceptors.inc | 3 +++ lib/sanitizer_common/sanitizer_symbolizer.cc | 4 ++++ lib/sanitizer_common/sanitizer_symbolizer.h | 2 ++ lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc | 9 +++++---- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc index b9c182e65..21a405ae4 100644 --- a/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -43,6 +43,7 @@ #include "sanitizer_errno.h" #include "sanitizer_placement_new.h" #include "sanitizer_platform_interceptors.h" +#include "sanitizer_symbolizer.h" #include "sanitizer_tls_get_addr.h" #include @@ -5575,6 +5576,7 @@ INTERCEPTOR(void*, dlopen, const char *filename, int flag) { if (filename) COMMON_INTERCEPTOR_READ_STRING(ctx, filename, 0); COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag); void *res = REAL(dlopen)(filename, flag); + Symbolizer::GetOrInit()->InvalidateModuleList(); COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res); return res; } @@ -5583,6 +5585,7 @@ INTERCEPTOR(int, dlclose, void *handle) { void *ctx; COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlclose, handle); int res = REAL(dlclose)(handle); + Symbolizer::GetOrInit()->InvalidateModuleList(); COMMON_INTERCEPTOR_LIBRARY_UNLOADED(); return res; } diff --git a/lib/sanitizer_common/sanitizer_symbolizer.cc b/lib/sanitizer_common/sanitizer_symbolizer.cc index 1cd5b6ee2..672c93668 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer.cc +++ b/lib/sanitizer_common/sanitizer_symbolizer.cc @@ -71,6 +71,10 @@ Symbolizer *Symbolizer::symbolizer_; StaticSpinMutex Symbolizer::init_mu_; LowLevelAllocator Symbolizer::symbolizer_allocator_; +void Symbolizer::InvalidateModuleList() { + modules_fresh_ = false; +} + void Symbolizer::AddHooks(Symbolizer::StartSymbolizationHook start_hook, Symbolizer::EndSymbolizationHook end_hook) { CHECK(start_hook_ == 0 && end_hook_ == 0); diff --git a/lib/sanitizer_common/sanitizer_symbolizer.h b/lib/sanitizer_common/sanitizer_symbolizer.h index 4fc7742a2..543e27e39 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer.h +++ b/lib/sanitizer_common/sanitizer_symbolizer.h @@ -121,6 +121,8 @@ class Symbolizer final { const LoadedModule *FindModuleForAddress(uptr address); + void InvalidateModuleList(); + private: // GetModuleNameAndOffsetForPC has to return a string to the caller. // Since the corresponding module might get unloaded later, we should create diff --git a/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc b/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc index 12369d709..caab4ca35 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc @@ -176,14 +176,15 @@ const LoadedModule *Symbolizer::FindModuleForAddress(uptr address) { return &modules_[i]; } } - // Reload the modules and look up again, if we haven't tried it yet. + // dlopen/dlclose interceptors invalidate the module list, but when + // interception is disabled, we need to retry if the lookup fails in + // case the module list changed. +#if !SANITIZER_INTERCEPT_DLOPEN_DLCLOSE 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); } +#endif return 0; } -- cgit v1.2.1