tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

sanitizer_deadlock_suppression_clang_22.patch (3311B)


      1 Add support for suppressing corner cases of recursive locking that TSAN
      2 normally doesn't allow.
      3 
      4 diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector1.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector1.cpp
      5 index ccb7065b07ae..58cfc5e1a1fb 100644
      6 --- a/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector1.cpp
      7 +++ b/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector1.cpp
      8 @@ -15,6 +15,7 @@
      9 #include "sanitizer_allocator_internal.h"
     10 #include "sanitizer_placement_new.h"
     11 #include "sanitizer_mutex.h"
     12 +#include "sanitizer_stackdepot.h"
     13 
     14 #if SANITIZER_DEADLOCK_DETECTOR_VERSION == 1
     15 
     16 @@ -162,8 +163,19 @@ void DD::MutexAfterLock(DDCallback *cb, DDMutex *m, bool wlock, bool trylock) {
     17 
     18   SpinMutexLock lk(&mtx);
     19   MutexEnsureID(lt, m);
     20 -  if (wlock)  // Only a recursive rlock may be held.
     21 -    CHECK(!dd.isHeld(&lt->dd, m->id));
     22 +  // Only a recursive rlock may be held.
     23 +  if (wlock && dd.isHeld(&lt->dd, m->id)) {
     24 +    // Get stack traces from where the lock is already held.
     25 +    u32 held_stk = dd.findLockContext(&lt->dd, m->id);
     26 +    if (!cb->IsDeadlockSuppressed(held_stk)) {
     27 +      stk = stk ? stk : cb->Unwind();
     28 +      if (!cb->IsDeadlockSuppressed(stk)) {
     29 +        // We could avoid calling this twice, by storing the result above, but
     30 +        // we do want the error message to be unchanged.
     31 +        CHECK(!dd.isHeld(&lt->dd, m->id));
     32 +      }
     33 +    }
     34 +  }
     35   if (!trylock)
     36     dd.addEdges(&lt->dd, m->id, stk ? stk : cb->Unwind(), cb->UniqueTid());
     37   dd.onLockAfter(&lt->dd, m->id, stk);
     38 diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector_interface.h b/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector_interface.h
     39 index 7f461c98bade..252e62e05622 100644
     40 --- a/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector_interface.h
     41 +++ b/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector_interface.h
     42 @@ -66,6 +66,7 @@ struct DDCallback {
     43 
     44   virtual u32 Unwind() { return 0; }
     45   virtual int UniqueTid() { return 0; }
     46 +  virtual bool IsDeadlockSuppressed(u32 stk) { return false; }
     47 
     48  protected:
     49   ~DDCallback() {}
     50 diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp
     51 index 30f5e964939d..2b254e323330 100644
     52 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp
     53 +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp
     54 @@ -15,9 +15,11 @@
     55 #include <sanitizer_common/sanitizer_stackdepot.h>
     56 
     57 #include "tsan_flags.h"
     58 +#include "tsan_mman.h"
     59 #include "tsan_platform.h"
     60 #include "tsan_report.h"
     61 #include "tsan_rtl.h"
     62 +#include "tsan_suppressions.h"
     63 #include "tsan_symbolize.h"
     64 #include "tsan_sync.h"
     65 
     66 @@ -40,6 +42,21 @@ struct Callback final : public DDCallback {
     67 
     68   StackID Unwind() override { return CurrentStackId(thr, pc); }
     69   int UniqueTid() override { return thr->tid; }
     70 +
     71 +  bool IsDeadlockSuppressed(u32 stk) override {
     72 +    bool result = false;
     73 +    if (stk) {
     74 +      Suppression *supp = nullptr;
     75 +      ReportStack *rs = SymbolizeStackId(stk);
     76 +      rs->suppressable = true;
     77 +      result = IsSuppressed(ReportTypeDeadlock, rs, &supp);
     78 +      if (rs->frames) {
     79 +        rs->frames->ClearAll();
     80 +      }
     81 +      DestroyAndFree(rs);
     82 +    }
     83 +    return result;
     84 +  }
     85 };
     86 
     87 void DDMutexInit(ThreadState *thr, uptr pc, SyncVar *s) {