diff options
author | Alexey Samsonov <samsonov@google.com> | 2013-10-31 21:44:07 +0000 |
---|---|---|
committer | Alexey Samsonov <samsonov@google.com> | 2013-10-31 21:44:07 +0000 |
commit | 66d91e3356a0c4d7aff3beaaaff3e87bbaec805c (patch) | |
tree | f8c46cf4e4982459fff87bc1d2e3f3e4b3c5c0ce | |
parent | b8a141f3783d796eabf45fabff82f3e08244e338 (diff) | |
download | compiler-rt-66d91e3356a0c4d7aff3beaaaff3e87bbaec805c.tar.gz |
[Sanitizer] Add Symbolizer::AddHooks() and use it in TSan and MSan.
Summary:
TSan and MSan need to know if interceptor was called by the
user code or by the symbolizer and use pre- and post-symbolization hooks
for that. Make Symbolizer class responsible for calling these hooks instead.
This would ensure the hooks are only called when necessary (during
in-process symbolization, they are not needed for out-of-process) and
save specific sanitizers from tracing all places in the code where symbolization
will be performed.
Reviewers: eugenis, dvyukov
Reviewed By: eugenis
CC: llvm-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D2067
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@193807 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/msan/msan.cc | 1 | ||||
-rw-r--r-- | lib/msan/msan_report.cc | 6 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer.cc | 20 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer.h | 22 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc | 11 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_rtl.cc | 1 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_symbolize.cc | 25 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_symbolize.h | 2 |
8 files changed, 66 insertions, 22 deletions
diff --git a/lib/msan/msan.cc b/lib/msan/msan.cc index 8d2c5ec9c..694733b70 100644 --- a/lib/msan/msan.cc +++ b/lib/msan/msan.cc @@ -337,6 +337,7 @@ void __msan_init() { if (external_symbolizer && external_symbolizer[0]) { CHECK(external_symbolizer_started); } + Symbolizer::Get()->AddHooks(EnterSymbolizer, ExitSymbolizer); GetThreadStackTopAndBottom(/* at_initialization */true, &__msan_stack_bounds.stack_top, diff --git a/lib/msan/msan_report.cc b/lib/msan/msan_report.cc index a629304e6..bb591ebda 100644 --- a/lib/msan/msan_report.cc +++ b/lib/msan/msan_report.cc @@ -35,7 +35,6 @@ class Decorator: private __sanitizer::AnsiColorDecorator { }; static void PrintStack(const uptr *trace, uptr size) { - SymbolizerScope sym_scope; StackTrace::PrintStack(trace, size); Printf("\n"); } @@ -76,10 +75,7 @@ static void ReportSummary(const char *error_type, StackTrace *stack) { if (!stack->size || !Symbolizer::Get()->IsAvailable()) return; AddressInfo ai; uptr pc = StackTrace::GetPreviousInstructionPc(stack->trace[0]); - { - SymbolizerScope sym_scope; - Symbolizer::Get()->SymbolizeCode(pc, &ai, 1); - } + Symbolizer::Get()->SymbolizeCode(pc, &ai, 1); ReportErrorSummary(error_type, ai.file, ai.line, ai.function); } diff --git a/lib/sanitizer_common/sanitizer_symbolizer.cc b/lib/sanitizer_common/sanitizer_symbolizer.cc index 6bec459b7..2290767b0 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer.cc +++ b/lib/sanitizer_common/sanitizer_symbolizer.cc @@ -40,4 +40,24 @@ Symbolizer *Symbolizer::Disable() { return symbolizer_; } +void Symbolizer::AddHooks(Symbolizer::StartSymbolizationHook start_hook, + Symbolizer::EndSymbolizationHook end_hook) { + CHECK(start_hook_ == 0 && end_hook_ == 0); + start_hook_ = start_hook; + end_hook_ = end_hook; +} + +Symbolizer::Symbolizer() : start_hook_(0), end_hook_(0) {} + +Symbolizer::SymbolizerScope::SymbolizerScope(const Symbolizer *sym) + : sym_(sym) { + if (sym_->start_hook_) + sym_->start_hook_(); +} + +Symbolizer::SymbolizerScope::~SymbolizerScope() { + if (sym_->end_hook_) + sym_->end_hook_(); +} + } // namespace __sanitizer diff --git a/lib/sanitizer_common/sanitizer_symbolizer.h b/lib/sanitizer_common/sanitizer_symbolizer.h index f41913281..886fed20d 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer.h +++ b/lib/sanitizer_common/sanitizer_symbolizer.h @@ -105,6 +105,16 @@ class Symbolizer { } virtual void PrepareForSandboxing() {} + // Allow user to install hooks that would be called before/after Symbolizer + // does the actual file/line info fetching. Specific sanitizers may need this + // to distinguish system library calls made in user code from calls made + // during in-process symbolization. + typedef void (*StartSymbolizationHook)(); + typedef void (*EndSymbolizationHook)(); + // May be called at most once. + void AddHooks(StartSymbolizationHook start_hook, + EndSymbolizationHook end_hook); + private: /// Platform-specific function for creating a Symbolizer object. static Symbolizer *PlatformInit(const char *path_to_external); @@ -116,7 +126,19 @@ class Symbolizer { static StaticSpinMutex init_mu_; protected: + Symbolizer(); + static LowLevelAllocator symbolizer_allocator_; + + StartSymbolizationHook start_hook_; + EndSymbolizationHook end_hook_; + class SymbolizerScope { + public: + explicit SymbolizerScope(const Symbolizer *sym); + ~SymbolizerScope(); + private: + const Symbolizer *sym_; + }; }; } // namespace __sanitizer diff --git a/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc b/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc index 206de8633..de1183287 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc @@ -368,7 +368,8 @@ class POSIXSymbolizer : public Symbolizer { public: POSIXSymbolizer(ExternalSymbolizer *external_symbolizer, InternalSymbolizer *internal_symbolizer) - : external_symbolizer_(external_symbolizer), + : Symbolizer(), + external_symbolizer_(external_symbolizer), internal_symbolizer_(internal_symbolizer) {} uptr SymbolizeCode(uptr addr, AddressInfo *frames, uptr max_frames) { @@ -463,14 +464,19 @@ class POSIXSymbolizer : public Symbolizer { void Flush() { BlockingMutexLock l(&mu_); - if (internal_symbolizer_ != 0) + if (internal_symbolizer_ != 0) { + SymbolizerScope sym_scope(this); internal_symbolizer_->Flush(); + } if (external_symbolizer_ != 0) external_symbolizer_->Flush(); } const char *Demangle(const char *name) { BlockingMutexLock l(&mu_); + // Run hooks even if we don't use internal symbolizer, as cxxabi + // demangle may call system functions. + SymbolizerScope sym_scope(this); if (internal_symbolizer_ != 0) return internal_symbolizer_->Demangle(name); return DemangleCXXABI(name); @@ -489,6 +495,7 @@ class POSIXSymbolizer : public Symbolizer { mu_.CheckLocked(); // First, try to use internal symbolizer. if (internal_symbolizer_) { + SymbolizerScope sym_scope(this); return internal_symbolizer_->SendCommand(is_data, module_name, module_offset); } diff --git a/lib/tsan/rtl/tsan_rtl.cc b/lib/tsan/rtl/tsan_rtl.cc index fc2aa767b..1f66d29a7 100644 --- a/lib/tsan/rtl/tsan_rtl.cc +++ b/lib/tsan/rtl/tsan_rtl.cc @@ -246,6 +246,7 @@ void Initialize(ThreadState *thr) { external_symbolizer); Die(); } + Symbolizer::Get()->AddHooks(EnterSymbolizer, ExitSymbolizer); #endif internal_start_thread(&BackgroundThread, 0); diff --git a/lib/tsan/rtl/tsan_symbolize.cc b/lib/tsan/rtl/tsan_symbolize.cc index a2ed5d059..24c747227 100644 --- a/lib/tsan/rtl/tsan_symbolize.cc +++ b/lib/tsan/rtl/tsan_symbolize.cc @@ -22,19 +22,17 @@ namespace __tsan { -struct ScopedInSymbolizer { - ScopedInSymbolizer() { - ThreadState *thr = cur_thread(); - CHECK(!thr->in_symbolizer); - thr->in_symbolizer = true; - } +void EnterSymbolizer() { + ThreadState *thr = cur_thread(); + CHECK(!thr->in_symbolizer); + thr->in_symbolizer = true; +} - ~ScopedInSymbolizer() { - ThreadState *thr = cur_thread(); - CHECK(thr->in_symbolizer); - thr->in_symbolizer = false; - } -}; +void ExitSymbolizer() { + ThreadState *thr = cur_thread(); + CHECK(thr->in_symbolizer); + thr->in_symbolizer = false; +} ReportStack *NewReportStackEntry(uptr addr) { ReportStack *ent = (ReportStack*)internal_alloc(MBlockReportStack, @@ -121,7 +119,6 @@ ReportStack *SymbolizeCode(uptr addr) { } if (!Symbolizer::Get()->IsAvailable()) return SymbolizeCodeAddr2Line(addr); - ScopedInSymbolizer in_symbolizer; static const uptr kMaxAddrFrames = 16; InternalScopedBuffer<AddressInfo> addr_frames(kMaxAddrFrames); for (uptr i = 0; i < kMaxAddrFrames; i++) @@ -148,7 +145,6 @@ ReportStack *SymbolizeCode(uptr addr) { ReportLocation *SymbolizeData(uptr addr) { if (!Symbolizer::Get()->IsAvailable()) return 0; - ScopedInSymbolizer in_symbolizer; DataInfo info; if (!Symbolizer::Get()->SymbolizeData(addr, &info)) return 0; @@ -168,7 +164,6 @@ ReportLocation *SymbolizeData(uptr addr) { void SymbolizeFlush() { if (!Symbolizer::Get()->IsAvailable()) return; - ScopedInSymbolizer in_symbolizer; Symbolizer::Get()->Flush(); } diff --git a/lib/tsan/rtl/tsan_symbolize.h b/lib/tsan/rtl/tsan_symbolize.h index 7bc6123df..6282e45b4 100644 --- a/lib/tsan/rtl/tsan_symbolize.h +++ b/lib/tsan/rtl/tsan_symbolize.h @@ -18,6 +18,8 @@ namespace __tsan { +void EnterSymbolizer(); +void ExitSymbolizer(); ReportStack *SymbolizeCode(uptr addr); ReportLocation *SymbolizeData(uptr addr); void SymbolizeFlush(); |