[PATCH] D20427: [tsan] Don't abort when a deadlock detector finds a mutex cycle longer than 10

Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat May 21 01:37:59 PDT 2016


This revision was automatically updated to reflect the committed changes.
Closed by commit rL270319: [tsan] Don't abort when a deadlock detector finds a mutex cycle longer than 10 (authored by kuba.brecka).

Changed prior to commit:
  http://reviews.llvm.org/D20427?vs=57916&id=58033#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D20427

Files:
  compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc
  compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector_interface.h
  compiler-rt/trunk/test/tsan/mutex_cycle_long.c

Index: compiler-rt/trunk/test/tsan/mutex_cycle_long.c
===================================================================
--- compiler-rt/trunk/test/tsan/mutex_cycle_long.c
+++ compiler-rt/trunk/test/tsan/mutex_cycle_long.c
@@ -0,0 +1,42 @@
+// RUN: %clangxx_tsan %s -o %t
+// RUN: not %run %t 5 2>&1 | FileCheck %s
+// RUN: not %run %t 10 2>&1 | FileCheck %s
+// RUN: not %run %t 15 2>&1 | FileCheck %s
+// RUN: not %run %t 20 2>&1 | FileCheck %s
+// RUN: %run %t 30 2>&1 | FileCheck %s --check-prefix=CHECK-TOO-LONG-CYCLE
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char *argv[]) {
+  int num_mutexes = 5;
+  if (argc > 1) num_mutexes = atoi(argv[1]);
+
+  pthread_mutex_t m[num_mutexes];
+  for (int i = 0; i < num_mutexes; ++i)
+    pthread_mutex_init(&m[i], NULL);
+  
+  for (int i = 0; i < num_mutexes - 1; ++i) {
+    pthread_mutex_lock(&m[i]);
+    pthread_mutex_lock(&m[i + 1]);
+
+    pthread_mutex_unlock(&m[i]);
+    pthread_mutex_unlock(&m[i + 1]);
+  }
+
+  pthread_mutex_lock(&m[num_mutexes - 1]);
+  pthread_mutex_lock(&m[0]);
+
+  pthread_mutex_unlock(&m[num_mutexes - 1]);
+  pthread_mutex_unlock(&m[0]);
+
+  for (int i = 0; i < num_mutexes; ++i)
+    pthread_mutex_destroy(&m[i]);
+
+  fprintf(stderr, "PASS\n");
+}
+
+// CHECK: ThreadSanitizer: lock-order-inversion (potential deadlock)
+// CHECK-TOO-LONG-CYCLE: WARNING: too long mutex cycle found
+// CHECK: PASS
Index: compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc
===================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc
@@ -119,11 +119,16 @@
 
 void DD::ReportDeadlock(DDCallback *cb, DDMutex *m) {
   DDLogicalThread *lt = cb->lt;
-  uptr path[10];
+  uptr path[20];
   uptr len = dd.findPathToLock(&lt->dd, m->id, path, ARRAY_SIZE(path));
-  CHECK_GT(len, 0U);  // Hm.. cycle of 10 locks? I'd like to see that.
+  if (len == 0U) {
+    // A cycle of 20+ locks? Well, that's a bit odd...
+    Printf("WARNING: too long mutex cycle found\n");
+    return;
+  }
   CHECK_EQ(m->id, path[0]);
   lt->report_pending = true;
+  len = Min<uptr>(len, DDReport::kMaxLoopSize);
   DDReport *rep = &lt->rep;
   rep->n = len;
   for (uptr i = 0; i < len; i++) {
Index: compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector_interface.h
===================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector_interface.h
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector_interface.h
@@ -51,7 +51,7 @@
 };
 
 struct DDReport {
-  enum { kMaxLoopSize = 8 };
+  enum { kMaxLoopSize = 20 };
   int n;  // number of entries in loop
   struct {
     u64 thr_ctx;   // user thread context


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D20427.58033.patch
Type: text/x-patch
Size: 2876 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160521/7a0e005b/attachment.bin>


More information about the llvm-commits mailing list