shutdown bugfix: Prevent segfault in server if connection is broken during long function call #118

pull ryanofsky wants to merge 2 commits into bitcoin-core:master from ryanofsky:pr/segwait changing 2 files +32 −3
  1. ryanofsky commented at 8:10 PM on October 8, 2024: collaborator

    Fix issue where if a client disconnects in the middle of a long running IPC method call, the server will segfault when the method eventually returns.

    This issue was reported tdb3 in https://github.com/bitcoin/bitcoin/pull/31003#pullrequestreview-2349619672 with a stack trace showing where the crash happens in the PassField mp.Context overload while calling request_threads.erase.

  2. bugfix: prevent double delete segfault in server if client disconnects during method call
    Fix issue where if a client disconnects in the middle of a long running IPC
    method call, the server will segfault when the method eventually returns.
    
    This behavior was reported by tdb3 in
    https://github.com/bitcoin/bitcoin/pull/31003#pullrequestreview-2349619672
    including a stack trace showing where the crash happens in the PassField
    mp.Context overload while calling request_threads.erase.
    9d11042772
  3. ryanofsky commented at 8:11 PM on October 8, 2024: collaborator

    Originally posted by @tdb3 in https://github.com/bitcoin/bitcoin/pull/31003#pullrequestreview-2349619672:

    I did, however, run into a repeatable segfault that appears to be occurring with bitcoin_node when running bitcoin-mine (which calls waitFeesChanged()), interrupting bitcoin-mine (CTRL-C while it waits for change), then generating a block (with bitcoin-cli). Feels a bit DoSsy. Could be something I'm overlooking/messed up on my end. Not sure. Please request more details if needed. bitcoin-node gdb trace

    2024-10-06T17:11:13Z [ipc] {bitcoin-node-67256/b-capnp-loop-67260} IPC server post request  [#4](/bitcoin-core-multiprocess/4/) {bitcoin-node-67256/b-capnp-loop-67291 (from bitcoin-mine-67289/bitcoin-mine-67289)}
    
    Thread 3 "b-capnp-loop" received signal SIGPIPE, Broken pipe.
    [Switching to Thread 0x7ffff6dfe6c0 (LWP 67260)]
    __GI___writev (iovcnt=2, iov=0x7ffff6dfc6c0, fd=31) at ../sysdeps/unix/sysv/linux/writev.c:26
    26      ../sysdeps/unix/sysv/linux/writev.c: No such file or directory.
    (gdb) c
    Continuing.
    2024-10-06T17:11:23Z [ipc] {bitcoin-node-67256/b-capnp-loop-67260} IPC server: socket disconnected.
    2024-10-06T17:11:23Z [ipc] {bitcoin-node-67256/b-capnp-loop-67260} IPC server destroy N2mp11ProxyServerIN3ipc5capnp8messages4InitEEE
    2024-10-06T17:11:26Z CreateNewBlock(): block weight: 888 txs: 0 fees: 0 sigops 400
    2024-10-06T17:11:26Z Saw new header hash=7227516712ea6f9f8fb24763a3ba8eeb3ecee4d0640f1227a41320b66cf6605a height=111
    2024-10-06T17:11:26Z UpdateTip: new best=7227516712ea6f9f8fb24763a3ba8eeb3ecee4d0640f1227a41320b66cf6605a height=111 version=0x20000000 log2_work=7.807355 tx=118 date='2024-10-06T17:11:26Z' progress=1.000000 cache=0.3MiB(8txo)
    2024-10-06T17:11:26Z [test] AddToWallet 20a7fcb543900a59764414197f5aaf36e85454dc916c4049c4fe4f0eb31381e4  new Confirmed (block=7227516712ea6f9f8fb24763a3ba8eeb3ecee4d0640f1227a41320b66cf6605a, height=111, index=0)
    
    Thread 30 "b-capnp-loop" received signal SIGSEGV, Segmentation fault.
    [Switching to Thread 0x7fff9d7fa6c0 (LWP 67291)]
    0x00007ffff7cc0193 in std::_Rb_tree_rebalance_for_erase(std::_Rb_tree_node_base*, std::_Rb_tree_node_base&) ()
       from /lib/x86_64-linux-gnu/libstdc++.so.6
    (gdb) bt
    [#0](/bitcoin-core-multiprocess/0/)  0x00007ffff7cc0193 in std::_Rb_tree_rebalance_for_erase(std::_Rb_tree_node_base*, std::_Rb_tree_node_base&) ()
       from /lib/x86_64-linux-gnu/libstdc++.so.6
    [#1](/bitcoin-core-multiprocess/1/)  0x0000555555a889d9 in std::_Rb_tree<mp::Connection*, std::pair<mp::Connection* const, mp::ProxyClient<mp::Thread> >, std::_Select1st<std::pair<mp::Connection* const, mp::ProxyClient<mp::Thread> > >, std::less<mp::Connection*>, std::allocator<std::pair<mp::Connection* const, mp::ProxyClient<mp::Thread> > > >::_M_erase_aux (__position=..., this=<optimized out>)
        at /usr/include/c++/12/bits/stl_tree.h:2488
    [#2](/bitcoin-core-multiprocess/2/)  std::_Rb_tree<mp::Connection*, std::pair<mp::Connection* const, mp::ProxyClient<mp::Thread> >, std::_Select1st<std::pair<mp::Connection* const, mp::ProxyClient<mp::Thread> > >, std::less<mp::Connection*>, std::allocator<std::pair<mp::Connection* const, mp::ProxyClient<mp::Thread> > > >::erase[abi:cxx11](std::_Rb_tree_iterator<std::pair<mp::Connection* const, mp::ProxyClient<mp::Thread> > >) (__position=..., this=<optimized out>) at /usr/include/c++/12/bits/stl_tree.h:1209
    [#3](/bitcoin-core-multiprocess/3/)  std::map<mp::Connection*, mp::ProxyClient<mp::Thread>, std::less<mp::Connection*>, std::allocator<std::pair<mp::Connection* const, mp::ProxyClient<mp::Thread> > > >::erase[abi:cxx11](std::_Rb_tree_iterator<std::pair<mp::Connection* const, mp::ProxyClient<mp::Thread> > >) (__position=..., this=<optimized out>) at /usr/include/c++/12/bits/stl_map.h:1086
    [#4](/bitcoin-core-multiprocess/4/)  mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > >, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > > >(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >&, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > > const&, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > >&&)::{lambda()#1}::operator()()::{lambda()#2}::operator()() const (__closure=<synthetic pointer>)
        at ../../../depends/x86_64-pc-linux-gnu/include/mp/proxy-types.h:156
    [#5](/bitcoin-core-multiprocess/5/)  mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > >, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > > >(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >&, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > > const&, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > >&&)::{lambda()#1}::operator()()::{lambda()#2}::operator()() const (__closure=<synthetic pointer>)
        at ../../../depends/x86_64-pc-linux-gnu/include/mp/proxy-types.h:156
    [#6](/bitcoin-core-multiprocess/6/)  kj::_::Deferred<mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > >, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > > >(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >&, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > > const&, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > >&&)::{lambda()#1}::operator()()::{lambda()#2}>::run() (this=0x7fff9d7f9250)
        at ../../../depends/x86_64-pc-linux-gnu/include/kj/common.h:2001
    [#7](/bitcoin-core-multiprocess/7/)  kj::_::Deferred<mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fi--Type <RET> for more, q to quit, c to continue without paging--
    elds::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > >, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > > >(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >&, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > > const&, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > >&&)::{lambda()#1}::operator()()::{lambda()#2}>::~Deferred() (this=0x7fff9d7f9250, __in_chrg=<optimized out>)
        at ../../../depends/x86_64-pc-linux-gnu/include/kj/common.h:1990
    [#8](/bitcoin-core-multiprocess/8/)  mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > >, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > > >(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >&, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > > const&, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > >&&)::{lambda()#1}::operator()() (__closure=0x7fffe801b640) at ../../../depends/x86_64-pc-linux-gnu/include/mp/proxy-types.h:161
    [#9](/bitcoin-core-multiprocess/9/)  0x0000555555d5145f in mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::{lambda()#1}::operator()() const ()
    [#10](/bitcoin-core-multiprocess/10/) 0x00007ffff7cd44a3 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
    [#11](/bitcoin-core-multiprocess/11/) 0x00007ffff7aa8144 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
    [#12](/bitcoin-core-multiprocess/12/) 0x00007ffff7b287dc in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
    (gdb) 
    
  4. ryanofsky referenced this in commit 965838b65f on Oct 8, 2024
  5. ryanofsky referenced this in commit 41d94fa0c3 on Oct 8, 2024
  6. tdb3 commented at 9:41 PM on October 8, 2024: none

    Still encountering a segfault. Trace below.

    2024-10-08T21:37:33Z [ipc] {bitcoin-node-72507/b-capnp-loop-72511} IPC server: socket disconnected.
    2024-10-08T21:37:33Z [ipc] {bitcoin-node-72507/b-capnp-loop-72511} IPC server destroy N2mp11ProxyServerIN3ipc5capnp8messages4InitEEE
    2024-10-08T21:37:38Z CreateNewBlock(): block weight: 888 txs: 0 fees: 0 sigops 400
    2024-10-08T21:37:38Z Saw new header hash=08c6cb824e73a5ff8db130c814ff064a4cb13a04179041159b70b71c7ae8e9cd height=111
    2024-10-08T21:37:38Z UpdateTip: new best=08c6cb824e73a5ff8db130c814ff064a4cb13a04179041159b70b71c7ae8e9cd height=111 version=0x20000000 log2_work=7.807355 tx=118 date='2024-10-08T21:37:38Z' progress=1.000000 cache=0.3MiB(8txo)
    2024-10-08T21:37:38Z [test] AddToWallet b953fe9cf081f57db02556a1fa9b0e0d5a626f2ce1202585c9ae23859f39481f  new Confirmed (block=08c6cb824e73a5ff8db130c814ff064a4cb13a04179041159b70b71c7ae8e9cd, height=111, index=0)
    
    Thread 30 "b-capnp-loop" received signal SIGSEGV, Segmentation fault.
    [Switching to Thread 0x7fff9d7fa6c0 (LWP 72541)]
    0x00007ffff7cc0193 in std::_Rb_tree_rebalance_for_erase(std::_Rb_tree_node_base*, std::_Rb_tree_node_base&) () from /lib/x86_64-linux-gnu/libstdc++.so.6
    (gdb) bt
    [#0](/bitcoin-core-multiprocess/0/)  0x00007ffff7cc0193 in std::_Rb_tree_rebalance_for_erase(std::_Rb_tree_node_base*, std::_Rb_tree_node_base&) () from /lib/x86_64-linux-gnu/libstdc++.so.6
    [#1](/bitcoin-core-multiprocess/1/)  0x0000555555a889d9 in std::_Rb_tree<mp::Connection*, std::pair<mp::Connection* const, mp::ProxyClient<mp::Thread> >, std::_Select1st<std::pair<mp::Connection* const, mp::ProxyClient<mp::Thread> > >, std::less<mp::Connection*>, std::allocator<std::pair<mp::Connection* const, mp::ProxyClient<mp::Thread> > > >::_M_erase_aux (__position=..., this=<optimized out>) at /usr/include/c++/12/bits/stl_tree.h:2488
    [#2](/bitcoin-core-multiprocess/2/)  std::_Rb_tree<mp::Connection*, std::pair<mp::Connection* const, mp::ProxyClient<mp::Thread> >, std::_Select1st<std::pair<mp::Connection* const, mp::ProxyClient<mp::Thread> > >, std::less<mp::Connection*>, std::allocator<std::pair<mp::Connection* const, mp::ProxyClient<mp::Thread> > > >::erase[abi:cxx11](std::_Rb_tree_iterator<std::pair<mp::Connection* const, mp::ProxyClient<mp::Thread> > >) (__position=..., this=<optimized out>)
        at /usr/include/c++/12/bits/stl_tree.h:1209
    [#3](/bitcoin-core-multiprocess/3/)  std::map<mp::Connection*, mp::ProxyClient<mp::Thread>, std::less<mp::Connection*>, std::allocator<std::pair<mp::Connection* const, mp::ProxyClient<mp::Thread> > > >::erase[abi:cxx11](std::_Rb_tree_iterator<std::pair<mp::Connection* const, mp::ProxyClient<mp::Thread> > >) (__position=..., 
        this=<optimized out>) at /usr/include/c++/12/bits/stl_map.h:1086
    [#4](/bitcoin-core-multiprocess/4/)  mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > >, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > > >(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >&, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > > const&, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > >&&)::{lambda()#1}::operator()()::{lambda()#2}::operator()() const (__closure=<synthetic pointer>)
        at ../../../depends/x86_64-pc-linux-gnu/include/mp/proxy-types.h:156
    [#5](/bitcoin-core-multiprocess/5/)  mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > >, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > > >(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >&, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > > const&, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > >&&)::{lambda()#1}::operator()()::{lambda()#2}::operator()() const (__closure=<synthetic pointer>)
        at ../../../depends/x86_64-pc-linux-gnu/include/mp/proxy-types.h:156
    [#6](/bitcoin-core-multiprocess/6/)  kj::_::Deferred<mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > >, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > > >(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >&, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > > const&, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > >&&)::{lambda()#1}::operator()()::{lambda()#2}>::run() (this=0x7fff9d7f9250)
        at ../../../depends/x86_64-pc-linux-gnu/include/kj/common.h:2001
    [#7](/bitcoin-core-multiprocess/7/)  kj::_::Deferred<mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > >, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > > >(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >&, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > > const&, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > >&&)::{lambda()#1}::operator()()::{lambda()#2}>::~Deferred() (this=0x7fff9d7f9250, __in_chrg=<optimized out>)
        at ../../../depends/x86_64-pc-linux-gnu/include/kj/common.h:1990
    --Type <RET> for more, q to quit, c to continue without paging--
    [#8](/bitcoin-core-multiprocess/8/)  mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > >, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > > >(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >&, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > > const&, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > >&&)::{lambda()#1}::operator()() (__closure=0x7fffe8017e40) at ../../../depends/x86_64-pc-linux-gnu/include/mp/proxy-types.h:161
    [#9](/bitcoin-core-multiprocess/9/)  0x0000555555d5145f in mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::{lambda()#1}::operator()() const ()
    [#10](/bitcoin-core-multiprocess/10/) 0x00007ffff7cd44a3 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
    [#11](/bitcoin-core-multiprocess/11/) 0x00007ffff7aa8144 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
    [#12](/bitcoin-core-multiprocess/12/) 0x00007ffff7b287dc in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
    (gdb) 
    
  7. ryanofsky force-pushed on Oct 15, 2024
  8. ryanofsky commented at 11:21 AM on October 16, 2024: collaborator

    Following the instructions from https://github.com/bitcoin/bitcoin/pull/31003#pullrequestreview-2349619672 (complicated but steps to reproduce were described very clearly!) I was able to reproduce the original segfault and a new segfault after applying the current fix 7f1d33f81c48585cba6ea6c20afc1cd64bea2772

    Will debug, but stack trace is:

    [#0](/bitcoin-core-multiprocess/0/)  std::operator== (__x=..., __y=...) at /nix/store/rqga421d43q40blrrgmiw820p01a4nba-gcc-13.2.0/include/c++/13.2.0/bits/std_thread.h:330
    [#1](/bitcoin-core-multiprocess/1/)  mp::EventLoop::post(std::function<void ()> const&) (this=0x0, fn=...) at /home/russ/work/mp/src/mp/proxy.cpp:219
    [#2](/bitcoin-core-multiprocess/2/)  0x000055ac4fc57dc4 in mp::EventLoop::sync<mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > >, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > > >(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >&, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > > const&, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > >&&)::{lambda()#1}::operator()()::{lambda()#3}::operator()() const::{lambda()#1}>(mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > >, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > > >(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >&, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > > const&, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > >&&)::{lambda()#1}::operator()()::{lambda()#3}::operator()() const::{lambda()#1}&&) (this=0x0, callable=...) at /home/russ/work/mp/build/prefix/include/mp/proxy-io.h:155
    [#3](/bitcoin-core-multiprocess/3/)  0x000055ac4fc57d44 in mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > >, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > > >(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >&, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > > const&, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > >&&)::{lambda()#1}::operator()()::{lambda()#3}::operator()() const (this=0x7f1c4affc7e8) at /home/russ/work/mp/build/prefix/include/mp/proxy-types.h:171
    [#4](/bitcoin-core-multiprocess/4/)  0x000055ac4fc52267 in kj::runCatchingExceptions<mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > >, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > > >(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >&, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > > const&, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > >&&)::{lambda()#1}::operator()()::{lambda()#3}>(mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > >, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > > >(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >&, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > > const&, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > >&&)::{lambda()#1}::operator()()::{lambda()#3}&&) (func=...) at /nix/store/0rvzw1dahhd1h8qyhyxmwgr2l745fn3a-capnproto-1.0.2/include/kj/exception.h:371
    [#5](/bitcoin-core-multiprocess/5/)  0x000055ac4fc51db9 in mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > >, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > > >(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >&, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > > const&, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > >&&)::{lambda()#1}::operator()() (this=0x7f1c8001c4d0) at /home/russ/work/mp/build/prefix/include/mp/proxy-types.h:171
    [#6](/bitcoin-core-multiprocess/6/)  0x000055ac4fc51afe in mp::AsyncCallable<mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > >, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > > >(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >&, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > > const&, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > >&&)::{lambda()#1}>::operator()() const (this=0x7f1c8001c440) at /home/russ/work/mp/build/prefix/include/mp/util.h:189
    [#7](/bitcoin-core-multiprocess/7/)  0x000055ac4fc51aa6 in std::__invoke_impl<void, mp::AsyncCallable<mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > >, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > > >(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >&, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > > const&, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > >&&)::{lambda()#1}>&>(std::__invoke_other, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >&&) (__f=...) at /nix/store/rqga421d43q40blrrgmiw820p01a4nba-gcc-13.2.0/include/c++/13.2.0/bits/invoke.h:61
    [#8](/bitcoin-core-multiprocess/8/)  0x000055ac4fc519f6 in std::__invoke_r<void, mp::AsyncCallable<mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > >, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > > >(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >&, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > > const&, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > >&&)::{lambda()#1}>&>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >&&) (__fn=...) at /nix/store/rqga421d43q40blrrgmiw820p01a4nba-gcc-13.2.0/include/c++/13.2.0/bits/invoke.h:111
    [#9](/bitcoin-core-multiprocess/9/)  0x000055ac4fc5182e in std::_Function_handler<void (), mp::AsyncCallable<mp::PassField<mp::Accessor<mp::mining_fields::Context, 17>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > >, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > > >(mp::Priority<1>, mp::TypeList<>, mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitFeesChangedParams, ipc::capnp::messages::Mining::WaitFeesChangedResults> >&, mp::ServerField<1, mp::Accessor<mp::mining_fields::CurrentTip, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::FeeThreshold, 1>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Options, 17>, mp::ServerField<1, mp::Accessor<mp::mining_fields::Timeout, 1>, mp::ServerRet<mp::Accessor<mp::mining_fields::Result, 2>, mp::ServerCall> > > > > const&, mp::TypeList<uint256, long, node::BlockCreateOptions const&, std::chrono::duration<double, std::ratio<1l, 1000l> > >&&)::{lambda()#1}> >::_M_invoke(std::_Any_data const&) (__functor=...)
        at /nix/store/rqga421d43q40blrrgmiw820p01a4nba-gcc-13.2.0/include/c++/13.2.0/bits/std_function.h:290
    [#10](/bitcoin-core-multiprocess/10/) 0x000055ac5016f360 in std::function<void ()>::operator()() const (this=<optimized out>) at /nix/store/rqga421d43q40blrrgmiw820p01a4nba-gcc-13.2.0/include/c++/13.2.0/bits/std_function.h:591
    [#11](/bitcoin-core-multiprocess/11/) mp::Waiter::wait<mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const::{lambda()#1}>(std::unique_lock<std::mutex>&, mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const::{lambda()#1})::{lambda()#1}::operator()() const (this=<optimized out>) at /home/russ/work/mp/include/mp/proxy-io.h:261
    [#12](/bitcoin-core-multiprocess/12/) std::condition_variable::wait<mp::Waiter::wait<mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const::{lambda()#1}>(std::unique_lock<std::mutex>&, mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const::{lambda()#1})::{lambda()#1}>(std::unique_lock<std::mutex>&, mp::Waiter::wait<mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const::{lambda()#1}>(std::unique_lock<std::mutex>&, mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const::{lambda()#1})::{lambda()#1}) (this=0x7f1c44001278, __lock=..., __p=...) at /nix/store/rqga421d43q40blrrgmiw820p01a4nba-gcc-13.2.0/include/c++/13.2.0/condition_variable:104
    [#13](/bitcoin-core-multiprocess/13/) mp::Waiter::wait<mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const::{lambda()#1}>(std::unique_lock<std::mutex>&, mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const::{lambda()#1}) (this=0x7f1c44001250, lock=..., pred=...) at /home/russ/work/mp/include/mp/proxy-io.h:251
    [#14](/bitcoin-core-multiprocess/14/) mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0::operator()() const (this=<optimized out>) at /home/russ/work/mp/src/mp/proxy.cpp:364
    [#15](/bitcoin-core-multiprocess/15/) 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&&) (__f=...) at /nix/store/rqga421d43q40blrrgmiw820p01a4nba-gcc-13.2.0/include/c++/13.2.0/bits/invoke.h:61
    [#16](/bitcoin-core-multiprocess/16/) 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&&) (__fn=...) at /nix/store/rqga421d43q40blrrgmiw820p01a4nba-gcc-13.2.0/include/c++/13.2.0/bits/invoke.h:96
    [#17](/bitcoin-core-multiprocess/17/) 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>) (this=<optimized out>)
        at /nix/store/rqga421d43q40blrrgmiw820p01a4nba-gcc-13.2.0/include/c++/13.2.0/bits/std_thread.h:292
    [#18](/bitcoin-core-multiprocess/18/) std::thread::_Invoker<std::tuple<mp::ProxyServer<mp::ThreadMap>::makeThread(capnp::CallContext<mp::ThreadMap::MakeThreadParams, mp::ThreadMap::MakeThreadResults>)::$_0> >::operator()() (this=<optimized out>)
        at /nix/store/rqga421d43q40blrrgmiw820p01a4nba-gcc-13.2.0/include/c++/13.2.0/bits/std_thread.h:299
    [#19](/bitcoin-core-multiprocess/19/) 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() (this=<optimized out>)
        at /nix/store/rqga421d43q40blrrgmiw820p01a4nba-gcc-13.2.0/include/c++/13.2.0/bits/std_thread.h:244
    [#20](/bitcoin-core-multiprocess/20/) 0x00007f1c90ee8683 in execute_native_thread_routine () from /nix/store/agp6lqznayysqvqkx4k1ggr8n1rsyi8c-gcc-13.2.0-lib/lib/libstdc++.so.6
    [#21](/bitcoin-core-multiprocess/21/) 0x00007f1c90bc0383 in start_thread () from /nix/store/1rm6sr6ixxzipv5358x0cmaw8rs84g2j-glibc-2.38-44/lib/libc.so.6
    [#22](/bitcoin-core-multiprocess/22/) 0x00007f1c90c4300c in clone3 () from /nix/store/1rm6sr6ixxzipv5358x0cmaw8rs84g2j-glibc-2.38-44/lib/libc.so.6
    
  9. bugfix: prevent null pointer dereference in server if client disconnects during method call
    This an imperfect workaround for a crash that can be triggered if a client
    disconnects in the middle of a long running IPC call. The workaround results in
    memory leak but avoids a crash. This can be improved later, and more details
    are in a code comment.
    196e6fcdbc
  10. ryanofsky force-pushed on Oct 16, 2024
  11. ryanofsky commented at 3:53 PM on October 16, 2024: collaborator

    The second crash turned out to be more complicated to fix than the first one, so just pushing a workaround for now that avoids the crash but results in a small memory leak. I will open a separate PR with a more complete fix. I should also add a test for this issue making sure deleting server-side Connection* during an ongoing method call does not cause crashes.

  12. ryanofsky merged this on Oct 16, 2024
  13. ryanofsky closed this on Oct 16, 2024

  14. ryanofsky referenced this in commit 90b405516f on Oct 16, 2024
  15. fanquake referenced this in commit 563c4d2926 on Oct 21, 2024
  16. janus referenced this in commit eb4d842678 on Jan 19, 2025
  17. ryanofsky referenced this in commit 7455fc0e37 on Jul 1, 2025
  18. ryanofsky referenced this in commit c6f7fdf173 on Jul 1, 2025
  19. ryanofsky commented at 12:35 PM on July 10, 2025: collaborator

    The second crash turned out to be more complicated to fix than the first one, so just pushing a workaround for now that avoids the crash but results in a small memory leak. I will open a separate PR with a more complete fix.

    Note: this is done now. The second commit of this PR was reverted in #186. The workaround was no longer needed after #160, and it was actually causing intermittent test hangs in the new unit test added in #160 disconnecting the client during an IPC call.

Contributors

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin-core/libmultiprocess. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-20 18:30 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me