summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Samsonov <samsonov@google.com>2013-10-31 21:44:07 +0000
committerAlexey Samsonov <samsonov@google.com>2013-10-31 21:44:07 +0000
commit66d91e3356a0c4d7aff3beaaaff3e87bbaec805c (patch)
treef8c46cf4e4982459fff87bc1d2e3f3e4b3c5c0ce
parentb8a141f3783d796eabf45fabff82f3e08244e338 (diff)
downloadcompiler-rt-66d91e3356a0c4d7aff3beaaaff3e87bbaec805c.tar.gz
compiler-rt-66d91e3356a0c4d7aff3beaaaff3e87bbaec805c.tar.bz2
compiler-rt-66d91e3356a0c4d7aff3beaaaff3e87bbaec805c.tar.xz
[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.cc1
-rw-r--r--lib/msan/msan_report.cc6
-rw-r--r--lib/sanitizer_common/sanitizer_symbolizer.cc20
-rw-r--r--lib/sanitizer_common/sanitizer_symbolizer.h22
-rw-r--r--lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc11
-rw-r--r--lib/tsan/rtl/tsan_rtl.cc1
-rw-r--r--lib/tsan/rtl/tsan_symbolize.cc25
-rw-r--r--lib/tsan/rtl/tsan_symbolize.h2
8 files changed, 66 insertions, 22 deletions
diff --git a/lib/msan/msan.cc b/lib/msan/msan.cc
index 8d2c5ec9..694733b7 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 a629304e..bb591ebd 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 6bec459b..2290767b 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 f4191328..886fed20 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 206de863..de118328 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 fc2aa767..1f66d29a 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 a2ed5d05..24c74722 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 7bc6123d..6282e45b 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();