[compiler-rt] ab02680 - tsan: fix a bug in trace part switching

Dmitry Vyukov via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 14 08:49:05 PDT 2022


Author: Dmitry Vyukov
Date: 2022-07-14T17:49:00+02:00
New Revision: ab02680b5aee81fbcf564e30891e8e2089d513e1

URL: https://github.com/llvm/llvm-project/commit/ab02680b5aee81fbcf564e30891e8e2089d513e1
DIFF: https://github.com/llvm/llvm-project/commit/ab02680b5aee81fbcf564e30891e8e2089d513e1.diff

LOG: tsan: fix a bug in trace part switching

Callers of TraceSwitchPart expect that TraceAcquire will always succeed
after the call. It's possible that TryTraceFunc/TraceMutexLock in TraceSwitchPart
that restore the current stack/mutexset filled the trace part exactly up
to the TracePart::kAlignment gap and the next TraceAcquire won't succeed.
Skip the alignment gap after writing initial stack/mutexset to avoid that.

Reviewed By: melver

Differential Revision: https://reviews.llvm.org/D129777

Added: 
    

Modified: 
    compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
    compiler-rt/lib/tsan/tests/unit/tsan_trace_test.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
index 607f373871b44..ef073ca32e573 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
@@ -951,6 +951,15 @@ void TraceSwitchPartImpl(ThreadState* thr) {
       TraceMutexLock(thr, d.write ? EventType::kLock : EventType::kRLock, 0,
                      d.addr, d.stack_id);
   }
+  // Callers of TraceSwitchPart expect that TraceAcquire will always succeed
+  // after the call. It's possible that TryTraceFunc/TraceMutexLock above
+  // filled the trace part exactly up to the TracePart::kAlignment gap
+  // and the next TraceAcquire won't succeed. Skip the gap to avoid that.
+  EventFunc *ev;
+  if (!TraceAcquire(thr, &ev)) {
+    CHECK(TraceSkipGap(thr));
+    CHECK(TraceAcquire(thr, &ev));
+  }
   {
     Lock lock(&ctx->slot_mtx);
     // There is a small chance that the slot may be not queued at this point.

diff  --git a/compiler-rt/lib/tsan/tests/unit/tsan_trace_test.cpp b/compiler-rt/lib/tsan/tests/unit/tsan_trace_test.cpp
index 9f006ab09833e..0d354db548c48 100644
--- a/compiler-rt/lib/tsan/tests/unit/tsan_trace_test.cpp
+++ b/compiler-rt/lib/tsan/tests/unit/tsan_trace_test.cpp
@@ -243,6 +243,18 @@ TRACE_TEST(Trace, MultiPart) {
   CHECK_EQ(mset.Get(1).count, 1);
 }
 
+TRACE_TEST(Trace, DeepSwitch) {
+  ThreadArray<1> thr;
+  for (int i = 0; i < 2000; i++) {
+    FuncEntry(thr, 0x1000);
+    const uptr kEvents = sizeof(TracePart) / sizeof(Event);
+    for (uptr i = 0; i < kEvents; i++) {
+      TraceMutexLock(thr, EventType::kLock, 0x4000, 0x5000, 0x6000);
+      TraceMutexUnlock(thr, 0x5000);
+    }
+  }
+}
+
 void CheckTraceState(uptr count, uptr finished, uptr excess, uptr recycle) {
   Lock l(&ctx->slot_mtx);
   Printf("CheckTraceState(%zu/%zu, %zu/%zu, %zu/%zu, %zu/%zu)\n",


        


More information about the llvm-commits mailing list