macos “Broken pipe” exceptions during tests #162

issue ryanofsky openend this issue on February 10, 2025
  1. ryanofsky commented at 9:32 pm on February 10, 2025: collaborator

    On macos there is error output running test_bitcoin -t ipc_tests that looks like:

    0capnp/rpc.c++:3666: error: exception = (unknown):-1: failed: std::exception: (unknown):-1: failed: std::exception: kj/async-io-unix.c++:778: disconnected: ::writev(fd, iov.begin(), iov.size()): Broken pipe; iovTotal = 80; iov.size() = 2
    

    followed by lists of stack addresses, repeated may times throughout the test.

    It’s not really clear what causes these errors, but they seem harmless, and might have to do with capnproto not really having a clean disconnect procedure (according to https://groups.google.com/g/capnproto/c/T7Yjcwi1z2Y). But regardless, libmultiprocess probably should be doing something to catch and handle these errors rather than letting them go to stderr.

    These errors happens using capnp 1.1.0 installed from homebrew, and a not very informative stack trace that just shows a write failing looks like:

     0* thread [#2](/bitcoin-core-multiprocess/2/), stop reason = breakpoint 1.1
     1  * frame [#0](/bitcoin-core-multiprocess/0/): 0x00007ff80921defa libc++abi.dylib`__cxa_throw
     2    frame [#1](/bitcoin-core-multiprocess/1/): 0x00000001025b6f8a libkj.1.1.0.dylib`kj::ExceptionCallback::RootExceptionCallback::onRecoverableException(kj::Exception&&) + 90
     3    frame [#2](/bitcoin-core-multiprocess/2/): 0x00000001025b1fa6 libkj.1.1.0.dylib`kj::_::Debug::Fault::~Fault() + 190
     4    frame [#3](/bitcoin-core-multiprocess/3/): 0x000000010285e666 libkj-async.1.1.0.dylib`kj::(anonymous namespace)::AsyncStreamFd::writeInternal(kj::ArrayPtr<unsigned char const>, kj::ArrayPtr<kj::ArrayPtr<unsigned char const> const>, kj::ArrayPtr<int const>) + 612
     5    frame [#4](/bitcoin-core-multiprocess/4/): 0x000000010285ca62 libkj-async.1.1.0.dylib`kj::(anonymous namespace)::AsyncStreamFd::write(kj::ArrayPtr<kj::ArrayPtr<unsigned char const> const>) + 90
     6    frame [#5](/bitcoin-core-multiprocess/5/): 0x000000010285cc10 libkj-async.1.1.0.dylib`non-virtual thunk to kj::(anonymous namespace)::AsyncStreamFd::write(kj::ArrayPtr<kj::ArrayPtr<unsigned char const> const>) + 18
     7    frame [#6](/bitcoin-core-multiprocess/6/): 0x00000001026486d6 libcapnp-rpc.1.1.0.dylib`capnp::writeMessages(kj::AsyncOutputStream&, kj::ArrayPtr<kj::ArrayPtr<kj::ArrayPtr<capnp::word const> const> >) + 360
     8    frame [#7](/bitcoin-core-multiprocess/7/): 0x0000000102649f8c libcapnp-rpc.1.1.0.dylib`capnp::BufferedMessageStream::writeMessages(kj::ArrayPtr<kj::ArrayPtr<kj::ArrayPtr<capnp::word const> const> >) + 22
     9    frame [#8](/bitcoin-core-multiprocess/8/): 0x0000000102648adb libcapnp-rpc.1.1.0.dylib`capnp::MessageStream::writeMessages(kj::ArrayPtr<capnp::MessageAndFds>) + 315
    10    frame [#9](/bitcoin-core-multiprocess/9/): 0x000000010269f591 libcapnp-rpc.1.1.0.dylib`capnp::TwoPartyVatNetwork::OutgoingMessageImpl::send()::'lambda'()::operator()() const::'lambda'()::operator()() const + 301
    11    frame [#10](/bitcoin-core-multiprocess/10/): 0x000000010269fdbc libcapnp-rpc.1.1.0.dylib`kj::_::TransformPromiseNode<kj::Promise<void>, kj::_::Void, capnp::TwoPartyVatNetwork::OutgoingMessageImpl::send()::'lambda'()::operator()() const::'lambda'(), kj::_::PropagateException>::getImpl(kj::_::ExceptionOrValue&) + 586
    12    frame [#11](/bitcoin-core-multiprocess/11/): 0x0000000102815aac libkj-async.1.1.0.dylib`kj::_::TransformPromiseNodeBase::get(kj::_::ExceptionOrValue&) + 32
    13    frame [#12](/bitcoin-core-multiprocess/12/): 0x00000001028165a8 libkj-async.1.1.0.dylib`kj::_::ChainPromiseNode::fire() + 120
    14    frame [#13](/bitcoin-core-multiprocess/13/): 0x0000000102816bfa libkj-async.1.1.0.dylib`non-virtual thunk to kj::_::ChainPromiseNode::fire() + 18
    15    frame [#14](/bitcoin-core-multiprocess/14/): 0x0000000102813e24 libkj-async.1.1.0.dylib`kj::EventLoop::turn() + 100
    16    frame [#15](/bitcoin-core-multiprocess/15/): 0x00000001028145d4 libkj-async.1.1.0.dylib`kj::_::waitImpl(kj::Own<kj::_::PromiseNode, kj::_::PromiseDisposer>&&, kj::_::ExceptionOrValue&, kj::WaitScope&, kj::SourceLocation) + 518
    17    frame [#16](/bitcoin-core-multiprocess/16/): 0x00000001011f36d9 test_bitcoin`kj::Promise<unsigned long>::wait(this=<unavailable>, waitScope=<unavailable>, location=(fileName = "ipc/libmultiprocess/src/mp/proxy.cpp", function = "loop", lineNumber = 196, columnNumber = 35)) at async-inl.h:1357:3 [opt]
    18    frame [#17](/bitcoin-core-multiprocess/17/): 0x00000001011f30e9 test_bitcoin`mp::EventLoop::loop(this=0x000070000e9a1e20) at proxy.cpp:196:68 [opt]
    19    frame [#18](/bitcoin-core-multiprocess/18/): 0x0000000100f9cd01 test_bitcoin`void* std::__1::__thread_proxy[abi:ne190107]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, IpcPipeTest()::$_0> >(void*) [inlined] IpcPipeTest(this=<unavailable>)::$_0::operator()() const at ipc_test.cpp:75:14 [opt]
    20    frame [#19](/bitcoin-core-multiprocess/19/): 0x0000000100f9c887 test_bitcoin`void* std::__1::__thread_proxy[abi:ne190107]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, IpcPipeTest()::$_0> >(void*) [inlined] decltype(__f=<unavailable>)::$_0>()()) std::__1::__invoke[abi:ne190107]<IpcPipeTest()::$_0>(IpcPipeTest()::$_0&&) at invoke.h:149:25 [opt]
    21    frame [#20](/bitcoin-core-multiprocess/20/): 0x0000000100f9c887 test_bitcoin`void* std::__1::__thread_proxy[abi:ne190107]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, IpcPipeTest()::$_0> >(void*) [inlined] _ZNSt3__116__thread_executeB8ne190107INS_10unique_ptrINS_15__thread_structENS_14default_deleteIS2_EEEEZ11IpcPipeTestvE3$_0JETpTnmJEEEvRNS_5tupleIJT_T0_DpT1_EEENS_15__tuple_indicesIJXspT2_EEEE(__t=<unavailable>, (null)=<unavailable>) at thread.h:192:3 [opt]
    22    frame [#21](/bitcoin-core-multiprocess/21/): 0x0000000100f9c887 test_bitcoin`void* std::__1::__thread_proxy[abi:ne190107]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, IpcPipeTest()::$_0> >(__vp=<unavailable>) at thread.h:201:3 [opt]
    23    frame [#22](/bitcoin-core-multiprocess/22/): 0x00007ff8092621d3 libsystem_pthread.dylib`_pthread_start + 125
    24    frame [#23](/bitcoin-core-multiprocess/23/): 0x00007ff80925dbd3 libsystem_pthread.dylib`thread_start + 15
    

    Stack trace was obtained with lldb:

    0lldb -- src/test/test_bitcoin -t ipc_tests
    1breakpoint set -E c++
    2run
    3bt
    
  2. ryanofsky commented at 11:17 am on August 23, 2025: collaborator
    This should be resolved now with disconnection exception handling improved in 56fff76f940b5be7dc41a2532195becf8b15230e and other disconnection handling improvements and tests in #160
  3. ryanofsky closed this on Aug 23, 2025


ryanofsky


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: 2025-12-04 19:30 UTC

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