diff options
author | Dmitry Vyukov <dvyukov@google.com> | 2016-06-03 11:48:27 +0000 |
---|---|---|
committer | Dmitry Vyukov <dvyukov@google.com> | 2016-06-03 11:48:27 +0000 |
commit | 031c1e40660c8eaaa418ce84b16b82b37ca32652 (patch) | |
tree | eb00e9d649aa7a2a8f7e5c4f3e7754d40729efab /lib/tsan/rtl/tsan_rtl_mutex.cc | |
parent | 009632990e8c5b96eb0973782381fa0e778858ae (diff) |
tsan: rely on AnnotateRWLockCreateStatic to detect linker-initialized mutexes
The new annotation was added a while ago, but was not actually used.
Use the annotation to detect linker-initialized mutexes instead
of the broken IsGlobalVar which has both false positives and false
negatives. Remove IsGlobalVar mess.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@271663 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/tsan/rtl/tsan_rtl_mutex.cc')
-rw-r--r-- | lib/tsan/rtl/tsan_rtl_mutex.cc | 29 |
1 files changed, 15 insertions, 14 deletions
diff --git a/lib/tsan/rtl/tsan_rtl_mutex.cc b/lib/tsan/rtl/tsan_rtl_mutex.cc index b5125b39b..3d700d824 100644 --- a/lib/tsan/rtl/tsan_rtl_mutex.cc +++ b/lib/tsan/rtl/tsan_rtl_mutex.cc @@ -84,21 +84,14 @@ void MutexCreate(ThreadState *thr, uptr pc, uptr addr, void MutexDestroy(ThreadState *thr, uptr pc, uptr addr) { DPrintf("#%d: MutexDestroy %zx\n", thr->tid, addr); StatInc(thr, StatMutexDestroy); -#ifndef SANITIZER_GO - // Global mutexes not marked as LINKER_INITIALIZED - // cause tons of not interesting reports, so just ignore it. - if (IsGlobalVar(addr)) - return; -#endif - if (IsAppMem(addr)) { - CHECK(!thr->is_freeing); - thr->is_freeing = true; - MemoryWrite(thr, pc, addr, kSizeLog1); - thr->is_freeing = false; - } SyncVar *s = ctx->metamap.GetIfExistsAndLock(addr); if (s == 0) return; + if (s->is_linker_init) { + // Destroy is no-op for linker-initialized mutexes. + s->mtx.Unlock(); + return; + } if (common_flags()->detect_deadlocks) { Callback cb(thr, pc); ctx->dd->MutexDestroy(&cb, &s->dd); @@ -128,8 +121,7 @@ void MutexDestroy(ThreadState *thr, uptr pc, uptr addr) { rep.AddStack(trace, true); rep.AddLocation(addr, 1); OutputReport(thr, rep); - } - if (unlock_locked) { + SyncVar *s = ctx->metamap.GetIfExistsAndLock(addr); if (s != 0) { s->Reset(thr->proc()); @@ -137,6 +129,15 @@ void MutexDestroy(ThreadState *thr, uptr pc, uptr addr) { } } thr->mset.Remove(mid); + // Imitate a memory write to catch unlock-destroy races. + // Do this outside of sync mutex, because it can report a race which locks + // sync mutexes. + if (IsAppMem(addr)) { + CHECK(!thr->is_freeing); + thr->is_freeing = true; + MemoryWrite(thr, pc, addr, kSizeLog1); + thr->is_freeing = false; + } // s will be destroyed and freed in MetaMap::FreeBlock. } |