summaryrefslogtreecommitdiff
path: root/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
commit5e540aaf9303f0a897989745f18a61e256ea5ec1 (patch)
treee05533bb888de2d8bb4c2e84d723ae56418a2698 /lib/tsan/rtl/tsan_rtl_mutex.cc
parent08eae9b72395ef00b6b8d7050e1049467f49d9fa (diff)
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 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@207204 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/tsan/rtl/tsan_rtl_mutex.cc')
-rw-r--r--lib/tsan/rtl/tsan_rtl_mutex.cc19
1 files changed, 16 insertions, 3 deletions
diff --git a/lib/tsan/rtl/tsan_rtl_mutex.cc b/lib/tsan/rtl/tsan_rtl_mutex.cc
index e26e14236..83e76968b 100644
--- a/lib/tsan/rtl/tsan_rtl_mutex.cc
+++ b/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));