From 2a35741064339fa7e3f7f54373e583211a24d068 Mon Sep 17 00:00:00 2001 From: Harris Brakmic Date: Sat, 22 Jul 2017 15:23:03 +0200 Subject: [PATCH] Changes in potential_deadlock_detected behavior --- src/sync.cpp | 62 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/src/sync.cpp b/src/sync.cpp index e624a9ee8499b..d3c74ba67ca57 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -59,21 +59,57 @@ static boost::thread_specific_ptr lockstack; static void potential_deadlock_detected(const std::pair& mismatch, const LockStack& s1, const LockStack& s2) { - LogPrintf("POTENTIAL DEADLOCK DETECTED\n"); - LogPrintf("Previous lock order was:\n"); - BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s2) - { - if (i.first == mismatch.first) LogPrintf(" (1)"); - if (i.first == mismatch.second) LogPrintf(" (2)"); - LogPrintf(" %s\n", i.second.ToString()); + // We attempt to not assert on probably-not deadlocks by assuming that + // a try lock will immediately have otherwise bailed if it had + // failed to get the lock + // We do this by, for the locks which triggered the potential deadlock, + // in either lockorder, checking that the second of the two which is locked + // is only a TRY_LOCK, ignoring locks if they are reentrant. + bool firstLocked = false; + bool secondLocked = false; + bool onlyMaybeDeadlock = false; + std::string strOutput = ""; + + strOutput += "POTENTIAL DEADLOCK DETECTED\n"; + strOutput += "Previous lock order was:\n"; + BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, s2) { + if (i.first == mismatch.first) { + strOutput += " (1)"; + if (!firstLocked && secondLocked && i.second.fTry) + onlyMaybeDeadlock = true; + firstLocked = true; + } + if (i.first == mismatch.second) { + strOutput += " (2)"; + if (!secondLocked && firstLocked && i.second.fTry) + onlyMaybeDeadlock = true; + secondLocked = true; + } + strOutput += strprintf(" %s\n", i.second.ToString().c_str()); } - LogPrintf("Current lock order is:\n"); - BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s1) - { - if (i.first == mismatch.first) LogPrintf(" (1)"); - if (i.first == mismatch.second) LogPrintf(" (2)"); - LogPrintf(" %s\n", i.second.ToString()); + firstLocked = false; + secondLocked = false; + strOutput += "Current lock order is:\n"; + BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, s1) { + if (i.first == mismatch.first) { + strOutput += " (1)"; + if (!firstLocked && secondLocked && i.second.fTry) + onlyMaybeDeadlock = true; + firstLocked = true; + } + if (i.first == mismatch.second) { + strOutput += " (2)"; + if (!secondLocked && firstLocked && i.second.fTry) + onlyMaybeDeadlock = true; + secondLocked = true; + } + strOutput += strprintf(" %s\n", i.second.ToString().c_str()); + } + if(!onlyMaybeDeadlock) { + printf("%s\n", strOutput.c_str()); + LogPrintf("%s\n", strOutput.c_str()); } + assert(onlyMaybeDeadlock); } static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)