diff options
author | Vitaly Buka <vitalybuka@google.com> | 2017-09-22 18:32:05 +0000 |
---|---|---|
committer | Vitaly Buka <vitalybuka@google.com> | 2017-09-22 18:32:05 +0000 |
commit | d8e18a4cf6d5b92393cc45311541e55a5d4b0ae0 (patch) | |
tree | 3ba73a8abf58127e734941cb834f2df54022cae8 /compiler-rt | |
parent | 03ac15fffb4b1570462e096382944ce7daf95d27 (diff) | |
download | bcm5719-llvm-d8e18a4cf6d5b92393cc45311541e55a5d4b0ae0.tar.gz bcm5719-llvm-d8e18a4cf6d5b92393cc45311541e55a5d4b0ae0.zip |
[sanitizer] Move report locking code from asan into common
llvm-svn: 314008
Diffstat (limited to 'compiler-rt')
-rw-r--r-- | compiler-rt/lib/asan/asan_report.cc | 55 | ||||
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_common.cc | 36 | ||||
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_common.h | 8 |
3 files changed, 55 insertions, 44 deletions
diff --git a/compiler-rt/lib/asan/asan_report.cc b/compiler-rt/lib/asan/asan_report.cc index d832633dbaf..9536ead660a 100644 --- a/compiler-rt/lib/asan/asan_report.cc +++ b/compiler-rt/lib/asan/asan_report.cc @@ -125,34 +125,16 @@ class ScopedInErrorReport { static const u32 kUnclaimedTid = 0xfffffe; static_assert(kUnclaimedTid != kInvalidTid, "Must be different"); - explicit ScopedInErrorReport(bool fatal = false) { - halt_on_error_ = fatal || flags()->halt_on_error; - u32 current_tid = GetCurrentTidOrInvalid(); - - for (;;) { - u32 expected_tid = kUnclaimedTid; - if (atomic_compare_exchange_strong(&reporting_thread_tid_, &expected_tid, - current_tid, memory_order_relaxed)) { - // We've claimed reporting_thread_tid_ so proceed. - StartReporting(); - return; - } - - if (expected_tid == current_tid) { - // This is either asynch signal or nested error during error reporting. - // Fail simple to avoid deadlocks in Report(). - - // Can't use Report() here because of potential deadlocks in nested - // signal handlers. - static const char msg[] = - "AddressSanitizer: nested bug in the same thread, aborting.\n"; - CatastrophicErrorWrite(msg, sizeof(msg) - 1); - - internal__exit(common_flags()->exitcode); - } - - SleepForMillis(100); - } + explicit ScopedInErrorReport(bool fatal = false) + : error_report_lock_(GetCurrentTidOrInvalid()), + halt_on_error_(fatal || flags()->halt_on_error) { + // Make sure the registry and sanitizer report mutexes are locked while + // we're printing an error report. + // We can lock them only here to avoid self-deadlock in case of + // recursive reports. + asanThreadRegistry().Lock(); + Printf( + "=================================================================\n"); } ~ScopedInErrorReport() { @@ -204,9 +186,6 @@ class ScopedInErrorReport { Report("ABORTING\n"); Die(); } - - CommonSanitizerReportMutex.Unlock(); - atomic_store_relaxed(&reporting_thread_tid_, kUnclaimedTid); } void ReportError(const ErrorDescription &description) { @@ -220,25 +199,13 @@ class ScopedInErrorReport { } private: - void StartReporting() { - CommonSanitizerReportMutex.Lock(); - // Make sure the registry and sanitizer report mutexes are locked while - // we're printing an error report. - // We can lock them only here to avoid self-deadlock in case of - // recursive reports. - asanThreadRegistry().Lock(); - Printf( - "=================================================================\n"); - } - - static atomic_uint32_t reporting_thread_tid_; + ScopedErrorReportLock error_report_lock_; // Error currently being reported. This enables the destructor to interact // with the debugger and point it to an error description. static ErrorDescription current_error_; bool halt_on_error_; }; -atomic_uint32_t ScopedInErrorReport::reporting_thread_tid_ = {kUnclaimedTid}; ErrorDescription ScopedInErrorReport::current_error_; void ReportDeadlySignal(const SignalContext &sig) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.cc b/compiler-rt/lib/sanitizer_common/sanitizer_common.cc index 970b11c00b1..c31f4e3a631 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.cc @@ -348,6 +348,42 @@ static int InstallMallocFreeHooks(void (*malloc_hook)(const void *, uptr), return 0; } +static const u32 kUnclaimedTid = 0xfffffe; +static atomic_uint32_t reporting_thread_tid = {kUnclaimedTid}; + +ScopedErrorReportLock::ScopedErrorReportLock(u32 current_tid) { + for (;;) { + u32 expected_tid = kUnclaimedTid; + if (current_tid == kUnclaimedTid || + atomic_compare_exchange_strong(&reporting_thread_tid, &expected_tid, + current_tid, memory_order_relaxed)) { + // We've claimed reporting_thread_tid_ so proceed. + CommonSanitizerReportMutex.Lock(); + return; + } + + if (expected_tid == current_tid) { + // This is either asynch signal or nested error during error reporting. + // Fail simple to avoid deadlocks in Report(). + + // Can't use Report() here because of potential deadlocks in nested + // signal handlers. + static const char msg[] = + "AddressSanitizer: nested bug in the same thread, aborting.\n"; + CatastrophicErrorWrite(msg, sizeof(msg) - 1); + + internal__exit(common_flags()->exitcode); + } + + internal_sched_yield(); + } +} + +ScopedErrorReportLock::~ScopedErrorReportLock() { + CommonSanitizerReportMutex.Unlock(); + atomic_store_relaxed(&reporting_thread_tid, kUnclaimedTid); +} + } // namespace __sanitizer using namespace __sanitizer; // NOLINT diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h index 75508cbe461..e2e2224d4f7 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -205,8 +205,16 @@ void SetPrintfAndReportCallback(void (*callback)(const char *)); } while (0) // Can be used to prevent mixing error reports from different sanitizers. +// FIXME: Replace with ScopedErrorReportLock and hide. extern StaticSpinMutex CommonSanitizerReportMutex; +// Lock sanitizer error reporting and protects against nested errors. +class ScopedErrorReportLock { + public: + explicit ScopedErrorReportLock(u32 current_tid); + ~ScopedErrorReportLock(); +}; + extern uptr stoptheworld_tracer_pid; extern uptr stoptheworld_tracer_ppid; |