From fab6d060ce5f580db538070beec1c5518c8c777c Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Thu, 23 Apr 2020 14:04:02 -0400 Subject: test: Add unregister_validation_interface_race test This commit is (intentionally) adding a broken test. The test is broken because it registering a subscriber object that can go out of scope while events are still being sent. To run the broken test and reproduce the bug: - Remove comment /** and */ - ./configure --with-sanitizers=address - export ASAN_OPTIONS=detect_leaks=0 - make - while ./src/test/test_bitcoin -t validationinterface_tests/unregister_validation_interface_race --catch_system_errors=no ; do true; done --- src/test/validationinterface_tests.cpp | 36 ++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'src/test/validationinterface_tests.cpp') diff --git a/src/test/validationinterface_tests.cpp b/src/test/validationinterface_tests.cpp index 208be9285..14f09ae90 100644 --- a/src/test/validationinterface_tests.cpp +++ b/src/test/validationinterface_tests.cpp @@ -12,6 +12,42 @@ BOOST_FIXTURE_TEST_SUITE(validationinterface_tests, TestingSetup) +/** +struct TestSubscriberNoop final : public CValidationInterface { + void BlockChecked(const CBlock&, const BlockValidationState&) override {} +}; + +BOOST_AUTO_TEST_CASE(unregister_validation_interface_race) +{ + std::atomic generate{true}; + + // Start thread to generate notifications + std::thread gen{[&] { + const CBlock block_dummy; + const BlockValidationState state_dummy; + while (generate) { + GetMainSignals().BlockChecked(block_dummy, state_dummy); + } + }}; + + // Start thread to consume notifications + std::thread sub{[&] { + // keep going for about 1 sec, which is 250k iterations + for (int i = 0; i < 250000; i++) { + TestSubscriberNoop sub{}; + RegisterValidationInterface(&sub); + UnregisterValidationInterface(&sub); + } + // tell the other thread we are done + generate = false; + }}; + + gen.join(); + sub.join(); + BOOST_CHECK(!generate); +} +*/ + class TestInterface : public CValidationInterface { public: -- cgit v1.2.3 From 7777f2a4bb1f9d843bc50a4e35085cfbb2808780 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 27 Apr 2020 10:35:32 -0400 Subject: miner: Avoid stack-use-after-return in validationinterface This is achieved by switching to a shared_ptr. Also, switch the validationinterfaces in the tests to use shared_ptrs for the same reason. --- src/test/validationinterface_tests.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/test/validationinterface_tests.cpp') diff --git a/src/test/validationinterface_tests.cpp b/src/test/validationinterface_tests.cpp index 14f09ae90..d2fc20e62 100644 --- a/src/test/validationinterface_tests.cpp +++ b/src/test/validationinterface_tests.cpp @@ -12,7 +12,6 @@ BOOST_FIXTURE_TEST_SUITE(validationinterface_tests, TestingSetup) -/** struct TestSubscriberNoop final : public CValidationInterface { void BlockChecked(const CBlock&, const BlockValidationState&) override {} }; @@ -34,9 +33,9 @@ BOOST_AUTO_TEST_CASE(unregister_validation_interface_race) std::thread sub{[&] { // keep going for about 1 sec, which is 250k iterations for (int i = 0; i < 250000; i++) { - TestSubscriberNoop sub{}; - RegisterValidationInterface(&sub); - UnregisterValidationInterface(&sub); + auto sub = std::make_shared(); + RegisterSharedValidationInterface(sub); + UnregisterSharedValidationInterface(sub); } // tell the other thread we are done generate = false; @@ -46,7 +45,6 @@ BOOST_AUTO_TEST_CASE(unregister_validation_interface_race) sub.join(); BOOST_CHECK(!generate); } -*/ class TestInterface : public CValidationInterface { -- cgit v1.2.3