[compiler-rt] r207209 - tsan: better reports for "read lock of a write locked mutex"

Dmitry Vyukov dvyukov at google.com
Fri Apr 25 01:58:24 PDT 2014


Author: dvyukov
Date: Fri Apr 25 03:58:23 2014
New Revision: 207209

URL: http://llvm.org/viewvc/llvm-project?rev=207209&view=rev
Log:
tsan: better reports for "read lock of a write locked mutex"


Added:
    compiler-rt/trunk/test/tsan/mutex_bad_read_lock.cc
Modified:
    compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_report.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc?rev=207209&r1=207208&r2=207209&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc Fri Apr 25 03:58:23 2014
@@ -78,6 +78,8 @@ static const char *ReportTypeString(Repo
     return "double lock of a mutex";
   if (typ == ReportTypeMutexBadUnlock)
     return "unlock of an unlocked mutex (or by a wrong thread)";
+  if (typ == ReportTypeMutexBadReadLock)
+    return "read lock of a write locked mutex";
   if (typ == ReportTypeMutexBadReadUnlock)
     return "read unlock of a write locked mutex";
   if (typ == ReportTypeSignalUnsafe)

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_report.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_report.h?rev=207209&r1=207208&r2=207209&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_report.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_report.h Fri Apr 25 03:58:23 2014
@@ -26,6 +26,7 @@ enum ReportType {
   ReportTypeMutexDestroyLocked,
   ReportTypeMutexDoubleLock,
   ReportTypeMutexBadUnlock,
+  ReportTypeMutexBadReadLock,
   ReportTypeMutexBadReadUnlock,
   ReportTypeSignalUnsafe,
   ReportTypeErrnoInSignal,

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc?rev=207209&r1=207208&r2=207209&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc Fri Apr 25 03:58:23 2014
@@ -50,6 +50,18 @@ void DDMutexInit(ThreadState *thr, uptr
   s->dd.ctx = s->GetId();
 }
 
+static void ReportMutexMisuse(ThreadState *thr, uptr pc, ReportType typ,
+    uptr addr, u64 mid) {
+  ThreadRegistryLock l(ctx->thread_registry);
+  ScopedReport rep(typ);
+  rep.AddMutex(mid);
+  StackTrace trace;
+  trace.ObtainCurrent(thr, pc);
+  rep.AddStack(&trace);
+  rep.AddLocation(addr, 1);
+  OutputReport(ctx, rep);
+}
+
 void MutexCreate(ThreadState *thr, uptr pc, uptr addr,
                  bool rw, bool recursive, bool linker_init) {
   DPrintf("#%d: MutexCreate %zx\n", thr->tid, addr);
@@ -146,16 +158,8 @@ void MutexLock(ThreadState *thr, uptr pc
   u64 mid = s->GetId();
   s->mtx.Unlock();
   // Can't touch s after this point.
-  if (report_double_lock) {
-    ThreadRegistryLock l(ctx->thread_registry);
-    ScopedReport rep(ReportTypeMutexDoubleLock);
-    rep.AddMutex(mid);
-    StackTrace trace;
-    trace.ObtainCurrent(thr, pc);
-    rep.AddStack(&trace);
-    rep.AddLocation(addr, 1);
-    OutputReport(ctx, rep);
-  }
+  if (report_double_lock)
+    ReportMutexMisuse(thr, pc, ReportTypeMutexDoubleLock, addr, mid);
   if (flags()->detect_deadlocks) {
     Callback cb(thr, pc);
     ReportDeadlock(thr, pc, ctx->dd->GetReport(&cb));
@@ -195,16 +199,8 @@ int MutexUnlock(ThreadState *thr, uptr p
   u64 mid = s->GetId();
   s->mtx.Unlock();
   // Can't touch s after this point.
-  if (report_bad_unlock) {
-    ThreadRegistryLock l(ctx->thread_registry);
-    ScopedReport rep(ReportTypeMutexBadUnlock);
-    rep.AddMutex(mid);
-    StackTrace trace;
-    trace.ObtainCurrent(thr, pc);
-    rep.AddStack(&trace);
-    rep.AddLocation(addr, 1);
-    OutputReport(ctx, rep);
-  }
+  if (report_bad_unlock)
+    ReportMutexMisuse(thr, pc, ReportTypeMutexBadUnlock, addr, mid);
   if (flags()->detect_deadlocks) {
     Callback cb(thr, pc);
     ReportDeadlock(thr, pc, ctx->dd->GetReport(&cb));
@@ -220,10 +216,12 @@ void MutexReadLock(ThreadState *thr, upt
   SyncVar *s = ctx->synctab.GetOrCreateAndLock(thr, pc, addr, false);
   thr->fast_state.IncrementEpoch();
   TraceAddEvent(thr, thr->fast_state, EventTypeRLock, s->GetId());
+  bool report_bad_lock = false;
   if (s->owner_tid != SyncVar::kInvalidTid) {
-    Printf("ThreadSanitizer WARNING: read lock of a write locked mutex %p\n",
-           addr);
-    PrintCurrentStack(thr, pc);
+    if (flags()->report_mutex_bugs && !s->is_broken) {
+      s->is_broken = true;
+      report_bad_lock = true;
+    }
   }
   AcquireImpl(thr, pc, &s->clock);
   s->last_lock = thr->fast_state.raw();
@@ -234,7 +232,11 @@ void MutexReadLock(ThreadState *thr, upt
       ctx->dd->MutexBeforeLock(&cb, &s->dd, false);
     ctx->dd->MutexAfterLock(&cb, &s->dd, false, trylock);
   }
+  u64 mid = s->GetId();
   s->mtx.ReadUnlock();
+  // Can't touch s after this point.
+  if (report_bad_lock)
+    ReportMutexMisuse(thr, pc, ReportTypeMutexBadReadLock, addr, mid);
   if (flags()->detect_deadlocks) {
     Callback cb(thr, pc);
     ReportDeadlock(thr, pc, ctx->dd->GetReport(&cb));
@@ -265,16 +267,8 @@ void MutexReadUnlock(ThreadState *thr, u
   s->mtx.Unlock();
   // Can't touch s after this point.
   thr->mset.Del(mid, false);
-  if (report_bad_unlock) {
-    ThreadRegistryLock l(ctx->thread_registry);
-    ScopedReport rep(ReportTypeMutexBadReadUnlock);
-    rep.AddMutex(mid);
-    StackTrace trace;
-    trace.ObtainCurrent(thr, pc);
-    rep.AddStack(&trace);
-    rep.AddLocation(addr, 1);
-    OutputReport(ctx, rep);
-  }
+  if (report_bad_unlock)
+    ReportMutexMisuse(thr, pc, ReportTypeMutexBadReadUnlock, addr, mid);
   if (flags()->detect_deadlocks) {
     Callback cb(thr, pc);
     ReportDeadlock(thr, pc, ctx->dd->GetReport(&cb));

Added: compiler-rt/trunk/test/tsan/mutex_bad_read_lock.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/mutex_bad_read_lock.cc?rev=207209&view=auto
==============================================================================
--- compiler-rt/trunk/test/tsan/mutex_bad_read_lock.cc (added)
+++ compiler-rt/trunk/test/tsan/mutex_bad_read_lock.cc Fri Apr 25 03:58:23 2014
@@ -0,0 +1,19 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s
+extern "C" void AnnotateRWLockAcquired(const char *f, int l, void *m, long rw);
+
+int main() {
+  int m = 0;
+  AnnotateRWLockAcquired(__FILE__, __LINE__, &m, 1);
+  AnnotateRWLockAcquired(__FILE__, __LINE__, &m, 0);
+  return 0;
+}
+
+// CHECK: WARNING: ThreadSanitizer: read lock of a write locked mutex
+// CHECK:     #0 AnnotateRWLockAcquired
+// CHECK:     #1 main
+// CHECK: Location is stack of main thread.
+// CHECK:   Mutex {{.*}}) created at:
+// CHECK:     #0 AnnotateRWLockAcquired
+// CHECK:     #1 main
+// CHECK: SUMMARY: ThreadSanitizer: read lock of a write locked mutex
+





More information about the llvm-commits mailing list