diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2014-04-25 07:42:55 +0000 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2014-04-25 07:42:55 +0000 |
| commit | c845decce1eaf0047b29bf44fef758ccd873be2d (patch) | |
| tree | 613602abd1533386dd36c7fbcfb710ccfd844571 /compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc | |
| parent | 3212b18bbf8458cc9eabbb8938ffcef68af7473c (diff) | |
| download | bcm5719-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.cc | 19 |
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)); |

