[tsan] in deadlock detector do not register locks on their creation and unregister them on destruction; added a relevant test

llvm-svn: 201568
This commit is contained in:
Kostya Serebryany 2014-02-18 12:50:31 +00:00
parent a50abe6656
commit aa416c39cd
2 changed files with 24 additions and 7 deletions

View File

@ -45,10 +45,6 @@ void MutexCreate(ThreadState *thr, uptr pc, uptr addr,
s->is_rw = rw;
s->is_recursive = recursive;
s->is_linker_init = linker_init;
if (common_flags()->detect_deadlocks) {
EnsureDeadlockDetectorID(thr, s);
Printf("MutexCreate: %zx\n", s->deadlock_detector_id);
}
s->mtx.Unlock();
}
@ -66,8 +62,9 @@ void MutexDestroy(ThreadState *thr, uptr pc, uptr addr) {
if (s == 0)
return;
if (common_flags()->detect_deadlocks) {
EnsureDeadlockDetectorID(thr, s);
Printf("MutexDestroy: %zx\n", s->deadlock_detector_id);
if (s->deadlock_detector_id)
g_deadlock_detector.removeNode(s->deadlock_detector_id);
s->deadlock_detector_id = 0;
}
if (IsAppMem(addr)) {
CHECK(!thr->is_freeing);
@ -169,7 +166,7 @@ int MutexUnlock(ThreadState *thr, uptr pc, uptr addr, bool all) {
thr->mset.Del(s->GetId(), true);
if (common_flags()->detect_deadlocks) {
EnsureDeadlockDetectorID(thr, s);
Printf("MutexUnlock: %zx\n", s->deadlock_detector_id);
// Printf("MutexUnlock: %zx\n", s->deadlock_detector_id);
g_deadlock_detector.onUnlock(&thr->deadlock_detector_tls,
s->deadlock_detector_id);
}

View File

@ -33,6 +33,7 @@ class LockTest {
locks_[i].unlock();
}
// Simple lock order onversion.
void Test1() {
fprintf(stderr, "Starting Test1\n");
// CHECK: Starting Test1
@ -42,6 +43,7 @@ class LockTest {
// CHECK-NOT: ThreadSanitizer:
}
// Simple lock order inversion with 3 locks.
void Test2() {
fprintf(stderr, "Starting Test2\n");
// CHECK: Starting Test2
@ -51,7 +53,24 @@ class LockTest {
// CHECK-NOT: ThreadSanitizer:
}
// Lock order inversion with lots of new locks created (but not used)
// between. Since the new locks are not used we should still detect the
// deadlock.
void Test3() {
fprintf(stderr, "Starting Test3\n");
// CHECK: Starting Test3
L(0); L(1); U(0); U(1);
CreateAndDestroyManyLocks();
L(1); L(0); U(0); U(1);
// CHECK: ThreadSanitizer: lock-order-inversion (potential deadlock)
// CHECK-NOT: ThreadSanitizer:
}
private:
void CreateAndDestroyManyLocks() {
PaddedLock create_many_locks_but_never_acquire[kDeadlockGraphSize];
}
static const size_t kDeadlockGraphSize = 4096;
size_t n_;
PaddedLock *locks_;
};
@ -59,6 +78,7 @@ class LockTest {
int main() {
{ LockTest t(5); t.Test1(); }
{ LockTest t(5); t.Test2(); }
{ LockTest t(5); t.Test3(); }
fprintf(stderr, "DONE\n");
// CHECK: DONE
}