summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2014-04-25 07:42:55 +0000
committerDmitry Vyukov <dvyukov@google.com>2014-04-25 07:42:55 +0000
commitc845decce1eaf0047b29bf44fef758ccd873be2d (patch)
tree613602abd1533386dd36c7fbcfb710ccfd844571 /compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc
parent3212b18bbf8458cc9eabbb8938ffcef68af7473c (diff)
downloadbcm5719-llvm-c845decce1eaf0047b29bf44fef758ccd873be2d.tar.gz
bcm5719-llvm-c845decce1eaf0047b29bf44fef758ccd873be2d.zip
tsan: better reports for "double lock of a mutex"
+ fixes crashes due to races on symbolizer, see: https://code.google.com/p/thread-sanitizer/issues/detail?id=55 llvm-svn: 207204
Diffstat (limited to 'compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc')
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc19
1 files changed, 16 insertions, 3 deletions
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc
index e26e142368f..83e76968b32 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc
@@ -117,15 +117,16 @@ void MutexLock(ThreadState *thr, uptr pc, uptr addr, int rec, bool try_lock) {
SyncVar *s = ctx->synctab.GetOrCreateAndLock(thr, pc, addr, true);
thr->fast_state.IncrementEpoch();
TraceAddEvent(thr, thr->fast_state, EventTypeLock, s->GetId());
+ bool report_double_lock = false;
if (s->owner_tid == SyncVar::kInvalidTid) {
CHECK_EQ(s->recursion, 0);
s->owner_tid = thr->tid;
s->last_lock = thr->fast_state.raw();
} else if (s->owner_tid == thr->tid) {
CHECK_GT(s->recursion, 0);
- } else {
- Printf("ThreadSanitizer WARNING: double lock of mutex %p\n", addr);
- PrintCurrentStack(thr, pc);
+ } else if (flags()->report_mutex_bugs && !s->is_broken) {
+ s->is_broken = true;
+ report_double_lock = true;
}
if (s->recursion == 0) {
StatInc(thr, StatMutexLock);
@@ -142,7 +143,19 @@ void MutexLock(ThreadState *thr, uptr pc, uptr addr, int rec, bool try_lock) {
ctx->dd->MutexBeforeLock(&cb, &s->dd, true);
ctx->dd->MutexAfterLock(&cb, &s->dd, true, try_lock);
}
+ u64 mid = s->GetId();
s->mtx.Unlock();
+ // Can't touch s after this point.
+ if (report_double_lock) {
+ ThreadRegistryLock l(ctx->thread_registry);
+ ScopedReport rep(ReportTypeMutexDoubleLock);
+ rep.AddMutex(mid);
+ StackTrace trace;
+ trace.ObtainCurrent(thr, pc);
+ rep.AddStack(&trace);
+ rep.AddLocation(addr, 1);
+ OutputReport(ctx, rep);
+ }
if (flags()->detect_deadlocks) {
Callback cb(thr, pc);
ReportDeadlock(thr, pc, ctx->dd->GetReport(&cb));
OpenPOWER on IntegriCloud