[compiler-rt] r207206 - tsan: better report for bad mutex unlocks

Dmitry Vyukov dvyukov at google.com
Fri Apr 25 00:55:11 PDT 2014


Author: dvyukov
Date: Fri Apr 25 02:55:11 2014
New Revision: 207206

URL: http://llvm.org/viewvc/llvm-project?rev=207206&view=rev
Log:
tsan: better report for bad mutex unlocks
+ fixes crashes due to races on symbolizer, see
https://code.google.com/p/thread-sanitizer/issues/detail?id=55


Added:
    compiler-rt/trunk/test/tsan/mutex_bad_unlock.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=207206&r1=207205&r2=207206&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc Fri Apr 25 02:55:11 2014
@@ -76,6 +76,8 @@ static const char *ReportTypeString(Repo
     return "destroy of a locked mutex";
   if (typ == ReportTypeMutexDoubleLock)
     return "double lock of a mutex";
+  if (typ == ReportTypeMutexBadUnlock)
+    return "unlock of an unlocked mutex (or by a wrong thread)";
   if (typ == ReportTypeSignalUnsafe)
     return "signal-unsafe call inside of a signal";
   if (typ == ReportTypeErrnoInSignal)

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=207206&r1=207205&r2=207206&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_report.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_report.h Fri Apr 25 02:55:11 2014
@@ -25,6 +25,7 @@ enum ReportType {
   ReportTypeThreadLeak,
   ReportTypeMutexDestroyLocked,
   ReportTypeMutexDoubleLock,
+  ReportTypeMutexBadUnlock,
   ReportTypeSignalUnsafe,
   ReportTypeErrnoInSignal,
   ReportTypeDeadlock

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=207206&r1=207205&r2=207206&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 02:55:11 2014
@@ -170,18 +170,11 @@ int MutexUnlock(ThreadState *thr, uptr p
   thr->fast_state.IncrementEpoch();
   TraceAddEvent(thr, thr->fast_state, EventTypeUnlock, s->GetId());
   int rec = 0;
-  if (s->recursion == 0) {
-    if (!s->is_broken) {
+  bool report_bad_unlock = false;
+  if (s->recursion == 0 || s->owner_tid != thr->tid) {
+    if (flags()->report_mutex_bugs && !s->is_broken) {
       s->is_broken = true;
-      Printf("ThreadSanitizer WARNING: unlock of unlocked mutex %p\n", addr);
-      PrintCurrentStack(thr, pc);
-    }
-  } else if (s->owner_tid != thr->tid) {
-    if (!s->is_broken) {
-      s->is_broken = true;
-      Printf("ThreadSanitizer WARNING: mutex %p is unlocked by wrong thread\n",
-             addr);
-      PrintCurrentStack(thr, pc);
+      report_bad_unlock = true;
     }
   } else {
     rec = all ? s->recursion : 1;
@@ -199,7 +192,19 @@ int MutexUnlock(ThreadState *thr, uptr p
     Callback cb(thr, pc);
     ctx->dd->MutexBeforeUnlock(&cb, &s->dd, true);
   }
+  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 (flags()->detect_deadlocks) {
     Callback cb(thr, pc);
     ReportDeadlock(thr, pc, ctx->dd->GetReport(&cb));

Added: compiler-rt/trunk/test/tsan/mutex_bad_unlock.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/mutex_bad_unlock.cc?rev=207206&view=auto
==============================================================================
--- compiler-rt/trunk/test/tsan/mutex_bad_unlock.cc (added)
+++ compiler-rt/trunk/test/tsan/mutex_bad_unlock.cc Fri Apr 25 02:55:11 2014
@@ -0,0 +1,18 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s
+extern "C" void AnnotateRWLockReleased(const char *f, int l, void *m, long rw);
+
+int main() {
+  int m = 0;
+  AnnotateRWLockReleased(__FILE__, __LINE__, &m, 1);
+  return 0;
+}
+
+// CHECK: WARNING: ThreadSanitizer: unlock of an unlocked mutex (or by a wrong thread)
+// CHECK:     #0 AnnotateRWLockReleased
+// CHECK:     #1 main
+// CHECK: Location is stack of main thread.
+// CHECK:   Mutex M1 ({{.*}}) created at:
+// CHECK:     #0 AnnotateRWLockReleased
+// CHECK:     #1 main
+// CHECK: SUMMARY: ThreadSanitizer: unlock of an unlocked mutex (or by a wrong thread)
+





More information about the llvm-commits mailing list