| 93 | } |
| 94 | |
| 95 | static void potential_deadlock_detected(const LockPair& mismatch, const LockStack& s1, const LockStack& s2) |
| 96 | { |
| 97 | LogPrintf("POTENTIAL DEADLOCK DETECTED\n"); |
| 98 | LogPrintf("Previous lock order was:\n"); |
| 99 | for (const LockStackItem& i : s1) { |
| 100 | std::string prefix{}; |
| 101 | if (i.first == mismatch.first) { |
| 102 | prefix = " (1)"; |
| 103 | } |
| 104 | if (i.first == mismatch.second) { |
| 105 | prefix = " (2)"; |
| 106 | } |
| 107 | LogPrintf("%s %s\n", prefix, i.second.ToString()); |
| 108 | } |
| 109 | |
| 110 | std::string mutex_a, mutex_b; |
| 111 | LogPrintf("Current lock order is:\n"); |
| 112 | for (const LockStackItem& i : s2) { |
| 113 | std::string prefix{}; |
| 114 | if (i.first == mismatch.first) { |
| 115 | prefix = " (1)"; |
| 116 | mutex_a = i.second.Name(); |
| 117 | } |
| 118 | if (i.first == mismatch.second) { |
| 119 | prefix = " (2)"; |
| 120 | mutex_b = i.second.Name(); |
| 121 | } |
| 122 | LogPrintf("%s %s\n", prefix, i.second.ToString()); |
| 123 | } |
| 124 | if (g_debug_lockorder_abort) { |
| 125 | tfm::format(std::cerr, "Assertion failed: detected inconsistent lock order for %s, details in debug log.\n", s2.back().second.ToString()); |
| 126 | abort(); |
| 127 | } |
| 128 | throw std::logic_error(strprintf("potential deadlock detected: %s -> %s -> %s", mutex_b, mutex_a, mutex_b)); |
| 129 | } |
| 130 | |
| 131 | static void double_lock_detected(const void* mutex, const LockStack& lock_stack) |
| 132 | { |