mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-03 17:54:19 +02:00
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:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user