forked from OSchip/llvm-project
tsan: improve "read unlock of a write locked mutex" report
llvm-svn: 207208
This commit is contained in:
parent
66dbbbc47b
commit
e296164f77
|
@ -78,6 +78,8 @@ static const char *ReportTypeString(ReportType typ) {
|
|||
return "double lock of a mutex";
|
||||
if (typ == ReportTypeMutexBadUnlock)
|
||||
return "unlock of an unlocked mutex (or by a wrong thread)";
|
||||
if (typ == ReportTypeMutexBadReadUnlock)
|
||||
return "read unlock of a write locked mutex";
|
||||
if (typ == ReportTypeSignalUnsafe)
|
||||
return "signal-unsafe call inside of a signal";
|
||||
if (typ == ReportTypeErrnoInSignal)
|
||||
|
|
|
@ -26,6 +26,7 @@ enum ReportType {
|
|||
ReportTypeMutexDestroyLocked,
|
||||
ReportTypeMutexDoubleLock,
|
||||
ReportTypeMutexBadUnlock,
|
||||
ReportTypeMutexBadReadUnlock,
|
||||
ReportTypeSignalUnsafe,
|
||||
ReportTypeErrnoInSignal,
|
||||
ReportTypeDeadlock
|
||||
|
|
|
@ -249,18 +249,32 @@ void MutexReadUnlock(ThreadState *thr, uptr pc, uptr addr) {
|
|||
SyncVar *s = ctx->synctab.GetOrCreateAndLock(thr, pc, addr, true);
|
||||
thr->fast_state.IncrementEpoch();
|
||||
TraceAddEvent(thr, thr->fast_state, EventTypeRUnlock, s->GetId());
|
||||
bool report_bad_unlock = false;
|
||||
if (s->owner_tid != SyncVar::kInvalidTid) {
|
||||
Printf("ThreadSanitizer WARNING: read unlock of a write locked mutex %p\n",
|
||||
addr);
|
||||
PrintCurrentStack(thr, pc);
|
||||
if (flags()->report_mutex_bugs && !s->is_broken) {
|
||||
s->is_broken = true;
|
||||
report_bad_unlock = true;
|
||||
}
|
||||
}
|
||||
ReleaseImpl(thr, pc, &s->read_clock);
|
||||
if (flags()->detect_deadlocks && s->recursion == 0) {
|
||||
Callback cb(thr, pc);
|
||||
ctx->dd->MutexBeforeUnlock(&cb, &s->dd, false);
|
||||
}
|
||||
u64 mid = s->GetId();
|
||||
s->mtx.Unlock();
|
||||
thr->mset.Del(s->GetId(), false);
|
||||
// Can't touch s after this point.
|
||||
thr->mset.Del(mid, false);
|
||||
if (report_bad_unlock) {
|
||||
ThreadRegistryLock l(ctx->thread_registry);
|
||||
ScopedReport rep(ReportTypeMutexBadReadUnlock);
|
||||
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));
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s
|
||||
extern "C" void AnnotateRWLockAcquired(const char *f, int l, void *m, long rw);
|
||||
extern "C" void AnnotateRWLockReleased(const char *f, int l, void *m, long rw);
|
||||
|
||||
int main() {
|
||||
int m = 0;
|
||||
AnnotateRWLockAcquired(__FILE__, __LINE__, &m, 1);
|
||||
AnnotateRWLockReleased(__FILE__, __LINE__, &m, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// CHECK: WARNING: ThreadSanitizer: read unlock of a write locked mutex
|
||||
// CHECK: #0 AnnotateRWLockReleased
|
||||
// CHECK: #1 main
|
||||
// CHECK: Location is stack of main thread.
|
||||
// CHECK: Mutex {{.*}}) created at:
|
||||
// CHECK: #0 AnnotateRWLockAcquired
|
||||
// CHECK: #1 main
|
||||
// CHECK: SUMMARY: ThreadSanitizer: read unlock of a write locked mutex
|
||||
|
Loading…
Reference in New Issue