<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Mar 21, 2014 at 3:37 PM, Kostya Serebryany <span dir="ltr"><<a href="mailto:kcc@google.com" target="_blank">kcc@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: kcc<br>
Date: Fri Mar 21 06:37:43 2014<br>
New Revision: 204454<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=204454&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=204454&view=rev</a><br>
Log:<br>
[sanitizer] more human-readable deadlock reports<br>
<br>
Modified:<br>
    compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc<br>
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc<br>
    compiler-rt/trunk/test/tsan/deadlock_detector_stress_test.cc<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc?rev=204454&r1=204453&r2=204454&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc?rev=204454&r1=204453&r2=204454&view=diff</a><br>

==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc Fri Mar 21 06:37:43 2014<br>
@@ -162,6 +162,12 @@ static void PrintMutexShort(const Report<br>
   Printf("%sM%zd%s%s", d.Mutex(), rm->id, d.EndMutex(), after);<br>
 }<br>
<br>
+static void PrintMutexShortWitAddress(const ReportMutex *rm,<br></blockquote><div><br></div><div>Typo in function name?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+                                      const char *after) {<br>
+  Decorator d;<br>
+  Printf("%sM%zd (%p)%s%s", d.Mutex(), rm->id, rm->addr, d.EndMutex(), after);<br>
+}<br>
+<br>
 static void PrintMutex(const ReportMutex *rm) {<br>
   Decorator d;<br>
   if (rm->destroyed) {<br>
@@ -231,18 +237,30 @@ void PrintReport(const ReportDesc *rep)<br>
   Printf("%s", d.EndWarning());<br>
<br>
   if (rep->typ == ReportTypeDeadlock) {<br>
-    Printf("  Path: ");<br>
-    CHECK_GT(rep->mutexes.Size(), 0U);<br>
-    CHECK_EQ(rep->mutexes.Size() * 2, rep->stacks.Size());<br>
+    Printf("  Cycle in lock order graph: ");<br>
     for (uptr i = 0; i < rep->mutexes.Size(); i++)<br>
-      PrintMutexShort(rep->mutexes[i], " => ");<br>
+      PrintMutexShortWitAddress(rep->mutexes[i], " => ");<br>
     PrintMutexShort(rep->mutexes[0], "\n\n");<br>
+    CHECK_GT(rep->mutexes.Size(), 0U);<br>
+    CHECK_EQ(rep->mutexes.Size() * (flags()->second_deadlock_stack ? 2 : 1),<br>
+             rep->stacks.Size());<br>
     for (uptr i = 0; i < rep->mutexes.Size(); i++) {<br>
-      Printf("  Edge: ");<br>
-      PrintMutexShort(rep->mutexes[i], " => ");<br>
-      PrintMutexShort(rep->mutexes[(i+1) % rep->mutexes.Size()], "\n");<br>
-      PrintStack(rep->stacks[2*i]);<br>
-      PrintStack(rep->stacks[2*i+1]);<br>
+      Printf("  Mutex ");<br>
+      PrintMutexShort(rep->mutexes[(i + 1) % rep->mutexes.Size()],<br>
+                      " acquired here while holding mutex ");<br>
+      PrintMutexShort(rep->mutexes[i], ":\n");<br>
+      if (flags()->second_deadlock_stack) {<br>
+        PrintStack(rep->stacks[2*i]);<br>
+        Printf("  Mutex ");<br>
+        PrintMutexShort(rep->mutexes[i],<br>
+                        " previously acquired by the same thread here:\n");<br>
+        PrintStack(rep->stacks[2*i+1]);<br>
+      } else {<br>
+        PrintStack(rep->stacks[i]);<br>
+        if (i == 0)<br>
+          Printf("    Hint: use TSAN_OPTIONS=second_deadlock_stack=1 "<br>
+                 "to get more informative warning message\n\n");<br>
+      }<br>
     }<br>
   } else {<br>
     for (uptr i = 0; i < rep->stacks.Size(); i++) {<br>
@@ -261,8 +279,10 @@ void PrintReport(const ReportDesc *rep)<br>
   for (uptr i = 0; i < rep->locs.Size(); i++)<br>
     PrintLocation(rep->locs[i]);<br>
<br>
-  for (uptr i = 0; i < rep->mutexes.Size(); i++)<br>
-    PrintMutex(rep->mutexes[i]);<br>
+  if (rep->typ != ReportTypeDeadlock) {<br>
+    for (uptr i = 0; i < rep->mutexes.Size(); i++)<br>
+      PrintMutex(rep->mutexes[i]);<br>
+  }<br>
<br>
   for (uptr i = 0; i < rep->threads.Size(); i++)<br>
     PrintThread(rep->threads[i]);<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc?rev=204454&r1=204453&r2=204454&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc?rev=204454&r1=204453&r2=204454&view=diff</a><br>

==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc Fri Mar 21 06:37:43 2014<br>
@@ -417,7 +417,7 @@ void ReportDeadlock(ThreadState *thr, up<br>
   uptr dummy_pc = 0x42;<br>
   for (int i = 0; i < r->n; i++) {<br>
     uptr size;<br>
-    for (int j = 0; j < 2; j++) {<br>
+    for (int j = 0; j < (flags()->second_deadlock_stack ? 2 : 1); j++) {<br>
       u32 stk = r->loop[i].stk[j];<br>
       if (stk) {<br>
         const uptr *trace = StackDepotGet(stk, &size);<br>
<br>
Modified: compiler-rt/trunk/test/tsan/deadlock_detector_stress_test.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/deadlock_detector_stress_test.cc?rev=204454&r1=204453&r2=204454&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/deadlock_detector_stress_test.cc?rev=204454&r1=204453&r2=204454&view=diff</a><br>

==============================================================================<br>
--- compiler-rt/trunk/test/tsan/deadlock_detector_stress_test.cc (original)<br>
+++ compiler-rt/trunk/test/tsan/deadlock_detector_stress_test.cc Fri Mar 21 06:37:43 2014<br>
@@ -152,17 +152,18 @@ class LockTest {<br>
     Lock_0_1();<br>
     Lock_1_0();<br>
     // CHECK: WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock)<br>
-    // CHECK: Path: [[M1:M[0-9]+]] => [[M2:M[0-9]+]] => [[M1]]<br>
-    // CHECK: Edge: [[M1]] => [[M2]]<br>
+    // CHECK: Cycle in lock order graph: [[M1:M[0-9]+]] ([[A1]]) => [[M2:M[0-9]+]] ([[A2]]) => [[M1]]<br>
+    // CHECK: Mutex [[M2]] acquired here while holding mutex [[M1]]<br>
     // CHECK:   #0 pthread_<br>
+    // CHECK-SECOND:   Mutex [[M1]] previously acquired by the same thread here:<br>
     // CHECK-SECOND:   #0 pthread_<br>
+    // CHECK-NOT-SECOND:   second_deadlock_stack=1 to get more informative warning message<br>
     // CHECK-NOT-SECOND-NOT:   #0 pthread_<br>
-    // CHECK: Edge: [[M2]] => [[M1]]<br>
+    // CHECK: Mutex [[M1]] acquired here while holding mutex [[M2]]<br>
     // CHECK:   #0 pthread_<br>
+    // CHECK-SECOND:   Mutex [[M2]] previously acquired by the same thread here:<br>
     // CHECK-SECOND:   #0 pthread_<br>
     // CHECK-NOT-SECOND-NOT:   #0 pthread_<br>
-    // CHECK: Mutex [[M1]] ([[A1]]) created at:<br>
-    // CHECK: Mutex [[M2]] ([[A2]]) created at:<br>
     // CHECK-NOT: WARNING: ThreadSanitizer:<br>
   }<br>
<br>
@@ -178,10 +179,7 @@ class LockTest {<br>
     Lock2(1, 2);<br>
     Lock2(2, 0);<br>
     // CHECK: WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock)<br>
-    // CHECK: Path: [[M1:M[0-9]+]] => [[M2:M[0-9]+]] => [[M3:M[0-9]+]] => [[M1]]<br>
-    // CHECK: Mutex [[M1]] ([[A1]]) created at:<br>
-    // CHECK: Mutex [[M2]] ([[A2]]) created at:<br>
-    // CHECK: Mutex [[M3]] ([[A3]]) created at:<br>
+    // CHECK: Cycle in lock order graph: [[M1:M[0-9]+]] ([[A1]]) => [[M2:M[0-9]+]] ([[A2]]) => [[M3:M[0-9]+]] ([[A3]]) => [[M1]]<br>
     // CHECK-NOT: WARNING: ThreadSanitizer:<br>
   }<br>
<br>
@@ -426,12 +424,16 @@ class LockTest {<br>
     fprintf(stderr, "Starting Test16: detailed output test with two locks\n");<br>
     // CHECK: Starting Test16<br>
     // CHECK: WARNING: ThreadSanitizer: lock-order-inversion<br>
+    // CHECK: acquired here while holding mutex<br>
     // CHECK: LockTest::Acquire1<br>
     // CHECK-NEXT: LockTest::Acquire_0_then_1<br>
+    // CHECK-SECOND: previously acquired by the same thread here<br>
     // CHECK-SECOND: LockTest::Acquire0<br>
     // CHECK-SECOND-NEXT: LockTest::Acquire_0_then_1<br>
+    // CHECK: acquired here while holding mutex<br>
     // CHECK: LockTest::Acquire0<br>
     // CHECK-NEXT: LockTest::Acquire_1_then_0<br>
+    // CHECK-SECOND: previously acquired by the same thread here<br>
     // CHECK-SECOND: LockTest::Acquire1<br>
     // CHECK-SECOND-NEXT: LockTest::Acquire_1_then_0<br>
     Init(5);<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div>Alexey Samsonov, MSK</div>
</div></div>