forked from OSchip/llvm-project
[sanitizer] more human-readable deadlock reports
llvm-svn: 204454
This commit is contained in:
parent
67c969367a
commit
7317d9499b
|
@ -162,6 +162,12 @@ static void PrintMutexShort(const ReportMutex *rm, const char *after) {
|
|||
Printf("%sM%zd%s%s", d.Mutex(), rm->id, d.EndMutex(), after);
|
||||
}
|
||||
|
||||
static void PrintMutexShortWitAddress(const ReportMutex *rm,
|
||||
const char *after) {
|
||||
Decorator d;
|
||||
Printf("%sM%zd (%p)%s%s", d.Mutex(), rm->id, rm->addr, d.EndMutex(), after);
|
||||
}
|
||||
|
||||
static void PrintMutex(const ReportMutex *rm) {
|
||||
Decorator d;
|
||||
if (rm->destroyed) {
|
||||
|
@ -231,18 +237,30 @@ void PrintReport(const ReportDesc *rep) {
|
|||
Printf("%s", d.EndWarning());
|
||||
|
||||
if (rep->typ == ReportTypeDeadlock) {
|
||||
Printf(" Path: ");
|
||||
CHECK_GT(rep->mutexes.Size(), 0U);
|
||||
CHECK_EQ(rep->mutexes.Size() * 2, rep->stacks.Size());
|
||||
Printf(" Cycle in lock order graph: ");
|
||||
for (uptr i = 0; i < rep->mutexes.Size(); i++)
|
||||
PrintMutexShort(rep->mutexes[i], " => ");
|
||||
PrintMutexShortWitAddress(rep->mutexes[i], " => ");
|
||||
PrintMutexShort(rep->mutexes[0], "\n\n");
|
||||
CHECK_GT(rep->mutexes.Size(), 0U);
|
||||
CHECK_EQ(rep->mutexes.Size() * (flags()->second_deadlock_stack ? 2 : 1),
|
||||
rep->stacks.Size());
|
||||
for (uptr i = 0; i < rep->mutexes.Size(); i++) {
|
||||
Printf(" Edge: ");
|
||||
PrintMutexShort(rep->mutexes[i], " => ");
|
||||
PrintMutexShort(rep->mutexes[(i+1) % rep->mutexes.Size()], "\n");
|
||||
PrintStack(rep->stacks[2*i]);
|
||||
PrintStack(rep->stacks[2*i+1]);
|
||||
Printf(" Mutex ");
|
||||
PrintMutexShort(rep->mutexes[(i + 1) % rep->mutexes.Size()],
|
||||
" acquired here while holding mutex ");
|
||||
PrintMutexShort(rep->mutexes[i], ":\n");
|
||||
if (flags()->second_deadlock_stack) {
|
||||
PrintStack(rep->stacks[2*i]);
|
||||
Printf(" Mutex ");
|
||||
PrintMutexShort(rep->mutexes[i],
|
||||
" previously acquired by the same thread here:\n");
|
||||
PrintStack(rep->stacks[2*i+1]);
|
||||
} else {
|
||||
PrintStack(rep->stacks[i]);
|
||||
if (i == 0)
|
||||
Printf(" Hint: use TSAN_OPTIONS=second_deadlock_stack=1 "
|
||||
"to get more informative warning message\n\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (uptr i = 0; i < rep->stacks.Size(); i++) {
|
||||
|
@ -261,8 +279,10 @@ void PrintReport(const ReportDesc *rep) {
|
|||
for (uptr i = 0; i < rep->locs.Size(); i++)
|
||||
PrintLocation(rep->locs[i]);
|
||||
|
||||
for (uptr i = 0; i < rep->mutexes.Size(); i++)
|
||||
PrintMutex(rep->mutexes[i]);
|
||||
if (rep->typ != ReportTypeDeadlock) {
|
||||
for (uptr i = 0; i < rep->mutexes.Size(); i++)
|
||||
PrintMutex(rep->mutexes[i]);
|
||||
}
|
||||
|
||||
for (uptr i = 0; i < rep->threads.Size(); i++)
|
||||
PrintThread(rep->threads[i]);
|
||||
|
|
|
@ -417,7 +417,7 @@ void ReportDeadlock(ThreadState *thr, uptr pc, DDReport *r) {
|
|||
uptr dummy_pc = 0x42;
|
||||
for (int i = 0; i < r->n; i++) {
|
||||
uptr size;
|
||||
for (int j = 0; j < 2; j++) {
|
||||
for (int j = 0; j < (flags()->second_deadlock_stack ? 2 : 1); j++) {
|
||||
u32 stk = r->loop[i].stk[j];
|
||||
if (stk) {
|
||||
const uptr *trace = StackDepotGet(stk, &size);
|
||||
|
|
|
@ -152,17 +152,18 @@ class LockTest {
|
|||
Lock_0_1();
|
||||
Lock_1_0();
|
||||
// CHECK: WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock)
|
||||
// CHECK: Path: [[M1:M[0-9]+]] => [[M2:M[0-9]+]] => [[M1]]
|
||||
// CHECK: Edge: [[M1]] => [[M2]]
|
||||
// CHECK: Cycle in lock order graph: [[M1:M[0-9]+]] ([[A1]]) => [[M2:M[0-9]+]] ([[A2]]) => [[M1]]
|
||||
// CHECK: Mutex [[M2]] acquired here while holding mutex [[M1]]
|
||||
// CHECK: #0 pthread_
|
||||
// CHECK-SECOND: Mutex [[M1]] previously acquired by the same thread here:
|
||||
// CHECK-SECOND: #0 pthread_
|
||||
// CHECK-NOT-SECOND: second_deadlock_stack=1 to get more informative warning message
|
||||
// CHECK-NOT-SECOND-NOT: #0 pthread_
|
||||
// CHECK: Mutex [[M1]] acquired here while holding mutex [[M2]]
|
||||
// CHECK: #0 pthread_
|
||||
// CHECK-SECOND: Mutex [[M2]] previously acquired by the same thread here:
|
||||
// CHECK-SECOND: #0 pthread_
|
||||
// CHECK-NOT-SECOND-NOT: #0 pthread_
|
||||
// CHECK: Edge: [[M2]] => [[M1]]
|
||||
// CHECK: #0 pthread_
|
||||
// CHECK-SECOND: #0 pthread_
|
||||
// CHECK-NOT-SECOND-NOT: #0 pthread_
|
||||
// CHECK: Mutex [[M1]] ([[A1]]) created at:
|
||||
// CHECK: Mutex [[M2]] ([[A2]]) created at:
|
||||
// CHECK-NOT: WARNING: ThreadSanitizer:
|
||||
}
|
||||
|
||||
|
@ -178,10 +179,7 @@ class LockTest {
|
|||
Lock2(1, 2);
|
||||
Lock2(2, 0);
|
||||
// CHECK: WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock)
|
||||
// CHECK: Path: [[M1:M[0-9]+]] => [[M2:M[0-9]+]] => [[M3:M[0-9]+]] => [[M1]]
|
||||
// CHECK: Mutex [[M1]] ([[A1]]) created at:
|
||||
// CHECK: Mutex [[M2]] ([[A2]]) created at:
|
||||
// CHECK: Mutex [[M3]] ([[A3]]) created at:
|
||||
// CHECK: Cycle in lock order graph: [[M1:M[0-9]+]] ([[A1]]) => [[M2:M[0-9]+]] ([[A2]]) => [[M3:M[0-9]+]] ([[A3]]) => [[M1]]
|
||||
// CHECK-NOT: WARNING: ThreadSanitizer:
|
||||
}
|
||||
|
||||
|
@ -426,12 +424,16 @@ class LockTest {
|
|||
fprintf(stderr, "Starting Test16: detailed output test with two locks\n");
|
||||
// CHECK: Starting Test16
|
||||
// CHECK: WARNING: ThreadSanitizer: lock-order-inversion
|
||||
// CHECK: acquired here while holding mutex
|
||||
// CHECK: LockTest::Acquire1
|
||||
// CHECK-NEXT: LockTest::Acquire_0_then_1
|
||||
// CHECK-SECOND: previously acquired by the same thread here
|
||||
// CHECK-SECOND: LockTest::Acquire0
|
||||
// CHECK-SECOND-NEXT: LockTest::Acquire_0_then_1
|
||||
// CHECK: acquired here while holding mutex
|
||||
// CHECK: LockTest::Acquire0
|
||||
// CHECK-NEXT: LockTest::Acquire_1_then_0
|
||||
// CHECK-SECOND: previously acquired by the same thread here
|
||||
// CHECK-SECOND: LockTest::Acquire1
|
||||
// CHECK-SECOND-NEXT: LockTest::Acquire_1_then_0
|
||||
Init(5);
|
||||
|
|
Loading…
Reference in New Issue