aboutsummaryrefslogtreecommitdiff
path: root/src/sync.cpp
diff options
context:
space:
mode:
authorHennadii Stepanov <32963518+hebasto@users.noreply.github.com>2020-09-20 11:33:48 +0300
committerHennadii Stepanov <32963518+hebasto@users.noreply.github.com>2020-12-10 20:46:29 +0200
commitc5e3e74f70c29ac8852903ef425f5f327d5da969 (patch)
tree4c5dacce17a448d00e01a248d36ef03ce78642b9 /src/sync.cpp
parentda957cd62ecc7fde5fa1dfcd134a73b388c2d438 (diff)
downloadbitcoin-c5e3e74f70c29ac8852903ef425f5f327d5da969.tar.xz
sync: Improve CheckLastCritical()
This commit adds actual lock stack logging if check fails.
Diffstat (limited to 'src/sync.cpp')
-rw-r--r--src/sync.cpp32
1 files changed, 20 insertions, 12 deletions
diff --git a/src/sync.cpp b/src/sync.cpp
index f07916041a..acfbe8fe29 100644
--- a/src/sync.cpp
+++ b/src/sync.cpp
@@ -228,20 +228,28 @@ template void EnterCritical(const char*, const char*, int, boost::mutex*, bool);
void CheckLastCritical(void* cs, std::string& lockname, const char* guardname, const char* file, int line)
{
- {
- LockData& lockdata = GetLockData();
- std::lock_guard<std::mutex> lock(lockdata.dd_mutex);
-
- const LockStack& lock_stack = lockdata.m_lock_stacks[std::this_thread::get_id()];
- if (!lock_stack.empty()) {
- const auto& lastlock = lock_stack.back();
- if (lastlock.first == cs) {
- lockname = lastlock.second.Name();
- return;
- }
+ LockData& lockdata = GetLockData();
+ std::lock_guard<std::mutex> lock(lockdata.dd_mutex);
+
+ const LockStack& lock_stack = lockdata.m_lock_stacks[std::this_thread::get_id()];
+ if (!lock_stack.empty()) {
+ const auto& lastlock = lock_stack.back();
+ if (lastlock.first == cs) {
+ lockname = lastlock.second.Name();
+ return;
}
}
- throw std::system_error(EPERM, std::generic_category(), strprintf("%s:%s %s was not most recent critical section locked", file, line, guardname));
+
+ LogPrintf("INCONSISTENT LOCK ORDER DETECTED\n");
+ LogPrintf("Current lock order (least recent first) is:\n");
+ for (const LockStackItem& i : lock_stack) {
+ LogPrintf(" %s\n", i.second.ToString());
+ }
+ if (g_debug_lockorder_abort) {
+ tfm::format(std::cerr, "%s:%s %s was not most recent critical section locked, details in debug log.\n", file, line, guardname);
+ abort();
+ }
+ throw std::logic_error(strprintf("%s was not most recent critical section locked", guardname));
}
void LeaveCritical()