Skip to content

Commit 4f42fc4

Browse files
committed
Fix getParams() delete race on async cancellations
TSAN reports errors when run_unclean_disconnect_test from https://github.com/bitcoin/bitcoin/pull/34284 is run because when the test disconnects during a `waitNext` IPC call there is no thread synchronization preventing the `waitNext` parameters from being deleted while they are being accessed. Fix by introducing a mutex to protect against this race. TSAN output from the test is shown below. WARNING: ThreadSanitizer: data race (pid=86917) Write of size 8 at 0x72300001e380 by thread T2: #0 operator delete(void*) <null> (bitcoin-node+0x1c1196) #1 capnp::BufferedMessageStream::MessageReaderImpl::~MessageReaderImpl() <null> (libcapnp-rpc.so.1.2.0+0x6095e) (BuildId: 98f819a103310afbd8f791a0c80d203a4d1b9791) #2 mp::EventLoop::loop() /home/src/bitcoin/build/src/ipc/libmultiprocess/./ipc/libmultiprocess/src/mp/proxy.cpp:244:68 (bitcoin-node+0x17b135e) #3 ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()::operator()() const /home/src/bitcoin/build/src/ipc/./ipc/capnp/protocol.cpp:136:21 (bitcoin-node+0xe516e4) #4 void std::__invoke_impl<void, ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>(std::__invoke_other, ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()&&) /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/invoke.h:61:14 (bitcoin-node+0xe514a2) #5 std::__invoke_result<ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>::type std::__invoke<ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>(ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()&&) /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/invoke.h:96:14 (bitcoin-node+0xe513a2) #6 void std::thread::_Invoker<std::tuple<ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>>::_M_invoke<0ul>(std::_Index_tuple<0ul>) /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/std_thread.h:301:13 (bitcoin-node+0xe5130a) #7 std::thread::_Invoker<std::tuple<ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>>::operator()() /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/std_thread.h:308:11 (bitcoin-node+0xe51272) #8 std::thread::_State_impl<std::thread::_Invoker<std::tuple<ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>>>::_M_run() /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/std_thread.h:253:13 (bitcoin-node+0xe5106a) #9 execute_native_thread_routine <null> (libstdc++.so.6+0xed063) Previous read of size 8 at 0x72300001e380 by thread T13: #0 capnp::_::DirectWireValue<double>::get() const /nix/store/8xjrdb1y9ng6w6yknzg9h6fkxd3sb824-capnproto-1.2.0/include/capnp/endian.h:77:44 (bitcoin-node+0x10dd19a) #1 double capnp::_::StructReader::getDataField<double>(unsigned int) const /nix/store/8xjrdb1y9ng6w6yknzg9h6fkxd3sb824-capnproto-1.2.0/include/capnp/layout.h:1100:84 (bitcoin-node+0x10dd0d1) #2 ipc::capnp::messages::BlockWaitOptions::Reader::getTimeout() const /home/src/bitcoin/build/src/ipc/capnp/mining.capnp.h:6092:18 (bitcoin-node+0x1222b65) #3 decltype(fp.getTimeout()) mp::mining_fields::Timeout::get<ipc::capnp::messages::BlockWaitOptions::Reader const&>(ipc::capnp::messages::BlockWaitOptions::Reader const&) /home/src/bitcoin/build/src/ipc/capnp/mining.capnp.proxy.h:163:88 (bitcoin-node+0x1222ab6) #4 mp::StructField<mp::Accessor<mp::mining_fields::Timeout, 3>, ipc::capnp::messages::BlockWaitOptions::Reader const>::get() const /home/src/bitcoin/build/src/ipc/./ipc/libmultiprocess/include/mp/proxy-types.h:40:41 (bitcoin-node+0x1222a16) #5 decltype(auto) mp::CustomReadField<double, std::ratio<1l, 1000l>, mp::StructField<mp::Accessor<mp::mining_fields::Timeout, 3>, ipc::capnp::messages::BlockWaitOptions::Reader const>, mp::ReadDestUpdate<std::chrono::duration<double, std::ratio<1l, 1000l>>>>(mp::TypeList<std::chrono::duration<double, std::ratio<1l, 1000l>>>, mp::Priority<1>, mp::InvokeContext&, mp::StructField<mp::Accessor<mp::mining_fields::Timeout, 3>, ipc::capnp::messages::BlockWaitOptions::Reader const>&&, mp::ReadDestUpdate<std::chrono::duration<double, std::ratio<1l, 1000l>>>&&) /home/src/bitcoin/build/src/ipc/./ipc/libmultiprocess/include/mp/type-chrono.h:30:38 (bitcoin-node+0x1222899) #6 decltype(auto) mp::ReadField<std::chrono::duration<double, std::ratio<1l, 1000l>>, mp::InvokeContext&, mp::StructField<mp::Accessor<mp::mining_fields::Timeout, 3>, ipc::capnp::messages::BlockWaitOptions::Reader const>, mp::ReadDestUpdate<std::chrono::duration<double, std::ratio<1l, 1000l>>>>(mp::TypeList<std::chrono::duration<double, std::ratio<1l, 1000l>>>, mp::InvokeContext&, mp::StructField<mp::Accessor<mp::mining_fields::Timeout, 3>, ipc::capnp::messages::BlockWaitOptions::Reader const>&&, mp::ReadDestUpdate<std::chrono::duration<double, std::ratio<1l, 1000l>>>&&) /home/src/bitcoin/build/src/ipc/./ipc/libmultiprocess/include/mp/proxy-types.h:172:12 (bitcoin-node+0x12222d6) #7 void mp::ReadOne<0ul, node::BlockWaitOptions, mp::StructField<mp::Accessor<mp::mining_fields::Options, 17>, ipc::capnp::messages::BlockTemplate::WaitNextParams::Reader const>&, node::BlockWaitOptions&>(mp::TypeList<node::BlockWaitOptions>, mp::InvokeContext&, mp::StructField<mp::Accessor<mp::mining_fields::Options, 17>, ipc::capnp::messages::BlockTemplate::WaitNextParams::Reader const>&, node::BlockWaitOptions&, std::enable_if<0ul != ProxyType<node::BlockWaitOptions>::fields, void>::type*) /home/src/bitcoin/build/src/ipc/./ipc/libmultiprocess/include/mp/type-struct.h:59:5 (bitcoin-node+0x122213a) #8 auto decltype(auto) mp::CustomReadField<node::BlockWaitOptions, mp::StructField<mp::Accessor<mp::mining_fields::Options, 17>, ipc::capnp::messages::BlockTemplate::WaitNextParams::Reader const>, mp::ReadDestEmplace<node::BlockWaitOptions, void mp::PassField<mp::Accessor<mp::mining_fields::Options, 17>, node::BlockWaitOptions, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall> const&, mp::TypeList<>>(mp::Priority<0>, mp::TypeList<node::BlockWaitOptions>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall> const&, mp::TypeList<>&&)::'lambda'(auto&&...)>>(mp::TypeList<node::BlockWaitOptions>, mp::Priority<1>, mp::InvokeContext&, node::BlockWaitOptions&&, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&&, mp::ProxyType<node::BlockWaitOptions>::Struct*)::'lambda'(node::BlockWaitOptions&)::operator()<node::BlockWaitOptions>(node::BlockWaitOptions&) const /home/src/bitcoin/build/src/ipc/./ipc/libmultiprocess/include/mp/type-struct.h:81:48 (bitcoin-node+0x1221a71) #9 decltype(auto) mp::ReadDestEmplace<node::BlockWaitOptions, void mp::PassField<mp::Accessor<mp::mining_fields::Options, 17>, node::BlockWaitOptions, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall> const&, mp::TypeList<>>(mp::Priority<0>, mp::TypeList<node::BlockWaitOptions>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall> const&, mp::TypeList<>&&)::'lambda'(auto&&...)>::update<decltype(auto) mp::CustomReadField<node::BlockWaitOptions, mp::StructField<mp::Accessor<mp::mining_fields::Options, 17>, ipc::capnp::messages::BlockTemplate::WaitNextParams::Reader const>, mp::ReadDestEmplace<node::BlockWaitOptions, void mp::PassField<mp::Accessor<mp::mining_fields::Options, 17>, node::BlockWaitOptions, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall> const&, mp::TypeList<>>(mp::Priority<0>, mp::TypeList<node::BlockWaitOptions>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall> const&, mp::TypeList<>&&)::'lambda'(auto&&...)>>(mp::TypeList<node::BlockWaitOptions>, mp::Priority<1>, mp::InvokeContext&, node::BlockWaitOptions&&, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&&, mp::ProxyType<node::BlockWaitOptions>::Struct*)::'lambda'(node::BlockWaitOptions&)>(node::BlockWaitOptions&&) /home/src/bitcoin/build/src/ipc/./ipc/libmultiprocess/include/mp/proxy-types.h:122:13 (bitcoin-node+0x122190d) #10 decltype(auto) mp::CustomReadField<node::BlockWaitOptions, mp::StructField<mp::Accessor<mp::mining_fields::Options, 17>, ipc::capnp::messages::BlockTemplate::WaitNextParams::Reader const>, mp::ReadDestEmplace<node::BlockWaitOptions, void mp::PassField<mp::Accessor<mp::mining_fields::Options, 17>, node::BlockWaitOptions, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall> const&, mp::TypeList<>>(mp::Priority<0>, mp::TypeList<node::BlockWaitOptions>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall> const&, mp::TypeList<>&&)::'lambda'(auto&&...)>>(mp::TypeList<node::BlockWaitOptions>, mp::Priority<1>, mp::InvokeContext&, node::BlockWaitOptions&&, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&&, mp::ProxyType<node::BlockWaitOptions>::Struct*) /home/src/bitcoin/build/src/ipc/./ipc/libmultiprocess/include/mp/type-struct.h:81:22 (bitcoin-node+0x1221832) #11 decltype(auto) mp::ReadField<node::BlockWaitOptions, mp::InvokeContext&, mp::StructField<mp::Accessor<mp::mining_fields::Options, 17>, ipc::capnp::messages::BlockTemplate::WaitNextParams::Reader const>, mp::ReadDestEmplace<node::BlockWaitOptions, void mp::PassField<mp::Accessor<mp::mining_fields::Options, 17>, node::BlockWaitOptions, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall> const&, mp::TypeList<>>(mp::Priority<0>, mp::TypeList<node::BlockWaitOptions>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall> const&, mp::TypeList<>&&)::'lambda'(auto&&...)>>(mp::TypeList<auto...>, mp::InvokeContext&, mp::StructField<mp::Accessor<mp::mining_fields::Options, 17>, ipc::capnp::messages::BlockTemplate::WaitNextParams::Reader const>&&, mp::ReadDestEmplace<node::BlockWaitOptions, void mp::PassField<mp::Accessor<mp::mining_fields::Options, 17>, node::BlockWaitOptions, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall> const&, mp::TypeList<>>(mp::Priority<0>, mp::TypeList<node::BlockWaitOptions>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall> const&, mp::TypeList<>&&)::'lambda'(auto&&...)>&&) /home/src/bitcoin/build/src/ipc/./ipc/libmultiprocess/include/mp/proxy-types.h:172:12 (bitcoin-node+0x122170a) #12 void mp::MaybeReadField<mp::TypeList<node::BlockWaitOptions>, mp::InvokeContext&, mp::StructField<mp::Accessor<mp::mining_fields::Options, 17>, ipc::capnp::messages::BlockTemplate::WaitNextParams::Reader const>, mp::ReadDestEmplace<node::BlockWaitOptions, void mp::PassField<mp::Accessor<mp::mining_fields::Options, 17>, node::BlockWaitOptions, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall> const&, mp::TypeList<>>(mp::Priority<0>, mp::TypeList<node::BlockWaitOptions>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall> const&, mp::TypeList<>&&)::'lambda'(auto&&...)>>(std::integral_constant<bool, true>, auto&&...) /home/src/bitcoin/build/src/ipc/./ipc/libmultiprocess/include/mp/proxy-types.h:269:5 (bitcoin-node+0x1220d52) #13 void mp::PassField<mp::Accessor<mp::mining_fields::Options, 17>, node::BlockWaitOptions, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall> const&, mp::TypeList<>>(mp::Priority<0>, mp::TypeList<node::BlockWaitOptions>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall> const&, mp::TypeList<>&&) /home/src/bitcoin/build/src/ipc/./ipc/libmultiprocess/include/mp/proxy-types.h:297:5 (bitcoin-node+0x1220a89) #14 decltype(auto) mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::TypeList<node::BlockWaitOptions>>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::TypeList<node::BlockWaitOptions>) const /home/src/bitcoin/build/src/ipc/./ipc/libmultiprocess/include/mp/proxy-types.h:549:16 (bitcoin-node+0x12208ea) #15 std::enable_if<std::is_same<decltype(mp::Accessor<mp::mining_fields::Context, 17>::get(fp1.call_context.getParams())), mp::Context::Reader>::value, kj::Promise<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>::CallContext>>::type mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>>, mp::TypeList<node::BlockWaitOptions>>(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>> const&, mp::TypeList<node::BlockWaitOptions>&&)::'lambda'(mp::CancelMonitor&)::operator()(mp::CancelMonitor&)::'lambda1'()::operator()() const /home/src/bitcoin/build/src/ipc/./ipc/libmultiprocess/include/mp/type-context.h:138:21 (bitcoin-node+0x1220534) #16 kj::Maybe<kj::Exception> kj::runCatchingExceptions<std::enable_if<std::is_same<decltype(mp::Accessor<mp::mining_fields::Context, 17>::get(fp1.call_context.getParams())), mp::Context::Reader>::value, kj::Promise<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>::CallContext>>::type mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>>, mp::TypeList<node::BlockWaitOptions>>(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>> const&, mp::TypeList<node::BlockWaitOptions>&&)::'lambda'(mp::CancelMonitor&)::operator()(mp::CancelMonitor&)::'lambda1'()>(mp::Accessor<mp::mining_fields::Context, 17>&&) /nix/store/8xjrdb1y9ng6w6yknzg9h6fkxd3sb824-capnproto-1.2.0/include/kj/exception.h:371:5 (bitcoin-node+0x121d6a1) #17 std::enable_if<std::is_same<decltype(mp::Accessor<mp::mining_fields::Context, 17>::get(fp1.call_context.getParams())), mp::Context::Reader>::value, kj::Promise<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>::CallContext>>::type mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>>, mp::TypeList<node::BlockWaitOptions>>(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>> const&, mp::TypeList<node::BlockWaitOptions>&&)::'lambda'(mp::CancelMonitor&)::operator()(mp::CancelMonitor&) /home/src/bitcoin/build/src/ipc/./ipc/libmultiprocess/include/mp/type-context.h:138:21 (bitcoin-node+0x121cc6c) #18 kj::Promise<mp::Accessor<mp::mining_fields::Context, 17>> mp::ProxyServer<mp::Thread>::post<capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>, std::enable_if<std::is_same<decltype(mp::Accessor<mp::mining_fields::Context, 17>::get(fp1.call_context.getParams())), mp::Context::Reader>::value, kj::Promise<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>::CallContext>>::type mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>>, mp::TypeList<node::BlockWaitOptions>>(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>> const&, mp::TypeList<node::BlockWaitOptions>&&)::'lambda'(mp::CancelMonitor&)>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&&)::'lambda'()::operator()()::'lambda'()::operator()()::'lambda0'()::operator()() const /home/src/bitcoin/build/src/ipc/./ipc/libmultiprocess/include/mp/proxy-io.h:720:100 (bitcoin-node+0x121c4d3) #19 kj::Maybe<kj::Exception> kj::runCatchingExceptions<kj::Promise<mp::Accessor<mp::mining_fields::Context, 17>> mp::ProxyServer<mp::Thread>::post<capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>, std::enable_if<std::is_same<decltype(mp::Accessor<mp::mining_fields::Context, 17>::get(fp1.call_context.getParams())), mp::Context::Reader>::value, kj::Promise<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>::CallContext>>::type mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>>, mp::TypeList<node::BlockWaitOptions>>(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>> const&, mp::TypeList<node::BlockWaitOptions>&&)::'lambda'(mp::CancelMonitor&)>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&&)::'lambda'()::operator()()::'lambda'()::operator()()::'lambda0'()>(mp::Accessor<mp::mining_fields::Context, 17>&&) /nix/store/8xjrdb1y9ng6w6yknzg9h6fkxd3sb824-capnproto-1.2.0/include/kj/exception.h:371:5 (bitcoin-node+0x121b371) #20 kj::Promise<mp::Accessor<mp::mining_fields::Context, 17>> mp::ProxyServer<mp::Thread>::post<capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>, std::enable_if<std::is_same<decltype(mp::Accessor<mp::mining_fields::Context, 17>::get(fp1.call_context.getParams())), mp::Context::Reader>::value, kj::Promise<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>::CallContext>>::type mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>>, mp::TypeList<node::BlockWaitOptions>>(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>> const&, mp::TypeList<node::BlockWaitOptions>&&)::'lambda'(mp::CancelMonitor&)>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&&)::'lambda'()::operator()()::'lambda'()::operator()() /home/src/bitcoin/build/src/ipc/./ipc/libmultiprocess/include/mp/proxy-io.h:720:48 (bitcoin-node+0x121aeb2) #21 kj::Function<void ()>::Impl<kj::Promise<mp::Accessor<mp::mining_fields::Context, 17>> mp::ProxyServer<mp::Thread>::post<capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>, std::enable_if<std::is_same<decltype(mp::Accessor<mp::mining_fields::Context, 17>::get(fp1.call_context.getParams())), mp::Context::Reader>::value, kj::Promise<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>::CallContext>>::type mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>>, mp::TypeList<node::BlockWaitOptions>>(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>> const&, mp::TypeList<node::BlockWaitOptions>&&)::'lambda'(mp::CancelMonitor&)>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&&)::'lambda'()::operator()()::'lambda'()>::operator()() /nix/store/8xjrdb1y9ng6w6yknzg9h6fkxd3sb824-capnproto-1.2.0/include/kj/function.h:142:14 (bitcoin-node+0x121acfa) #22 kj::Function<void ()>::operator()() /nix/store/8xjrdb1y9ng6w6yknzg9h6fkxd3sb824-capnproto-1.2.0/include/kj/function.h:119:12 (bitcoin-node+0xe8e221) #23 void mp::Unlock<mp::Lock, kj::Function<void ()>&>(mp::Lock&, kj::Function<void ()>&) /home/src/bitcoin/build/src/ipc/./ipc/libmultiprocess/include/mp/util.h:210:5 (bitcoin-node+0xe8dd31) #24 void mp::Waiter::wait<mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const::'lambda'()>(mp::Lock&, mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const::'lambda'())::'lambda'()::operator()() const /home/src/bitcoin/build/src/ipc/libmultiprocess/./ipc/libmultiprocess/include/mp/proxy-io.h:371:17 (bitcoin-node+0x17b827f) #25 void std::condition_variable::wait<void mp::Waiter::wait<mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const::'lambda'()>(mp::Lock&, mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const::'lambda'())::'lambda'()>(std::unique_lock<std::mutex>&, mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const::'lambda'()) /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/condition_variable:104:10 (bitcoin-node+0x17b815e) #26 void mp::Waiter::wait<mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const::'lambda'()>(mp::Lock&, mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const::'lambda'()) /home/src/bitcoin/build/src/ipc/libmultiprocess/./ipc/libmultiprocess/include/mp/proxy-io.h:362:14 (bitcoin-node+0x17b7fdf) #27 mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const /home/src/bitcoin/build/src/ipc/libmultiprocess/./ipc/libmultiprocess/src/mp/proxy.cpp:423:34 (bitcoin-node+0x17b7e39) #28 void std::__invoke_impl<void, mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0>(std::__invoke_other, mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0&&) /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/invoke.h:61:14 (bitcoin-node+0x17b7ba2) #29 std::__invoke_result<mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0>::type std::__invoke<mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0>(mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0&&) /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/invoke.h:96:14 (bitcoin-node+0x17b7aa2) #30 void std::thread::_Invoker<std::tuple<mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0>>::_M_invoke<0ul>(std::_Index_tuple<0ul>) /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/std_thread.h:301:13 (bitcoin-node+0x17b7a0a) #31 std::thread::_Invoker<std::tuple<mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0>>::operator()() /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/std_thread.h:308:11 (bitcoin-node+0x17b7972) #32 std::thread::_State_impl<std::thread::_Invoker<std::tuple<mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0>>>::_M_run() /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/std_thread.h:253:13 (bitcoin-node+0x17b745a) #33 execute_native_thread_routine <null> (libstdc++.so.6+0xed063) Thread T2 'b-capnp-loop' (tid=86923, running) created by main thread at: #0 pthread_create <null> (bitcoin-node+0x13a395) #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State>>, void (*)()) <null> (libstdc++.so.6+0xed138) #2 ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*) /home/src/bitcoin/build/src/ipc/./ipc/capnp/protocol.cpp:127:25 (bitcoin-node+0xe50b88) #3 ipc::capnp::(anonymous namespace)::CapnpProtocol::listen(int, char const*, interfaces::Init&) /home/src/bitcoin/build/src/ipc/./ipc/capnp/protocol.cpp:87:9 (bitcoin-node+0xe503b2) #4 ipc::(anonymous namespace)::IpcImpl::listenAddress(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&) /home/src/bitcoin/build/src/ipc/./ipc/interfaces.cpp:111:21 (bitcoin-node+0xe475c5) #5 AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) /home/src/bitcoin/build/src/./init.cpp:1483:22 (bitcoin-node+0x1f8a67) #6 AppInit(node::NodeContext&) /home/src/bitcoin/build/src/./bitcoind.cpp:242:43 (bitcoin-node+0x1c42fd) #7 main /home/src/bitcoin/build/src/./bitcoind.cpp:283:10 (bitcoin-node+0x1c2a95) Thread T13 (tid=86942, running) created by thread T2 at: #0 pthread_create <null> (bitcoin-node+0x13a395) #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State>>, void (*)()) <null> (libstdc++.so.6+0xed138) #2 mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>) /home/src/bitcoin/build/src/ipc/libmultiprocess/./ipc/libmultiprocess/src/mp/proxy.cpp:416:17 (bitcoin-node+0x17b3821) #3 mp::ThreadMap::Server::dispatchCallInternal(unsigned short, capnp::CallContext<capnp::AnyPointer, capnp::AnyPointer>) /home/src/bitcoin/build/src/ipc/libmultiprocess/include/mp/proxy.capnp.c++:602:9 (bitcoin-node+0x17ad47e) #4 mp::ThreadMap::Server::dispatchCall(unsigned long, unsigned short, capnp::CallContext<capnp::AnyPointer, capnp::AnyPointer>) /home/src/bitcoin/build/src/ipc/libmultiprocess/include/mp/proxy.capnp.c++:591:14 (bitcoin-node+0x17ad2f1) #5 virtual thunk to mp::ThreadMap::Server::dispatchCall(unsigned long, unsigned short, capnp::CallContext<capnp::AnyPointer, capnp::AnyPointer>) /home/src/bitcoin/build/src/ipc/libmultiprocess/include/mp/proxy.capnp.c++ (bitcoin-node+0x17ad5f7) #6 capnp::LocalClient::callInternal(unsigned long, unsigned short, capnp::CallContextHook&) <null> (libcapnp-rpc.so.1.2.0+0x747d6) (BuildId: 98f819a103310afbd8f791a0c80d203a4d1b9791) #7 mp::EventLoop::loop() /home/src/bitcoin/build/src/ipc/libmultiprocess/./ipc/libmultiprocess/src/mp/proxy.cpp:244:68 (bitcoin-node+0x17b135e) #8 ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()::operator()() const /home/src/bitcoin/build/src/ipc/./ipc/capnp/protocol.cpp:136:21 (bitcoin-node+0xe516e4) #9 void std::__invoke_impl<void, ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>(std::__invoke_other, ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()&&) /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/invoke.h:61:14 (bitcoin-node+0xe514a2) #10 std::__invoke_result<ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>::type std::__invoke<ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>(ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()&&) /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/invoke.h:96:14 (bitcoin-node+0xe513a2) #11 void std::thread::_Invoker<std::tuple<ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>>::_M_invoke<0ul>(std::_Index_tuple<0ul>) /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/std_thread.h:301:13 (bitcoin-node+0xe5130a) #12 std::thread::_Invoker<std::tuple<ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>>::operator()() /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/std_thread.h:308:11 (bitcoin-node+0xe51272) #13 std::thread::_State_impl<std::thread::_Invoker<std::tuple<ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>>>::_M_run() /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/std_thread.h:253:13 (bitcoin-node+0xe5106a) #14 execute_native_thread_routine <null> (libstdc++.so.6+0xed063) SUMMARY: ThreadSanitizer: data race (/home/src/bitcoin/build/bin/bitcoin-node+0x1c1196) in operator delete(void*) ================== ================== WARNING: ThreadSanitizer: data race (pid=86917) Write of size 8 at 0x723c00034cb0 by thread T2: #0 operator delete(void*, unsigned long) <null> (bitcoin-node+0x1c1616) #1 kj::_::AttachmentPromiseNode<kj::_::Tuple<kj::Own<capnp::LocalClient, std::nullptr_t>, kj::Own<capnp::CallContextHook, std::nullptr_t>>>::~AttachmentPromiseNode() <null> (libcapnp-rpc.so.1.2.0+0x75c5f) (BuildId: 98f819a103310afbd8f791a0c80d203a4d1b9791) #2 mp::EventLoop::loop() /home/src/bitcoin/build/src/ipc/libmultiprocess/./ipc/libmultiprocess/src/mp/proxy.cpp:244:68 (bitcoin-node+0x17b135e) #3 ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()::operator()() const /home/src/bitcoin/build/src/ipc/./ipc/capnp/protocol.cpp:136:21 (bitcoin-node+0xe516e4) #4 void std::__invoke_impl<void, ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>(std::__invoke_other, ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()&&) /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/invoke.h:61:14 (bitcoin-node+0xe514a2) #5 std::__invoke_result<ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>::type std::__invoke<ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>(ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()&&) /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/invoke.h:96:14 (bitcoin-node+0xe513a2) #6 void std::thread::_Invoker<std::tuple<ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>>::_M_invoke<0ul>(std::_Index_tuple<0ul>) /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/std_thread.h:301:13 (bitcoin-node+0xe5130a) #7 std::thread::_Invoker<std::tuple<ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>>::operator()() /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/std_thread.h:308:11 (bitcoin-node+0xe51272) #8 std::thread::_State_impl<std::thread::_Invoker<std::tuple<ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>>>::_M_run() /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/std_thread.h:253:13 (bitcoin-node+0xe5106a) #9 execute_native_thread_routine <null> (libstdc++.so.6+0xed063) Previous read of size 8 at 0x723c00034cb0 by thread T13: #0 capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>::getParams() /nix/store/8xjrdb1y9ng6w6yknzg9h6fkxd3sb824-capnproto-1.2.0/include/capnp/capability.h:1129:16 (bitcoin-node+0x1213722) #1 void mp::PassField<mp::Accessor<mp::mining_fields::Options, 17>, node::BlockWaitOptions, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall> const&, mp::TypeList<>>(mp::Priority<0>, mp::TypeList<node::BlockWaitOptions>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall> const&, mp::TypeList<>&&) /home/src/bitcoin/build/src/ipc/./ipc/libmultiprocess/include/mp/proxy-types.h:296:54 (bitcoin-node+0x12209f5) #2 decltype(auto) mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::TypeList<node::BlockWaitOptions>>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::TypeList<node::BlockWaitOptions>) const /home/src/bitcoin/build/src/ipc/./ipc/libmultiprocess/include/mp/proxy-types.h:549:16 (bitcoin-node+0x12208ea) #3 std::enable_if<std::is_same<decltype(mp::Accessor<mp::mining_fields::Context, 17>::get(fp1.call_context.getParams())), mp::Context::Reader>::value, kj::Promise<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>::CallContext>>::type mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>>, mp::TypeList<node::BlockWaitOptions>>(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>> const&, mp::TypeList<node::BlockWaitOptions>&&)::'lambda'(mp::CancelMonitor&)::operator()(mp::CancelMonitor&)::'lambda1'()::operator()() const /home/src/bitcoin/build/src/ipc/./ipc/libmultiprocess/include/mp/type-context.h:138:21 (bitcoin-node+0x1220534) #4 kj::Maybe<kj::Exception> kj::runCatchingExceptions<std::enable_if<std::is_same<decltype(mp::Accessor<mp::mining_fields::Context, 17>::get(fp1.call_context.getParams())), mp::Context::Reader>::value, kj::Promise<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>::CallContext>>::type mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>>, mp::TypeList<node::BlockWaitOptions>>(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>> const&, mp::TypeList<node::BlockWaitOptions>&&)::'lambda'(mp::CancelMonitor&)::operator()(mp::CancelMonitor&)::'lambda1'()>(mp::Accessor<mp::mining_fields::Context, 17>&&) /nix/store/8xjrdb1y9ng6w6yknzg9h6fkxd3sb824-capnproto-1.2.0/include/kj/exception.h:371:5 (bitcoin-node+0x121d6a1) #5 std::enable_if<std::is_same<decltype(mp::Accessor<mp::mining_fields::Context, 17>::get(fp1.call_context.getParams())), mp::Context::Reader>::value, kj::Promise<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>::CallContext>>::type mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>>, mp::TypeList<node::BlockWaitOptions>>(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>> const&, mp::TypeList<node::BlockWaitOptions>&&)::'lambda'(mp::CancelMonitor&)::operator()(mp::CancelMonitor&) /home/src/bitcoin/build/src/ipc/./ipc/libmultiprocess/include/mp/type-context.h:138:21 (bitcoin-node+0x121cc6c) #6 kj::Promise<mp::Accessor<mp::mining_fields::Context, 17>> mp::ProxyServer<mp::Thread>::post<capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>, std::enable_if<std::is_same<decltype(mp::Accessor<mp::mining_fields::Context, 17>::get(fp1.call_context.getParams())), mp::Context::Reader>::value, kj::Promise<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>::CallContext>>::type mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>>, mp::TypeList<node::BlockWaitOptions>>(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>> const&, mp::TypeList<node::BlockWaitOptions>&&)::'lambda'(mp::CancelMonitor&)>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&&)::'lambda'()::operator()()::'lambda'()::operator()()::'lambda0'()::operator()() const /home/src/bitcoin/build/src/ipc/./ipc/libmultiprocess/include/mp/proxy-io.h:720:100 (bitcoin-node+0x121c4d3) #7 kj::Maybe<kj::Exception> kj::runCatchingExceptions<kj::Promise<mp::Accessor<mp::mining_fields::Context, 17>> mp::ProxyServer<mp::Thread>::post<capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>, std::enable_if<std::is_same<decltype(mp::Accessor<mp::mining_fields::Context, 17>::get(fp1.call_context.getParams())), mp::Context::Reader>::value, kj::Promise<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>::CallContext>>::type mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>>, mp::TypeList<node::BlockWaitOptions>>(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>> const&, mp::TypeList<node::BlockWaitOptions>&&)::'lambda'(mp::CancelMonitor&)>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&&)::'lambda'()::operator()()::'lambda'()::operator()()::'lambda0'()>(mp::Accessor<mp::mining_fields::Context, 17>&&) /nix/store/8xjrdb1y9ng6w6yknzg9h6fkxd3sb824-capnproto-1.2.0/include/kj/exception.h:371:5 (bitcoin-node+0x121b371) #8 kj::Promise<mp::Accessor<mp::mining_fields::Context, 17>> mp::ProxyServer<mp::Thread>::post<capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>, std::enable_if<std::is_same<decltype(mp::Accessor<mp::mining_fields::Context, 17>::get(fp1.call_context.getParams())), mp::Context::Reader>::value, kj::Promise<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>::CallContext>>::type mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>>, mp::TypeList<node::BlockWaitOptions>>(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>> const&, mp::TypeList<node::BlockWaitOptions>&&)::'lambda'(mp::CancelMonitor&)>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&&)::'lambda'()::operator()()::'lambda'()::operator()() /home/src/bitcoin/build/src/ipc/./ipc/libmultiprocess/include/mp/proxy-io.h:720:48 (bitcoin-node+0x121aeb2) #9 kj::Function<void ()>::Impl<kj::Promise<mp::Accessor<mp::mining_fields::Context, 17>> mp::ProxyServer<mp::Thread>::post<capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>, std::enable_if<std::is_same<decltype(mp::Accessor<mp::mining_fields::Context, 17>::get(fp1.call_context.getParams())), mp::Context::Reader>::value, kj::Promise<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>::CallContext>>::type mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>>, mp::TypeList<node::BlockWaitOptions>>(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 18>, mp::ServerCall>> const&, mp::TypeList<node::BlockWaitOptions>&&)::'lambda'(mp::CancelMonitor&)>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&&)::'lambda'()::operator()()::'lambda'()>::operator()() /nix/store/8xjrdb1y9ng6w6yknzg9h6fkxd3sb824-capnproto-1.2.0/include/kj/function.h:142:14 (bitcoin-node+0x121acfa) #10 kj::Function<void ()>::operator()() /nix/store/8xjrdb1y9ng6w6yknzg9h6fkxd3sb824-capnproto-1.2.0/include/kj/function.h:119:12 (bitcoin-node+0xe8e221) #11 void mp::Unlock<mp::Lock, kj::Function<void ()>&>(mp::Lock&, kj::Function<void ()>&) /home/src/bitcoin/build/src/ipc/./ipc/libmultiprocess/include/mp/util.h:210:5 (bitcoin-node+0xe8dd31) #12 void mp::Waiter::wait<mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const::'lambda'()>(mp::Lock&, mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const::'lambda'())::'lambda'()::operator()() const /home/src/bitcoin/build/src/ipc/libmultiprocess/./ipc/libmultiprocess/include/mp/proxy-io.h:371:17 (bitcoin-node+0x17b827f) #13 void std::condition_variable::wait<void mp::Waiter::wait<mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const::'lambda'()>(mp::Lock&, mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const::'lambda'())::'lambda'()>(std::unique_lock<std::mutex>&, mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const::'lambda'()) /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/condition_variable:104:10 (bitcoin-node+0x17b815e) #14 void mp::Waiter::wait<mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const::'lambda'()>(mp::Lock&, mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const::'lambda'()) /home/src/bitcoin/build/src/ipc/libmultiprocess/./ipc/libmultiprocess/include/mp/proxy-io.h:362:14 (bitcoin-node+0x17b7fdf) #15 mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const /home/src/bitcoin/build/src/ipc/libmultiprocess/./ipc/libmultiprocess/src/mp/proxy.cpp:423:34 (bitcoin-node+0x17b7e39) #16 void std::__invoke_impl<void, mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0>(std::__invoke_other, mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0&&) /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/invoke.h:61:14 (bitcoin-node+0x17b7ba2) #17 std::__invoke_result<mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0>::type std::__invoke<mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0>(mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0&&) /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/invoke.h:96:14 (bitcoin-node+0x17b7aa2) #18 void std::thread::_Invoker<std::tuple<mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0>>::_M_invoke<0ul>(std::_Index_tuple<0ul>) /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/std_thread.h:301:13 (bitcoin-node+0x17b7a0a) #19 std::thread::_Invoker<std::tuple<mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0>>::operator()() /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/std_thread.h:308:11 (bitcoin-node+0x17b7972) #20 std::thread::_State_impl<std::thread::_Invoker<std::tuple<mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0>>>::_M_run() /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/std_thread.h:253:13 (bitcoin-node+0x17b745a) #21 execute_native_thread_routine <null> (libstdc++.so.6+0xed063) Thread T2 'b-capnp-loop' (tid=86923, running) created by main thread at: #0 pthread_create <null> (bitcoin-node+0x13a395) #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State>>, void (*)()) <null> (libstdc++.so.6+0xed138) #2 ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*) /home/src/bitcoin/build/src/ipc/./ipc/capnp/protocol.cpp:127:25 (bitcoin-node+0xe50b88) #3 ipc::capnp::(anonymous namespace)::CapnpProtocol::listen(int, char const*, interfaces::Init&) /home/src/bitcoin/build/src/ipc/./ipc/capnp/protocol.cpp:87:9 (bitcoin-node+0xe503b2) #4 ipc::(anonymous namespace)::IpcImpl::listenAddress(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&) /home/src/bitcoin/build/src/ipc/./ipc/interfaces.cpp:111:21 (bitcoin-node+0xe475c5) #5 AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) /home/src/bitcoin/build/src/./init.cpp:1483:22 (bitcoin-node+0x1f8a67) #6 AppInit(node::NodeContext&) /home/src/bitcoin/build/src/./bitcoind.cpp:242:43 (bitcoin-node+0x1c42fd) #7 main /home/src/bitcoin/build/src/./bitcoind.cpp:283:10 (bitcoin-node+0x1c2a95) Thread T13 (tid=86942, running) created by thread T2 at: #0 pthread_create <null> (bitcoin-node+0x13a395) #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State>>, void (*)()) <null> (libstdc++.so.6+0xed138) #2 mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>) /home/src/bitcoin/build/src/ipc/libmultiprocess/./ipc/libmultiprocess/src/mp/proxy.cpp:416:17 (bitcoin-node+0x17b3821) #3 mp::ThreadMap::Server::dispatchCallInternal(unsigned short, capnp::CallContext<capnp::AnyPointer, capnp::AnyPointer>) /home/src/bitcoin/build/src/ipc/libmultiprocess/include/mp/proxy.capnp.c++:602:9 (bitcoin-node+0x17ad47e) #4 mp::ThreadMap::Server::dispatchCall(unsigned long, unsigned short, capnp::CallContext<capnp::AnyPointer, capnp::AnyPointer>) /home/src/bitcoin/build/src/ipc/libmultiprocess/include/mp/proxy.capnp.c++:591:14 (bitcoin-node+0x17ad2f1) #5 virtual thunk to mp::ThreadMap::Server::dispatchCall(unsigned long, unsigned short, capnp::CallContext<capnp::AnyPointer, capnp::AnyPointer>) /home/src/bitcoin/build/src/ipc/libmultiprocess/include/mp/proxy.capnp.c++ (bitcoin-node+0x17ad5f7) #6 capnp::LocalClient::callInternal(unsigned long, unsigned short, capnp::CallContextHook&) <null> (libcapnp-rpc.so.1.2.0+0x747d6) (BuildId: 98f819a103310afbd8f791a0c80d203a4d1b9791) #7 mp::EventLoop::loop() /home/src/bitcoin/build/src/ipc/libmultiprocess/./ipc/libmultiprocess/src/mp/proxy.cpp:244:68 (bitcoin-node+0x17b135e) #8 ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()::operator()() const /home/src/bitcoin/build/src/ipc/./ipc/capnp/protocol.cpp:136:21 (bitcoin-node+0xe516e4) #9 void std::__invoke_impl<void, ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>(std::__invoke_other, ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()&&) /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/invoke.h:61:14 (bitcoin-node+0xe514a2) #10 std::__invoke_result<ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>::type std::__invoke<ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>(ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()&&) /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/invoke.h:96:14 (bitcoin-node+0xe513a2) #11 void std::thread::_Invoker<std::tuple<ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>>::_M_invoke<0ul>(std::_Index_tuple<0ul>) /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/std_thread.h:301:13 (bitcoin-node+0xe5130a) #12 std::thread::_Invoker<std::tuple<ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>>::operator()() /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/std_thread.h:308:11 (bitcoin-node+0xe51272) #13 std::thread::_State_impl<std::thread::_Invoker<std::tuple<ipc::capnp::(anonymous namespace)::CapnpProtocol::startLoop(char const*)::'lambda'()>>>::_M_run() /nix/store/kzq78n13l8w24jn8bx4djj79k5j717f1-gcc-14.3.0/include/c++/14.3.0/bits/std_thread.h:253:13 (bitcoin-node+0xe5106a) #14 execute_native_thread_routine <null> (libstdc++.so.6+0xed063) SUMMARY: ThreadSanitizer: data race (/home/src/bitcoin/build/bin/bitcoin-node+0x1c1616) in operator delete(void*, unsigned long) ================== ThreadSanitizer: reported 2 warnings
1 parent 0a22425 commit 4f42fc4

File tree

3 files changed

+17
-1
lines changed

3 files changed

+17
-1
lines changed

include/mp/proxy-io.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ struct ServerInvokeContext : InvokeContext
4747

4848
ProxyServer& proxy_server;
4949
CallContext& call_context;
50+
//! Lock used to protect access to call_context.getParams() data when the
51+
//! IPC method executes asynchronously (not on the event loop thread). This
52+
//! lock is needed in case there is a cancellation or disconnect during
53+
//! execution that could cause the parameters to be deleted from the event
54+
//! loop thread while they are accessed from the execution thread.
55+
Lock* params_lock{nullptr};
5056
int req;
5157
//! If the IPC method executes asynchronously (not on the event loop thread)
5258
//! and the IPC call was cancelled by the client, or cancelled by a

include/mp/proxy-types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,9 @@ struct ServerCall
445445
template <typename ServerContext, typename... Args>
446446
decltype(auto) invoke(ServerContext& server_context, TypeList<>, Args&&... args) const
447447
{
448+
// Release params lock since call_context.getParams() will no longer be
449+
// called after this point.
450+
if (server_context.params_lock) server_context.params_lock->m_lock.unlock();
448451
return ProxyServerMethodTraits<typename decltype(server_context.call_context.getParams())::Reads>::invoke(
449452
server_context,
450453
std::forward<Args>(args)...);

include/mp/type-context.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,20 @@ auto PassField(Priority<1>, TypeList<>, ServerContext& server_context, const Fn&
9191
auto& request_threads = thread_context.request_threads;
9292
ConnThread request_thread;
9393
bool inserted;
94+
Mutex params_mutex;
95+
Lock params_lock{params_mutex};
96+
server_context.params_lock = &params_lock;
9497
server.m_context.loop->sync([&] {
9598
// Detect request being cancelled before or while it executes.
9699
if (cancel_monitor.m_cancelled) MP_LOG(*server.m_context.loop, Log::Raise) << "IPC server request #" << req << " cancelled before it could be executed";
97100
assert(!cancel_monitor.m_on_cancel);
98-
cancel_monitor.m_on_cancel = [&server, &server_context, req]() {
101+
cancel_monitor.m_on_cancel = [&server, &server_context, &params_mutex, req]() {
99102
MP_LOG(*server.m_context.loop, Log::Error) << "IPC server request #" << req << " cancelled while executing.";
100103
server_context.cancelled = true;
104+
// Wait for params_mutex to be released by the
105+
// execution thread before returning to the event
106+
// loop and letting parameters to be deleted.
107+
Lock{params_mutex};
101108
};
102109

103110
// Update requests_threads map if not cancelled.

0 commit comments

Comments
 (0)