Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2012-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#include <sync.h>6#include <test/util/common.h>8#include <boost/test/unit_test.hpp>10#include <mutex>11#include <stdexcept>13namespace {14template <typename MutexType>15void TestPotentialDeadLockDetected(MutexType& mutex1, MutexType& mutex2)16{17{18LOCK2(mutex1, mutex2);19}20BOOST_CHECK(LockStackEmpty());21{22#ifdef DEBUG_LOCKORDER23BOOST_CHECK_EXCEPTION(LOCK2(mutex2, mutex1), std::logic_error, HasReason{"potential deadlock detected: mutex1 -> mutex2 -> mutex1"});24#else25LOCK2(mutex2, mutex1);26#endif27}28BOOST_CHECK(LockStackEmpty());29}31#ifdef DEBUG_LOCKORDER32template <typename MutexType>33void TestDoubleLock2(MutexType& m)34{35LOCK(m);36}38template <typename MutexType>39void TestDoubleLock(bool should_throw)40{41const bool prev = g_debug_lockorder_abort;42g_debug_lockorder_abort = false;44MutexType m;45{46LOCK(m);47if (should_throw) {48BOOST_CHECK_EXCEPTION(TestDoubleLock2(m), std::logic_error,49HasReason("double lock detected"));50} else {51BOOST_CHECK_NO_THROW(TestDoubleLock2(m));52}53}54BOOST_CHECK(LockStackEmpty());56g_debug_lockorder_abort = prev;57}58#endif /* DEBUG_LOCKORDER */60template <typename MutexType>61void TestInconsistentLockOrderDetected(MutexType& mutex1, MutexType& mutex2)62{63{64WAIT_LOCK(mutex1, lock1);65LOCK(mutex2);66#ifdef DEBUG_LOCKORDER67BOOST_CHECK_EXCEPTION(REVERSE_LOCK(lock1, mutex1), std::logic_error, HasReason("mutex1 was not most recent critical section locked"));68#endif // DEBUG_LOCKORDER69}70BOOST_CHECK(LockStackEmpty());71}72} // namespace74BOOST_AUTO_TEST_SUITE(sync_tests)76BOOST_AUTO_TEST_CASE(potential_deadlock_detected)77{78#ifdef DEBUG_LOCKORDER79bool prev = g_debug_lockorder_abort;80g_debug_lockorder_abort = false;81#endif83RecursiveMutex rmutex1, rmutex2;84TestPotentialDeadLockDetected(rmutex1, rmutex2);85// The second test ensures that lock tracking data have not been broken by exception.86TestPotentialDeadLockDetected(rmutex1, rmutex2);88Mutex mutex1, mutex2;89TestPotentialDeadLockDetected(mutex1, mutex2);90// The second test ensures that lock tracking data have not been broken by exception.91TestPotentialDeadLockDetected(mutex1, mutex2);93#ifdef DEBUG_LOCKORDER94g_debug_lockorder_abort = prev;95#endif96}98/* Double lock would produce an undefined behavior. Thus, we only do that if99* DEBUG_LOCKORDER is activated to detect it. We don't want non-DEBUG_LOCKORDER100* build to produce tests that exhibit known undefined behavior. */101#ifdef DEBUG_LOCKORDER102BOOST_AUTO_TEST_CASE(double_lock_mutex)103{104TestDoubleLock<Mutex>(/*should_throw=*/true);105}107BOOST_AUTO_TEST_CASE(double_lock_recursive_mutex)108{109TestDoubleLock<RecursiveMutex>(/*should_throw=*/false);110}111#endif /* DEBUG_LOCKORDER */113BOOST_AUTO_TEST_CASE(inconsistent_lock_order_detected)114{115#ifdef DEBUG_LOCKORDER116bool prev = g_debug_lockorder_abort;117g_debug_lockorder_abort = false;118#endif // DEBUG_LOCKORDER120RecursiveMutex rmutex1, rmutex2;121TestInconsistentLockOrderDetected(rmutex1, rmutex2);122// By checking lock order consistency (CheckLastCritical) before any unlocking (LeaveCritical)123// the lock tracking data must not have been broken by exception.124TestInconsistentLockOrderDetected(rmutex1, rmutex2);126Mutex mutex1, mutex2;127TestInconsistentLockOrderDetected(mutex1, mutex2);128// By checking lock order consistency (CheckLastCritical) before any unlocking (LeaveCritical)129// the lock tracking data must not have been broken by exception.130TestInconsistentLockOrderDetected(mutex1, mutex2);132#ifdef DEBUG_LOCKORDER133g_debug_lockorder_abort = prev;134#endif // DEBUG_LOCKORDER135}137BOOST_AUTO_TEST_SUITE_END()
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.