[compiler-rt] r314008 - [sanitizer] Move report locking code from asan into common

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 22 11:32:05 PDT 2017


Author: vitalybuka
Date: Fri Sep 22 11:32:05 2017
New Revision: 314008

URL: http://llvm.org/viewvc/llvm-project?rev=314008&view=rev
Log:
[sanitizer] Move report locking code from asan into common

Modified:
    compiler-rt/trunk/lib/asan/asan_report.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h

Modified: compiler-rt/trunk/lib/asan/asan_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_report.cc?rev=314008&r1=314007&r2=314008&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_report.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_report.cc Fri Sep 22 11:32:05 2017
@@ -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) {

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc?rev=314008&r1=314007&r2=314008&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc Fri Sep 22 11:32:05 2017
@@ -348,6 +348,42 @@ static int InstallMallocFreeHooks(void (
   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

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h?rev=314008&r1=314007&r2=314008&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h Fri Sep 22 11:32:05 2017
@@ -205,8 +205,16 @@ void SetPrintfAndReportCallback(void (*c
   } 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;
 




More information about the llvm-commits mailing list