summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-04-27 08:59:35 +0000
committerDmitry Vyukov <dvyukov@google.com>2018-04-27 08:59:35 +0000
commit21dc68fe7b4cd06b2ac194a66467352ddc2c4ecb (patch)
treeec16602c6cc40f9d020809100abf002d444fc1cc
parent1956a48d273dca31d379b3b032bf772040d3c93d (diff)
downloadbcm5719-llvm-21dc68fe7b4cd06b2ac194a66467352ddc2c4ecb.tar.gz
bcm5719-llvm-21dc68fe7b4cd06b2ac194a66467352ddc2c4ecb.zip
tsan: improve "destroy of a locked mutex" reports
1. Allow to suppress by current stack. We generally allow to suppress by all main stacks. Current is probably the stack one wants to use to suppress such reports. 2. Fix last lock stack restoration. We trimmed shadow value by storing it in u32. This magically worked for the test that provoked the report on the main thread. But this breaks for locks in any other threads. llvm-svn: 331023
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc4
-rw-r--r--compiler-rt/test/tsan/mutex_destroy_locked2.cc29
-rw-r--r--compiler-rt/test/tsan/suppressions_mutex.cc19
-rw-r--r--compiler-rt/test/tsan/suppressions_mutex.cc.supp2
4 files changed, 52 insertions, 2 deletions
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc
index 152b965ad53..f0f4fbe7c7c 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc
@@ -104,7 +104,7 @@ void MutexDestroy(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
unlock_locked = true;
}
u64 mid = s->GetId();
- u32 last_lock = s->last_lock;
+ u64 last_lock = s->last_lock;
if (!unlock_locked)
s->Reset(thr->proc()); // must not reset it before the report is printed
s->mtx.Unlock();
@@ -114,7 +114,7 @@ void MutexDestroy(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
rep.AddMutex(mid);
VarSizeStackTrace trace;
ObtainCurrentStack(thr, pc, &trace);
- rep.AddStack(trace);
+ rep.AddStack(trace, true);
FastState last(last_lock);
RestoreStack(last.tid(), last.epoch(), &trace, 0);
rep.AddStack(trace, true);
diff --git a/compiler-rt/test/tsan/mutex_destroy_locked2.cc b/compiler-rt/test/tsan/mutex_destroy_locked2.cc
new file mode 100644
index 00000000000..e29c96138a8
--- /dev/null
+++ b/compiler-rt/test/tsan/mutex_destroy_locked2.cc
@@ -0,0 +1,29 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+#include <pthread.h>
+#include <unistd.h>
+
+void *thread(void *arg) {
+ pthread_mutex_t m;
+ pthread_mutex_init(&m, 0);
+ pthread_mutex_lock(&m);
+ pthread_mutex_destroy(&m);
+ return 0;
+}
+
+int main() {
+ pthread_t th;
+ pthread_create(&th, 0, thread, 0);
+ pthread_join(th, 0);
+ return 0;
+}
+
+// CHECK: WARNING: ThreadSanitizer: destroy of a locked mutex
+// CHECK: #0 pthread_mutex_destroy
+// CHECK: #1 thread
+// CHECK: and:
+// CHECK: #0 pthread_mutex_lock
+// CHECK: #1 thread
+// CHECK: Mutex {{.*}} created at:
+// CHECK: #0 pthread_mutex_init
+// CHECK: #1 thread
+// CHECK: SUMMARY: ThreadSanitizer: destroy of a locked mutex {{.*}} in thread
diff --git a/compiler-rt/test/tsan/suppressions_mutex.cc b/compiler-rt/test/tsan/suppressions_mutex.cc
new file mode 100644
index 00000000000..5d3a5d05289
--- /dev/null
+++ b/compiler-rt/test/tsan/suppressions_mutex.cc
@@ -0,0 +1,19 @@
+// RUN: %clang_tsan -O1 %s -o %t && %env_tsan_opts=suppressions='%s.supp' %run %t 2>&1 | FileCheck %s
+#include "test.h"
+
+void __attribute__((noinline)) suppress_this(pthread_mutex_t *mu) {
+ pthread_mutex_destroy(mu);
+}
+
+int main() {
+ pthread_mutex_t mu;
+ pthread_mutex_init(&mu, 0);
+ pthread_mutex_lock(&mu);
+ suppress_this(&mu);
+ fprintf(stderr, "DONE\n");
+ return 0;
+}
+
+// CHECK-NOT: failed to open suppressions file
+// CHECK-NOT: WARNING: ThreadSanitizer:
+// CHECK: DONE
diff --git a/compiler-rt/test/tsan/suppressions_mutex.cc.supp b/compiler-rt/test/tsan/suppressions_mutex.cc.supp
new file mode 100644
index 00000000000..595febbea5c
--- /dev/null
+++ b/compiler-rt/test/tsan/suppressions_mutex.cc.supp
@@ -0,0 +1,2 @@
+mutex:suppress_this
+
OpenPOWER on IntegriCloud