Bitcoin Core UBSan failure for interfaces::Echo #125

issue Sjors opened this issue on January 13, 2025
  1. Sjors commented at 10:47 AM on January 13, 2025: member

    When running ipc_tests.cpp with the UBSan fix from #121, it still fails:

    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: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>'
    ...
    SUMMARY: UndefinedBehaviorSanitizer: dynamic-type-mismatch /usr/local/include/mp/proxy.h:95:45 in 
    
  2. ryanofsky commented at 8:22 PM on January 13, 2025: collaborator

    CI failure from this was posted in https://github.com/bitcoin/bitcoin/pull/30975#issuecomment-2583641138: https://github.com/bitcoin/bitcoin/actions/runs/12715313812/job/35447236983?pr=30975#step:7:5079

    This is helpful because it includes a new stack trace. Based on https://github.com/bitcoin/bitcoin/commit/e35f64041750aef1502b011599a2bddab8efec9c checkout with libmultiprocess version 5b8119284760ef0e945b709cfaad0e5370e3677f:

    [test/ipc_/usr/local/include/mp/proxy.h:95:45: runtime error: downcast of address 0x5060000392c0 which does not point to an object of type 'ProxyClient<Interface>' (aka 'ProxyClient<ipc::capnp::messages::Echo>')
    0x5060000392c0: note: object is of type 'mp::ProxyClientBase<ipc::capnp::messages::Echo, interfaces::Echo>'
     03 00 00 00  88 14 5d dc 2a 56 00 00  38 14 5d dc 2a 56 00 00  e8 50 03 00 70 50 00 00  e0 50 03 00
                  ^~~~~~~~~~~~~~~~~~~~~~~
                  vptr for 'mp::ProxyClientBase<ipc::capnp::messages::Echo, interfaces::Echo>'
        [#0](/bitcoin-core-multiprocess/0/) 0x562adaebf03e in mp::ProxyClientBase<ipc::capnp::messages::Echo, interfaces::Echo>::self() /usr/local/include/mp/proxy.h:95:45
        [#1](/bitcoin-core-multiprocess/1/) 0x562adaebf03e in mp::ProxyClientBase<ipc::capnp::messages::Echo, interfaces::Echo>::ProxyClientBase(ipc::capnp::messages::Echo::Client, mp::Connection*, bool)::'lambda0'()::operator()() const /usr/local/include/mp/proxy-io.h:415:9
        [#2](/bitcoin-core-multiprocess/2/) 0x562adaebd9be in std::function<void ()>::operator()() const /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_function.h:591:9
        [#3](/bitcoin-core-multiprocess/3/) 0x562adaebd9be in mp::ProxyClientBase<ipc::capnp::messages::Echo, interfaces::Echo>::~ProxyClientBase() /usr/local/include/mp/proxy-io.h:441:9
        [#4](/bitcoin-core-multiprocess/4/) 0x562adaefd6fe in mp::ProxyClient<ipc::capnp::messages::Echo>::~ProxyClient() /home/runner/work/_temp/ci/scratch/build-x86_64-pc-linux-gnu/src/ipc/capnp/echo.capnp.proxy-types.c++:7:57
        [#5](/bitcoin-core-multiprocess/5/) 0x562adadf3b9b in std::default_delete<interfaces::Echo>::operator()(interfaces::Echo*) const /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/unique_ptr.h:99:2
        [#6](/bitcoin-core-multiprocess/6/) 0x562adadf3b9b in std::__uniq_ptr_impl<interfaces::Echo, std::default_delete<interfaces::Echo>>::reset(interfaces::Echo*) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/unique_ptr.h:211:4
        [#7](/bitcoin-core-multiprocess/7/) 0x562adadf3b9b in std::unique_ptr<interfaces::Echo, std::default_delete<interfaces::Echo>>::reset(interfaces::Echo*) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/unique_ptr.h:509:7
        [#8](/bitcoin-core-multiprocess/8/) 0x562adadf3b9b in IpcSocketPairTest() /home/runner/work/_temp/ci/scratch/build-x86_64-pc-linux-gnu/src/./test/ipc_test.cpp:144:17
        [#9](/bitcoin-core-multiprocess/9/) 0x562ad9e71dc0 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
        [#10](/bitcoin-core-multiprocess/10/) 0x562ad9e7102f 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
        [#11](/bitcoin-core-multiprocess/11/) 0x562ad89dc93d in boost::function0<void>::operator()() const /usr/include/boost/function/function_template.hpp:771:14
        [#12](/bitcoin-core-multiprocess/12/) 0x562ad8a5d3d8 in boost::detail::forward::operator()() /usr/include/boost/test/impl/execution_monitor.ipp:1395:32
        [#13](/bitcoin-core-multiprocess/13/) 0x562ad8a5d3d8 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
        [#14](/bitcoin-core-multiprocess/14/) 0x562ad8a56ecd in boost::function0<int>::operator()() const /usr/include/boost/function/function_template.hpp:771:14
        [#15](/bitcoin-core-multiprocess/15/) 0x562ad894260c 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
        [#16](/bitcoin-core-multiprocess/16/) 0x562ad894260c in boost::execution_monitor::catch_signals(boost::function<int ()> const&) /usr/include/boost/test/impl/execution_monitor.ipp:910:16
        [#17](/bitcoin-core-multiprocess/17/) 0x562ad8942b1d in boost::execution_monitor::execute(boost::function<int ()> const&) /usr/include/boost/test/impl/execution_monitor.ipp:1308:16
        [#18](/bitcoin-core-multiprocess/18/) 0x562ad893b1a8 in boost::execution_monitor::vexecute(boost::function<void ()> const&) /usr/include/boost/test/impl/execution_monitor.ipp:1404:5
        [#19](/bitcoin-core-multiprocess/19/) 0x562ad893b1a8 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
        [#20](/bitcoin-core-multiprocess/20/) 0x562ad899f195 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
        [#21](/bitcoin-core-multiprocess/21/) 0x562ad899e0a4 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/) 0x562ad899e0a4 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
        [#23](/bitcoin-core-multiprocess/23/) 0x562ad89395fb in boost::unit_test::framework::run(unsigned long, bool) /usr/include/boost/test/impl/framework.ipp:1722:29
        [#24](/bitcoin-core-multiprocess/24/) 0x562ad89682c0 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
        [#25](/bitcoin-core-multiprocess/25/) 0x7f80fa67e1c9  (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 6d64b17fbac799e68da7ebd9985ddf9b5cb375e6)
        [#26](/bitcoin-core-multiprocess/26/) 0x7f80fa67e28a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 6d64b17fbac799e68da7ebd9985ddf9b5cb375e6)
        [#27](/bitcoin-core-multiprocess/27/) 0x562ad88344c4 in _start (/home/runner/work/_temp/ci/scratch/build-x86_64-pc-linux-gnu/src/test/test_bitcoin+0x13414c4) (BuildId: e1386a5013133aba2702db4ec3dc7a50fba57dcb)
    
    SUMMARY: UndefinedBehaviorSanitizer: dynamic-type-mismatch /usr/local/include/mp/proxy.h:95:45 
    

    I didn't figure out what's going on yet, but there are some differences between this stack trace and the last one https://github.com/chaincodelabs/libmultiprocess/pull/121#issuecomment-2512190620, the main one seeming to be that this crash happens in the ProxyClient<messages::Echo> destructor instead of the ProxyClient<messages::Init> constructor like last time

  3. ryanofsky commented at 8:59 PM on January 13, 2025: collaborator

    Looking into this more, it is basically the same bug that's fixed in #121 but happening in a different place. In both cases a ProxyClientBase pointer is cast to a ProxyClient pointer at a bad time when the ProxyClient object is only partially constructed.

    The fix in #121 works by delaying ProxyClient::construct() calls that were happening in ProxyClientBase constructor to happen later in the ProxyClient constructor instead.

    A new fix will be required to move ProxyClient::destroy() calls triggered in the ProxyClientBase destructor to happen earlier in the ProxyClient destructor. It looks like the fix should be similar and not too complicated.

  4. ryanofsky referenced this in commit 2f0122121f on Jan 15, 2025
  5. ryanofsky commented at 6:12 PM on January 15, 2025: collaborator

    I think #126 should fix this, so could be worth testing. I think I might try to implement a different fix instead because this fix adds more complexity, and maybe it is possible to go in opposite direction, but it's not clear yet.

  6. ryanofsky referenced this in commit f22c2c0fa4 on Jan 15, 2025
  7. ryanofsky referenced this in commit 63a39d4c9b on Jan 15, 2025
  8. ryanofsky closed this on Jan 16, 2025

  9. ryanofsky referenced this in commit 3b2617b3e5 on Jan 16, 2025
  10. bitcoin-core locked this on Jan 16, 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