fuzz: use ImmediateBackgroundTaskRunner to silence DEBUG_LOCKORDER

DEBUG_LOCKORDER was reporting a false positive deadlock with the
cmpctblock fuzz harness when using ImmediateTaskRunner. Since it is
single-threaded, ImmediateTaskRunner callbacks added LockOrders that
could never happen outside of a fuzz test.

First a block would get connected:
* LOCK(mempool.cs)
* BlockConnected (fuzz test runs in same thread)
* LOCK(m_tx_download_mutex)

Then a later iteration of the LIMITED_WHILE would send a TX:
* LOCK(m_tx_download_mutex)
* LOCK(mempool.cs)

causing a false positive deadlock. Normally, the BlockConnected
callback would run in a different thread and no deadlock is reported.

Fix this by launching a thread that runs the callback and is
immediately joined.
This commit is contained in:
Eugene Siegel
2026-05-13 12:00:27 -04:00
parent 1af8e0c4e8
commit 801d36f55b

View File

@@ -36,6 +36,7 @@
#include <txmempool.h>
#include <uint256.h>
#include <util/check.h>
#include <util/task_runner.h>
#include <util/time.h>
#include <util/translation.h>
#include <validation.h>
@@ -52,6 +53,7 @@
#include <optional>
#include <string>
#include <string_view>
#include <thread>
#include <utility>
#include <vector>
@@ -135,6 +137,15 @@ void ResetChainmanAndMempool(TestingSetup& setup)
}
}
//! Used to run tasks in a std::thread to avoid DEBUG_LOCKORDER false positives.
class ImmediateBackgroundTaskRunner : public util::TaskRunnerInterface
{
public:
void insert(std::function<void()> func) override { std::thread(std::move(func)).join(); }
void flush() override {}
size_t size() override { return 0; }
};
} // namespace
extern void MakeRandDeterministicDANGEROUS(const uint256& seed) noexcept;
@@ -144,6 +155,8 @@ void initialize_cmpctblock()
static const auto testing_setup = MakeNoLogFileContext<TestingSetup>();
g_setup = testing_setup.get();
g_nBits = Params().GenesisBlock().nBits;
// Replace validation_signals before creating chainman and mempool so they use it.
testing_setup->m_node.validation_signals = std::make_unique<ValidationSignals>(std::make_unique<ImmediateBackgroundTaskRunner>());
ResetChainmanAndMempool(*g_setup);
}