diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -237,9 +237,11 @@ // Lock sanitizer error reporting and protects against nested errors. class ScopedErrorReportLock { public: - ScopedErrorReportLock(); - ~ScopedErrorReportLock(); + ScopedErrorReportLock() { Lock(); } + ~ScopedErrorReportLock() { Unlock(); } + static void Lock(); + static void Unlock(); static void CheckLocked(); }; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp @@ -253,7 +253,7 @@ static atomic_uintptr_t reporting_thread = {0}; static StaticSpinMutex CommonSanitizerReportMutex; -ScopedErrorReportLock::ScopedErrorReportLock() { +void ScopedErrorReportLock::Lock() ACQUIRE(CommonSanitizerReportMutex) { uptr current = GetThreadSelf(); for (;;) { uptr expected = 0; @@ -282,7 +282,7 @@ } } -ScopedErrorReportLock::~ScopedErrorReportLock() { +void ScopedErrorReportLock::Unlock() RELEASE(CommonSanitizerReportMutex) { CommonSanitizerReportMutex.Unlock(); atomic_store_relaxed(&reporting_thread, 0); } diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp @@ -534,6 +534,7 @@ void ForkBefore(ThreadState *thr, uptr pc) NO_THREAD_SAFETY_ANALYSIS { ctx->thread_registry->Lock(); ctx->report_mtx.Lock(); + ScopedErrorReportLock::Lock(); // Suppress all reports in the pthread_atfork callbacks. // Reports will deadlock on the report_mtx. // We could ignore sync operations as well, @@ -548,6 +549,7 @@ void ForkParentAfter(ThreadState *thr, uptr pc) NO_THREAD_SAFETY_ANALYSIS { thr->suppress_reports--; // Enabled in ForkBefore. thr->ignore_interceptors--; + ScopedErrorReportLock::Unlock(); ctx->report_mtx.Unlock(); ctx->thread_registry->Unlock(); } @@ -555,6 +557,7 @@ void ForkChildAfter(ThreadState *thr, uptr pc) NO_THREAD_SAFETY_ANALYSIS { thr->suppress_reports--; // Enabled in ForkBefore. thr->ignore_interceptors--; + ScopedErrorReportLock::Unlock(); ctx->report_mtx.Unlock(); ctx->thread_registry->Unlock();