[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(<->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 = <->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