[compiler-rt] r270319 - [tsan] Don't abort when a deadlock detector finds a mutex cycle longer than 10

Kuba Brecka via llvm-commits llvm-commits at lists.llvm.org
Sat May 21 01:31:18 PDT 2016


Author: kuba.brecka
Date: Sat May 21 03:31:13 2016
New Revision: 270319

URL: http://llvm.org/viewvc/llvm-project?rev=270319&view=rev
Log:
[tsan] Don't abort when a deadlock detector finds a mutex cycle longer than 10

In one of the already existing apps that I'm testing TSan on, I really see a mutex path that is longer than 10 (but not by much, something like 11-13 actually). Let's raise this to 20 and weaken the assertion so we don't crash.

Differential Revision: http://reviews.llvm.org/D20427


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

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc?rev=270319&r1=270318&r2=270319&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc Sat May 21 03:31:13 2016
@@ -119,11 +119,16 @@ void DD::MutexBeforeLock(DDCallback *cb,
 
 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++) {

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector_interface.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector_interface.h?rev=270319&r1=270318&r2=270319&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector_interface.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector_interface.h Sat May 21 03:31:13 2016
@@ -51,7 +51,7 @@ struct DDFlags {
 };
 
 struct DDReport {
-  enum { kMaxLoopSize = 8 };
+  enum { kMaxLoopSize = 20 };
   int n;  // number of entries in loop
   struct {
     u64 thr_ctx;   // user thread context

Added: compiler-rt/trunk/test/tsan/mutex_cycle_long.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/mutex_cycle_long.c?rev=270319&view=auto
==============================================================================
--- compiler-rt/trunk/test/tsan/mutex_cycle_long.c (added)
+++ compiler-rt/trunk/test/tsan/mutex_cycle_long.c Sat May 21 03:31:13 2016
@@ -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




More information about the llvm-commits mailing list