summaryrefslogtreecommitdiff
path: root/lib/tsan/rtl/tsan_rtl_mutex.cc
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2016-06-03 11:48:27 +0000
committerDmitry Vyukov <dvyukov@google.com>2016-06-03 11:48:27 +0000
commit031c1e40660c8eaaa418ce84b16b82b37ca32652 (patch)
treeeb00e9d649aa7a2a8f7e5c4f3e7754d40729efab /lib/tsan/rtl/tsan_rtl_mutex.cc
parent009632990e8c5b96eb0973782381fa0e778858ae (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.cc29
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.
}