[compiler-rt] r204454 - [sanitizer] more human-readable deadlock reports

Kostya Serebryany kcc at google.com
Fri Mar 21 04:37:43 PDT 2014


Author: kcc
Date: Fri Mar 21 06:37:43 2014
New Revision: 204454

URL: http://llvm.org/viewvc/llvm-project?rev=204454&view=rev
Log:
[sanitizer] more human-readable deadlock reports

Modified:
    compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc
    compiler-rt/trunk/test/tsan/deadlock_detector_stress_test.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=204454&r1=204453&r2=204454&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc Fri Mar 21 06:37:43 2014
@@ -162,6 +162,12 @@ static void PrintMutexShort(const Report
   Printf("%sM%zd%s%s", d.Mutex(), rm->id, d.EndMutex(), after);
 }
 
+static void PrintMutexShortWitAddress(const ReportMutex *rm,
+                                      const char *after) {
+  Decorator d;
+  Printf("%sM%zd (%p)%s%s", d.Mutex(), rm->id, rm->addr, d.EndMutex(), after);
+}
+
 static void PrintMutex(const ReportMutex *rm) {
   Decorator d;
   if (rm->destroyed) {
@@ -231,18 +237,30 @@ void PrintReport(const ReportDesc *rep)
   Printf("%s", d.EndWarning());
 
   if (rep->typ == ReportTypeDeadlock) {
-    Printf("  Path: ");
-    CHECK_GT(rep->mutexes.Size(), 0U);
-    CHECK_EQ(rep->mutexes.Size() * 2, rep->stacks.Size());
+    Printf("  Cycle in lock order graph: ");
     for (uptr i = 0; i < rep->mutexes.Size(); i++)
-      PrintMutexShort(rep->mutexes[i], " => ");
+      PrintMutexShortWitAddress(rep->mutexes[i], " => ");
     PrintMutexShort(rep->mutexes[0], "\n\n");
+    CHECK_GT(rep->mutexes.Size(), 0U);
+    CHECK_EQ(rep->mutexes.Size() * (flags()->second_deadlock_stack ? 2 : 1),
+             rep->stacks.Size());
     for (uptr i = 0; i < rep->mutexes.Size(); i++) {
-      Printf("  Edge: ");
-      PrintMutexShort(rep->mutexes[i], " => ");
-      PrintMutexShort(rep->mutexes[(i+1) % rep->mutexes.Size()], "\n");
-      PrintStack(rep->stacks[2*i]);
-      PrintStack(rep->stacks[2*i+1]);
+      Printf("  Mutex ");
+      PrintMutexShort(rep->mutexes[(i + 1) % rep->mutexes.Size()],
+                      " acquired here while holding mutex ");
+      PrintMutexShort(rep->mutexes[i], ":\n");
+      if (flags()->second_deadlock_stack) {
+        PrintStack(rep->stacks[2*i]);
+        Printf("  Mutex ");
+        PrintMutexShort(rep->mutexes[i],
+                        " previously acquired by the same thread here:\n");
+        PrintStack(rep->stacks[2*i+1]);
+      } else {
+        PrintStack(rep->stacks[i]);
+        if (i == 0)
+          Printf("    Hint: use TSAN_OPTIONS=second_deadlock_stack=1 "
+                 "to get more informative warning message\n\n");
+      }
     }
   } else {
     for (uptr i = 0; i < rep->stacks.Size(); i++) {
@@ -261,8 +279,10 @@ void PrintReport(const ReportDesc *rep)
   for (uptr i = 0; i < rep->locs.Size(); i++)
     PrintLocation(rep->locs[i]);
 
-  for (uptr i = 0; i < rep->mutexes.Size(); i++)
-    PrintMutex(rep->mutexes[i]);
+  if (rep->typ != ReportTypeDeadlock) {
+    for (uptr i = 0; i < rep->mutexes.Size(); i++)
+      PrintMutex(rep->mutexes[i]);
+  }
 
   for (uptr i = 0; i < rep->threads.Size(); i++)
     PrintThread(rep->threads[i]);

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=204454&r1=204453&r2=204454&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc Fri Mar 21 06:37:43 2014
@@ -417,7 +417,7 @@ void ReportDeadlock(ThreadState *thr, up
   uptr dummy_pc = 0x42;
   for (int i = 0; i < r->n; i++) {
     uptr size;
-    for (int j = 0; j < 2; j++) {
+    for (int j = 0; j < (flags()->second_deadlock_stack ? 2 : 1); j++) {
       u32 stk = r->loop[i].stk[j];
       if (stk) {
         const uptr *trace = StackDepotGet(stk, &size);

Modified: compiler-rt/trunk/test/tsan/deadlock_detector_stress_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/deadlock_detector_stress_test.cc?rev=204454&r1=204453&r2=204454&view=diff
==============================================================================
--- compiler-rt/trunk/test/tsan/deadlock_detector_stress_test.cc (original)
+++ compiler-rt/trunk/test/tsan/deadlock_detector_stress_test.cc Fri Mar 21 06:37:43 2014
@@ -152,17 +152,18 @@ class LockTest {
     Lock_0_1();
     Lock_1_0();
     // CHECK: WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock)
-    // CHECK: Path: [[M1:M[0-9]+]] => [[M2:M[0-9]+]] => [[M1]]
-    // CHECK: Edge: [[M1]] => [[M2]]
+    // CHECK: Cycle in lock order graph: [[M1:M[0-9]+]] ([[A1]]) => [[M2:M[0-9]+]] ([[A2]]) => [[M1]]
+    // CHECK: Mutex [[M2]] acquired here while holding mutex [[M1]]
     // CHECK:   #0 pthread_
+    // CHECK-SECOND:   Mutex [[M1]] previously acquired by the same thread here:
     // CHECK-SECOND:   #0 pthread_
+    // CHECK-NOT-SECOND:   second_deadlock_stack=1 to get more informative warning message
     // CHECK-NOT-SECOND-NOT:   #0 pthread_
-    // CHECK: Edge: [[M2]] => [[M1]]
+    // CHECK: Mutex [[M1]] acquired here while holding mutex [[M2]]
     // CHECK:   #0 pthread_
+    // CHECK-SECOND:   Mutex [[M2]] previously acquired by the same thread here:
     // CHECK-SECOND:   #0 pthread_
     // CHECK-NOT-SECOND-NOT:   #0 pthread_
-    // CHECK: Mutex [[M1]] ([[A1]]) created at:
-    // CHECK: Mutex [[M2]] ([[A2]]) created at:
     // CHECK-NOT: WARNING: ThreadSanitizer:
   }
 
@@ -178,10 +179,7 @@ class LockTest {
     Lock2(1, 2);
     Lock2(2, 0);
     // CHECK: WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock)
-    // CHECK: Path: [[M1:M[0-9]+]] => [[M2:M[0-9]+]] => [[M3:M[0-9]+]] => [[M1]]
-    // CHECK: Mutex [[M1]] ([[A1]]) created at:
-    // CHECK: Mutex [[M2]] ([[A2]]) created at:
-    // CHECK: Mutex [[M3]] ([[A3]]) created at:
+    // CHECK: Cycle in lock order graph: [[M1:M[0-9]+]] ([[A1]]) => [[M2:M[0-9]+]] ([[A2]]) => [[M3:M[0-9]+]] ([[A3]]) => [[M1]]
     // CHECK-NOT: WARNING: ThreadSanitizer:
   }
 
@@ -426,12 +424,16 @@ class LockTest {
     fprintf(stderr, "Starting Test16: detailed output test with two locks\n");
     // CHECK: Starting Test16
     // CHECK: WARNING: ThreadSanitizer: lock-order-inversion
+    // CHECK: acquired here while holding mutex
     // CHECK: LockTest::Acquire1
     // CHECK-NEXT: LockTest::Acquire_0_then_1
+    // CHECK-SECOND: previously acquired by the same thread here
     // CHECK-SECOND: LockTest::Acquire0
     // CHECK-SECOND-NEXT: LockTest::Acquire_0_then_1
+    // CHECK: acquired here while holding mutex
     // CHECK: LockTest::Acquire0
     // CHECK-NEXT: LockTest::Acquire_1_then_0
+    // CHECK-SECOND: previously acquired by the same thread here
     // CHECK-SECOND: LockTest::Acquire1
     // CHECK-SECOND-NEXT: LockTest::Acquire_1_then_0
     Init(5);





More information about the llvm-commits mailing list