ProxyClientBase: avoid static_cast to partially constructed object #121

pull ryanofsky wants to merge 1 commits into bitcoin-core:master from ryanofsky:pr/ucon changing 2 files +2 −2
  1. ryanofsky commented at 5:08 PM on December 2, 2024: collaborator

    ProxyClientBase constructor was trying to call ProxyClient::construct() method before ProxyClient object had been fully constructed. This is causing a UBSAN error reported:

    that looks like:

    include/mp/proxy.h:95:45: runtime error: downcast of address 0x50600002bdc0 which does not point to an object of type 'ProxyClient<Interface>' (aka 'ProxyClient<ipc::capnp::messages::Init>')
    0x50600002bdc0: note: object is of type 'mp::ProxyClientBase<ipc::capnp::messages::Init, interfaces::Init>'
    
  2. ProxyClientBase: avoid static_cast to partially constructed object
    ProxyClientBase constructor was trying to call ProxyClient::construct() method before ProxyClient object had been fully constructed yet. This was causing
    a UBSAN error reported:
    https://github.com/bitcoin/bitcoin/actions/runs/11970857809/job/33374462331?pr=30975
    https://github.com/bitcoin/bitcoin/pull/30975#issuecomment-2511204009
    
    that looked like:
    
    include/mp/proxy.h:95:45: runtime error: downcast of address 0x50600002bdc0 which does not point to an object of type 'ProxyClient<Interface>' (aka 'ProxyClient<ipc::capnp::messages::Init>')
    0x50600002bdc0: note: object is of type 'mp::ProxyClientBase<ipc::capnp::messages::Init, interfaces::Init>'
    5b81192847
  3. ryanofsky commented at 5:09 PM on December 2, 2024: collaborator

    A more complete stack trace from https://github.com/bitcoin/bitcoin/actions/runs/11970857809/job/33374462331?pr=30975 is:

    2024-11-22T10:38:22.317815Z/usr/local/include/mp/proxy.h:95:45: runtime error: downcast of address 0x50600002bdc0 which does not point to an object of type 'ProxyClient<Interface>' (aka 'ProxyClient<ipc::capnp::messages::Init>')
    0x50600002bdc0: note: object is of type 'mp::ProxyClientBase<ipc::capnp::messages::Init, interfaces::Init>'
     00 00 00 00  18 04 23 9a 4a 56 00 00  08 03 23 9a 4a 56 00 00  68 17 01 00 b0 50 00 00  60 17 01 00
                  ^~~~~~~~~~~~~~~~~~~~~~~
                  vptr for 'mp::ProxyClientBase<ipc::capnp::messages::Init, interfaces::Init>'
        [#0](/bitcoin-core-multiprocess/0/) 0x564a98a7b7fa in mp::ProxyClientBase<ipc::capnp::messages::Init, interfaces::Init>::self() /usr/local/include/mp/proxy.h:95:45
        [#1](/bitcoin-core-multiprocess/1/) 0x564a98a7b7fa in mp::ProxyClientBase<ipc::capnp::messages::Init, interfaces::Init>::ProxyClientBase(ipc::capnp::messages::Init::Client, mp::Connection*, bool) /usr/local/include/mp/proxy-io.h:435:5
        [#2](/bitcoin-core-multiprocess/2/) 0x564a98a75cac in mp::ProxyClientCustom<ipc::capnp::messages::Init, interfaces::Init>::ProxyClientCustom(ipc::capnp::messages::Init::Client, mp::Connection*, bool) /usr/local/include/mp/proxy.h:106:45
        [#3](/bitcoin-core-multiprocess/3/) 0x564a98a75cac in mp::ProxyClient<ipc::capnp::messages::Init>::ProxyClient(ipc::capnp::messages::Init::Client, mp::Connection*, bool) /home/runner/work/_temp/ci/scratch/build-x86_64-pc-linux-gnu/src/ipc/capnp/init.capnp.proxy.h:73:30
        [#4](/bitcoin-core-multiprocess/4/) 0x564a98a75cac in std::__detail::_MakeUniq<mp::ProxyClient<ipc::capnp::messages::Init>>::__single_object std::make_unique<mp::ProxyClient<ipc::capnp::messages::Init>, ipc::capnp::messages::Init::Client, mp::Connection*, bool>(ipc::capnp::messages::Init::Client&&, mp::Connection*&&, bool&&) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/unique_ptr.h:1070:34
        [#5](/bitcoin-core-multiprocess/5/) 0x564a98a74cf6 in std::unique_ptr<mp::ProxyClient<ipc::capnp::messages::Init>, std::default_delete<mp::ProxyClient<ipc::capnp::messages::Init>>> mp::ConnectStream<ipc::capnp::messages::Init>(mp::EventLoop&, int) /usr/local/include/mp/proxy-io.h:577:12
        [#6](/bitcoin-core-multiprocess/6/) 0x564a98a72c26 in ipc::capnp::(anonymous namespace)::CapnpProtocol::connect(int, char const*) /home/runner/work/_temp/ci/scratch/build-x86_64-pc-linux-gnu/src/ipc/./ipc/capnp/protocol.cpp:54:16
        [#7](/bitcoin-core-multiprocess/7/) 0x564a989e0d13 in IpcSocketPairTest() /home/runner/work/_temp/ci/scratch/build-x86_64-pc-linux-gnu/src/./test/ipc_test.cpp:141:61
        [#8](/bitcoin-core-multiprocess/8/) 0x564a97a43380 in ipc_tests::ipc_tests::test_method() /home/runner/work/_temp/ci/scratch/build-x86_64-pc-linux-gnu/src/test/./test/ipc_tests.cpp:15:5
        [#9](/bitcoin-core-multiprocess/9/) 0x564a97a425ef in ipc_tests::ipc_tests_invoker() /home/runner/work/_temp/ci/scratch/build-x86_64-pc-linux-gnu/src/test/./test/ipc_tests.cpp:12:1
        [#10](/bitcoin-core-multiprocess/10/) 0x564a965e731d in boost::function0<void>::operator()() const /usr/include/boost/function/function_template.hpp:771:14
        [#11](/bitcoin-core-multiprocess/11/) 0x564a96667db8 in boost::detail::forward::operator()() /usr/include/boost/test/impl/execution_monitor.ipp:1395:32
        [#12](/bitcoin-core-multiprocess/12/) 0x564a96667db8 in boost::detail::function::function_obj_invoker0<boost::detail::forward, int>::invoke(boost::detail::function::function_buffer&) /usr/include/boost/function/function_template.hpp:137:18
        [#13](/bitcoin-core-multiprocess/13/) 0x564a966618ad in boost::function0<int>::operator()() const /usr/include/boost/function/function_template.hpp:771:14
        [#14](/bitcoin-core-multiprocess/14/) 0x564a9654cfec in int boost::detail::do_invoke<boost::shared_ptr<boost::detail::translator_holder_base>, boost::function<int ()>>(boost::shared_ptr<boost::detail::translator_holder_base> const&, boost::function<int ()> const&) /usr/include/boost/test/impl/execution_monitor.ipp:308:30
        [#15](/bitcoin-core-multiprocess/15/) 0x564a9654cfec in boost::execution_monitor::catch_signals(boost::function<int ()> const&) /usr/include/boost/test/impl/execution_monitor.ipp:910:16
        [#16](/bitcoin-core-multiprocess/16/) 0x564a9654d4fd in boost::execution_monitor::execute(boost::function<int ()> const&) /usr/include/boost/test/impl/execution_monitor.ipp:1308:16
        [#17](/bitcoin-core-multiprocess/17/) 0x564a96545b88 in boost::execution_monitor::vexecute(boost::function<void ()> const&) /usr/include/boost/test/impl/execution_monitor.ipp:1404:5
        [#18](/bitcoin-core-multiprocess/18/) 0x564a96545b88 in boost::unit_test::unit_test_monitor_t::execute_and_translate(boost::function<void ()> const&, unsigned long) /usr/include/boost/test/impl/unit_test_monitor.ipp:49:9
        [#19](/bitcoin-core-multiprocess/19/) 0x564a965a9b75 in boost::unit_test::framework::state::execute_test_tree(unsigned long, unsigned long, boost::unit_test::framework::state::random_generator_helper const*) /usr/include/boost/test/impl/framework.ipp:815:44
        [#20](/bitcoin-core-multiprocess/20/) 0x564a965a8a84 in boost::unit_test::framework::state::execute_test_tree(unsigned long, unsigned long, boost::unit_test::framework::state::random_generator_helper const*) /usr/include/boost/test/impl/framework.ipp:784:58
        [#21](/bitcoin-core-multiprocess/21/) 0x564a965a8a84 in boost::unit_test::framework::state::execute_test_tree(unsigned long, unsigned long, boost::unit_test::framework::state::random_generator_helper const*) /usr/include/boost/test/impl/framework.ipp:784:58
        [#22](/bitcoin-core-multiprocess/22/) 0x564a96543fdb in boost::unit_test::framework::run(unsigned long, bool) /usr/include/boost/test/impl/framework.ipp:1722:29
        [#23](/bitcoin-core-multiprocess/23/) 0x564a96572ca0 in boost::unit_test::unit_test_main(boost::unit_test::test_suite* (*)(int, char**), int, char**) /usr/include/boost/test/impl/unit_test_main.ipp:250:9
        [#24](/bitcoin-core-multiprocess/24/) 0x7f99693bf1c9  (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 6d64b17fbac799e68da7ebd9985ddf9b5cb375e6)
        [#25](/bitcoin-core-multiprocess/25/) 0x7f99693bf28a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 6d64b17fbac799e68da7ebd9985ddf9b5cb375e6)
        [#26](/bitcoin-core-multiprocess/26/) 0x564a9643eea4 in _start (/home/runner/work/_temp/ci/scratch/build-x86_64-pc-linux-gnu/src/test/test_bitcoin+0x1355ea4) (BuildId: 5aa0be89931561f87bfc4b03f135b8264e316e4e)
    
  4. sedited approved
  5. sedited commented at 8:45 PM on January 5, 2025: collaborator

    lgtm ACK 5b8119284760ef0e945b709cfaad0e5370e3677f

    Makes sense to instantiate the custom implementation first before calling construct.

  6. Sjors commented at 5:58 PM on January 10, 2025: member

    Testing on Bitcoin Core CI: https://github.com/bitcoin/bitcoin/pull/30975/commits/93f7f307a522abd45066cb392f79447e47ab887e https://github.com/bitcoin/bitcoin/pull/30975#issuecomment-2583641138

    Which fails, but it seems to happen at a different place (at Echo instead of Init), so perhaps it's a completely different issue.

  7. Sjors commented at 10:45 AM on January 13, 2025: member

    I reproduced the original failure locally on macOS 15.2, by installing libmultiprocess from master @ abe254b9734f2e2b220d1456de195532d6e6ac1e (no depends).

    export UBSAN_OPTIONS="suppressions=$(pwd)/test/sanitizer_suppressions/ubsan:print_stacktrace=1:halt_on_error=1:report_error_type=1"
    cmake -B build -DWITH_MULTIPROCESS=ON -DSANITIZERS=undefined
    cmake --build build
    
    build/src/test/test_bitcoin --run_test=ipc_tests --log_level=all | grep -v disabled
    ...
    test/ipc_test.cpp:133: info: check socketpair(1, 1, 0, fds) == 0 has passed
    /usr/local/include/mp/proxy.h:95:45: runtime error: downcast of address 0x600001d74480 which does not point to an object of type 'ProxyClient<Interface>' (aka 'ProxyClient<ipc::capnp::messages::Init>')
    0x600001d74480: note: object is of type 'mp::ProxyClientBase<ipc::capnp::messages::Init, interfaces::Init>'
    ...
    SUMMARY: UndefinedBehaviorSanitizer: dynamic-type-mismatch /usr/local/include/mp/proxy.h:95:45 in 
    

    I then installed libmultiprocess from this PR, deleted the Bitcoin Core build dir and did the above again.

    The test now makes it line 143, so I'd say the original issue is fixed.

    test/ipc_test.cpp:133: info: check socketpair(1, 1, 0, fds) == 0 has passed
    test/ipc_test.cpp:143: info: check remote_echo->echo("echo test") == "echo test" has passed
    /usr/local/include/mp/proxy.h:95:45: runtime error: downcast of address 0x600001f28700 which does not point to an object of type 'ProxyClient<Interface>' (aka 'ProxyClient<ipc::capnp::messages::Echo>')
    0x600001f28700: note: object is of type 'mp::ProxyClientBase<ipc::capnp::messages::Echo, interfaces::Echo>'
    

    I'll open a new issue for the new failure.

  8. ryanofsky merged this on Jan 13, 2025
  9. ryanofsky closed this on Jan 13, 2025

  10. ryanofsky referenced this in commit 2f0122121f on Jan 15, 2025
  11. ryanofsky referenced this in commit f22c2c0fa4 on Jan 15, 2025
  12. ryanofsky referenced this in commit 63a39d4c9b on Jan 15, 2025
  13. ryanofsky referenced this in commit 3b2617b3e5 on Jan 16, 2025
  14. Sjors referenced this in commit b298856792 on Jan 16, 2025
  15. Sjors referenced this in commit 2f7dc7d665 on Jan 16, 2025
  16. Sjors referenced this in commit d7013a805b on Jan 17, 2025
  17. Sjors referenced this in commit 42673bf471 on Jan 17, 2025
  18. Sjors referenced this in commit 0ca9eef7a5 on Jan 20, 2025
  19. Sjors referenced this in commit a3be4d6731 on Jan 22, 2025
  20. Sjors referenced this in commit b804b6c4b8 on Jan 23, 2025
  21. Sjors referenced this in commit 0325502620 on Jan 27, 2025
  22. Sjors referenced this in commit 57e60735cf on Jan 27, 2025
  23. Sjors referenced this in commit 71be9377ee on Jan 27, 2025
  24. ryanofsky referenced this in commit 90b116bd70 on Jan 27, 2025
  25. ryanofsky referenced this in commit ada8c1a5b8 on Jan 27, 2025
  26. ryanofsky referenced this in commit 2221c8814d on Jan 27, 2025
  27. Sjors referenced this in commit b66fe2fc03 on Jan 28, 2025
  28. fanquake referenced this in commit ad2f9324c6 on Jan 29, 2025
  29. janus referenced this in commit 311822f35f on Sep 1, 2025
  30. bitcoin-core locked this on Jan 13, 2026

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