Skip to content

refactor: memcpy to std::ranges::copy to work around ubsan warn#305

Open
maflcko wants to merge 1 commit into
bitcoin-core:masterfrom
maflcko:2607-ubsan-memcpy-null-warn
Open

refactor: memcpy to std::ranges::copy to work around ubsan warn#305
maflcko wants to merge 1 commit into
bitcoin-core:masterfrom
maflcko:2607-ubsan-memcpy-null-warn

Conversation

@maflcko

@maflcko maflcko commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Using std::ranges::copy from the C++ standard library has a few benefits here:

  • It has the additional benefit of being a bit more type safe and document any needed cast explicitly. (No cast is needed here)
  • It has defined semantics for empty source ranges.

This should also fix bitcoin/bitcoin#35118 (comment)

@DrahtBot

DrahtBot commented Jul 9, 2026

Copy link
Copy Markdown

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Reviews

See the guideline and AI policy for information on the review process.

Type Reviewers
ACK Sjors

If your review is incorrectly listed, please copy-paste <!--meta-tag:bot-skip--> into the comment that the bot should ignore.

@maflcko maflcko force-pushed the 2607-ubsan-memcpy-null-warn branch from d4b028b to fac7b9b Compare July 9, 2026 18:06
@maflcko

maflcko commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Failure should look roughly like:

# cmake --build build-ubsan-gcc --target tests && UBSAN_OPTIONS="print_stacktrace=1:halt_on_error=0:report_error_type=1" ./build-ubsan-gcc/test/mptest 
ninja: no work to do.
[ TEST ] listen_tests.cpp:214: ListenConnections accepts incoming connections
[ PASS ] listen_tests.cpp:214: ListenConnections accepts incoming connections (18477 μs)
[ TEST ] listen_tests.cpp:224: ListenConnections enforces a local connection limit
[ PASS ] listen_tests.cpp:224: ListenConnections enforces a local connection limit (18818 μs)
[ TEST ] listen_tests.cpp:262: ListenConnections accepts multiple connections
[ PASS ] listen_tests.cpp:262: ListenConnections accepts multiple connections (9224 μs)
[ TEST ] spawn_tests.cpp:46: SpawnProcess does not run callback in child
[ PASS ] spawn_tests.cpp:46: SpawnProcess does not run callback in child (138059 μs)
[ TEST ] test.cpp:143: Call FooInterface methods
/tmp/tmp.sFxQecaMfz/git_dir/include/mp/type-data.h:36:11: runtime error: null pointer passed as argument 2, which is declared to never be null
    #0 0x61583eb6352f in _ZN2mp16CustomBuildFieldISt6vectorIcSaIcEES3_NS_11StructFieldINS_8AccessorINS_10foo_fields3ArgELi17EEEN5capnp7RequestINS_4test8messages12FooInterface14PassDataParamsENSD_15PassDataResultsEEEEEEEvNS_8TypeListIJT_EEENS_8PriorityILi2EEERNS_13InvokeContextEOT0_OT1_Qaa9is_same_vIDTcldtfL0p3_3getEENS9_4Data7BuilderEE10IsByteSpanISJ_E /tmp/tmp.sFxQecaMfz/git_dir/include/mp/type-data.h:36
    #1 0x61583eb45ee2 in void mp::BuildField<std::vector<char, std::allocator<char> >, mp::ClientInvokeContext, std::vector<char, std::allocator<char> >, mp::StructField<mp::Accessor<mp::foo_fields::Arg, 17>, capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults> > >(mp::TypeList<std::vector<char, std::allocator<char> > >, mp::ClientInvokeContext&, mp::StructField<mp::Accessor<mp::foo_fields::Arg, 17>, capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults> >&&, std::vector<char, std::allocator<char> >&&) /tmp/tmp.sFxQecaMfz/git_dir/include/mp/proxy-types.h:253
    #2 0x61583eb1dcad in void mp::MaybeBuildField<mp::TypeList<std::vector<char, std::allocator<char> > >, mp::ClientInvokeContext&, mp::StructField<mp::Accessor<mp::foo_fields::Arg, 17>, capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults> >, std::vector<char, std::allocator<char> > >(std::integral_constant<bool, true>, mp::TypeList<std::vector<char, std::allocator<char> > >&&, mp::ClientInvokeContext&, mp::StructField<mp::Accessor<mp::foo_fields::Arg, 17>, capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults> >&&, std::vector<char, std::allocator<char> >&&) /tmp/tmp.sFxQecaMfz/git_dir/include/mp/proxy-types.h:336
    #3 0x61583eaeacc0 in auto mp::ClientParam<mp::Accessor<mp::foo_fields::Arg, 17>, std::vector<char, std::allocator<char> > >::BuildParams::handleField<capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>, mp::TypeList<std::vector<char, std::allocator<char> > > >(mp::ClientInvokeContext&, capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>&, mp::TypeList<std::vector<char, std::allocator<char> > >)::{lambda<typename... $T0>(($T0&&)...)#1}::operator()<std::vector<char, std::allocator<char> > >(std::vector<char, std::allocator<char> >&&) const /tmp/tmp.sFxQecaMfz/git_dir/include/mp/proxy-types.h:474
    #4 0x61583eb4601d in void std::__invoke_impl<void, mp::ClientParam<mp::Accessor<mp::foo_fields::Arg, 17>, std::vector<char, std::allocator<char> > >::BuildParams::handleField<capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>, mp::TypeList<std::vector<char, std::allocator<char> > > >(mp::ClientInvokeContext&, capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>&, mp::TypeList<std::vector<char, std::allocator<char> > >)::{lambda<typename... $T0>(($T0&&)...)#1} const&, std::vector<char, std::allocator<char> > >(std::__invoke_other, mp::ClientParam<mp::Accessor<mp::foo_fields::Arg, 17>, std::vector<char, std::allocator<char> > >::BuildParams::handleField<capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>, mp::TypeList<std::vector<char, std::allocator<char> > > >(mp::ClientInvokeContext&, capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>&, mp::TypeList<std::vector<char, std::allocator<char> > >)::{lambda<typename... $T0>(($T0&&)...)#1} const&, std::vector<char, std::allocator<char> >&&) /usr/include/c++/15/bits/invoke.h:63
    #5 0x61583eb1de59 in std::__invoke_result<mp::ClientParam<mp::Accessor<mp::foo_fields::Arg, 17>, std::vector<char, std::allocator<char> > >::BuildParams::handleField<capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>, mp::TypeList<std::vector<char, std::allocator<char> > > >(mp::ClientInvokeContext&, capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>&, mp::TypeList<std::vector<char, std::allocator<char> > >)::{lambda<typename... $T0>(($T0&&)...)#1} const&, std::vector<char, std::allocator<char> > >::type std::__invoke<mp::ClientParam<mp::Accessor<mp::foo_fields::Arg, 17>, std::vector<char, std::allocator<char> > >::BuildParams::handleField<capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>, mp::TypeList<std::vector<char, std::allocator<char> > > >(mp::ClientInvokeContext&, capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>&, mp::TypeList<std::vector<char, std::allocator<char> > >)::{lambda<typename... $T0>(($T0&&)...)#1} const&, std::vector<char, std::allocator<char> > >(capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>&&, std::vector<char, std::allocator<char> >&&) /usr/include/c++/15/bits/invoke.h:98
    #6 0x61583eaeadc1 in decltype(auto) std::__apply_impl<mp::ClientParam<mp::Accessor<mp::foo_fields::Arg, 17>, std::vector<char, std::allocator<char> > >::BuildParams::handleField<capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>, mp::TypeList<std::vector<char, std::allocator<char> > > >(mp::ClientInvokeContext&, capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>&, mp::TypeList<std::vector<char, std::allocator<char> > >)::{lambda<typename... $T0>(($T0&&)...)#1} const&, std::tuple<std::vector<char, std::allocator<char> >&&>, 0ul>(capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>&&, std::tuple<std::vector<char, std::allocator<char> >&&>&&, std::integer_sequence<unsigned long, 0ul>) /usr/include/c++/15/tuple:2920
    #7 0x61583eaeaea0 in decltype(auto) std::apply<mp::ClientParam<mp::Accessor<mp::foo_fields::Arg, 17>, std::vector<char, std::allocator<char> > >::BuildParams::handleField<capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>, mp::TypeList<std::vector<char, std::allocator<char> > > >(mp::ClientInvokeContext&, capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>&, mp::TypeList<std::vector<char, std::allocator<char> > >)::{lambda<typename... $T0>(($T0&&)...)#1} const&, std::tuple<std::vector<char, std::allocator<char> >&&> >(capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>&&, std::tuple<std::vector<char, std::allocator<char> >&&>&&) /usr/include/c++/15/tuple:2935
    #8 0x61583eaeafbc in void mp::ClientParam<mp::Accessor<mp::foo_fields::Arg, 17>, std::vector<char, std::allocator<char> > >::BuildParams::handleField<capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>, mp::TypeList<std::vector<char, std::allocator<char> > > >(mp::ClientInvokeContext&, capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>&, mp::TypeList<std::vector<char, std::allocator<char> > >) /tmp/tmp.sFxQecaMfz/git_dir/include/mp/proxy-types.h:485
    #9 0x61583eaaf470 in void mp::IterateFieldsHelper<mp::ClientParam<mp::Accessor<mp::foo_fields::Arg, 17>, std::vector<char, std::allocator<char> > >::BuildParams, 1ul>::handleChain<mp::ClientInvokeContext, capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>, mp::TypeList<std::vector<char, std::allocator<char> > > >(mp::ClientInvokeContext&, capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>&, mp::TypeList<std::vector<char, std::allocator<char> > >) /tmp/tmp.sFxQecaMfz/git_dir/include/mp/proxy-types.h:416
    #10 0x61583ea8b2b7 in void mp::IterateFieldsHelper<mp::ClientParam<mp::Accessor<mp::foo_fields::Arg, 17>, std::vector<char, std::allocator<char> > >::BuildParams, 1ul>::handleChain<mp::ClientInvokeContext, capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>, mp::TypeList<std::vector<char, std::allocator<char> >, std::vector<char, std::allocator<char> > >, mp::ClientParam<mp::Accessor<mp::foo_fields::Result, 18>, std::vector<char, std::allocator<char> >&>::BuildParams>(mp::ClientInvokeContext&, capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>&, mp::TypeList<std::vector<char, std::allocator<char> >, std::vector<char, std::allocator<char> > >, mp::ClientParam<mp::Accessor<mp::foo_fields::Result, 18>, std::vector<char, std::allocator<char> >&>::BuildParams&&) /tmp/tmp.sFxQecaMfz/git_dir/include/mp/proxy-types.h:408
    #11 0x61583ea6abc4 in void mp::IterateFieldsHelper<mp::IterateFields, 0ul>::handleChain<mp::ClientInvokeContext, capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>, mp::TypeList<std::vector<char, std::allocator<char> >, std::vector<char, std::allocator<char> > >, mp::ClientParam<mp::Accessor<mp::foo_fields::Arg, 17>, std::vector<char, std::allocator<char> > >::BuildParams, mp::ClientParam<mp::Accessor<mp::foo_fields::Result, 18>, std::vector<char, std::allocator<char> >&>::BuildParams>(mp::ClientInvokeContext&, capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>&, mp::TypeList<std::vector<char, std::allocator<char> >, std::vector<char, std::allocator<char> > >, mp::ClientParam<mp::Accessor<mp::foo_fields::Arg, 17>, std::vector<char, std::allocator<char> > >::BuildParams&&, mp::ClientParam<mp::Accessor<mp::foo_fields::Result, 18>, std::vector<char, std::allocator<char> >&>::BuildParams&&) /tmp/tmp.sFxQecaMfz/git_dir/include/mp/proxy-types.h:409
    #12 0x61583ea27feb in mp::clientInvoke<mp::ProxyClient<mp::test::messages::FooInterface>, capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults> (mp::test::messages::FooInterface::Client::*)(kj::Maybe<capnp::MessageSize>), mp::ClientParam<mp::Accessor<mp::foo_fields::Arg, 17>, std::vector<char, std::allocator<char> > >, mp::ClientParam<mp::Accessor<mp::foo_fields::Result, 18>, std::vector<char, std::allocator<char> >&> >(mp::ProxyClient<mp::test::messages::FooInterface>&, capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults> (mp::test::messages::FooInterface::Client::* const&)(kj::Maybe<capnp::MessageSize>), mp::ClientParam<mp::Accessor<mp::foo_fields::Arg, 17>, std::vector<char, std::allocator<char> > >&&, mp::ClientParam<mp::Accessor<mp::foo_fields::Result, 18>, std::vector<char, std::allocator<char> >&>&&)::{lambda()#1}::operator()() const /tmp/tmp.sFxQecaMfz/git_dir/include/mp/proxy-types.h:730
    #13 0x61583ebbb923 in kj::Function<void ()>::Impl<mp::clientInvoke<mp::ProxyClient<mp::test::messages::FooInterface>, capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults> (mp::test::messages::FooInterface::Client::*)(kj::Maybe<capnp::MessageSize>), mp::ClientParam<mp::Accessor<mp::foo_fields::Arg, 17>, std::vector<char, std::allocator<char> > >, mp::ClientParam<mp::Accessor<mp::foo_fields::Result, 18>, std::vector<char, std::allocator<char> >&> >(mp::ProxyClient<mp::test::messages::FooInterface>&, capnp::Request<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults> (mp::test::messages::FooInterface::Client::* const&)(kj::Maybe<capnp::MessageSize>), mp::ClientParam<mp::Accessor<mp::foo_fields::Arg, 17>, std::vector<char, std::allocator<char> > >&&, mp::ClientParam<mp::Accessor<mp::foo_fields::Result, 18>, std::vector<char, std::allocator<char> >&>&&)::{lambda()#1}>::operator()() /usr/include/kj/function.h:142
    #14 0x61583e95004c in kj::Function<void ()>::operator()() /usr/include/kj/function.h:119
    #15 0x61583e941e89 in void mp::Unlock<mp::Lock, kj::Function<void ()>&>(mp::Lock&, kj::Function<void ()>&) /tmp/tmp.sFxQecaMfz/git_dir/include/mp/util.h:216
    #16 0x61583f10d034 in operator() /tmp/tmp.sFxQecaMfz/git_dir/src/mp/proxy.cpp:254
    #17 0x61583f1176e2 in runCatchingExceptions<mp::EventLoop::loop()::<lambda()> > /usr/include/kj/exception.h:371
    #18 0x61583f10d926 in mp::EventLoop::loop() /tmp/tmp.sFxQecaMfz/git_dir/src/mp/proxy.cpp:254
    #19 0x61583e9153aa in mp::test::TestSetup::TestSetup(bool)::{lambda()#1}::operator()() const /tmp/tmp.sFxQecaMfz/git_dir/test/mp/test/test.cpp:125
    #20 0x61583e97cacc in void std::__invoke_impl<void, mp::test::TestSetup::TestSetup(bool)::{lambda()#1}>(std::__invoke_other, mp::test::TestSetup::TestSetup(bool)::{lambda()#1}&&) /usr/include/c++/15/bits/invoke.h:63
    #21 0x61583e97adaf in std::__invoke_result<mp::test::TestSetup::TestSetup(bool)::{lambda()#1}>::type std::__invoke<mp::test::TestSetup::TestSetup(bool)::{lambda()#1}>(mp::test::TestSetup::TestSetup(bool)::{lambda()#1}&&) /usr/include/c++/15/bits/invoke.h:98
    #22 0x61583e979782 in void std::thread::_Invoker<std::tuple<mp::test::TestSetup::TestSetup(bool)::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) /usr/include/c++/15/bits/std_thread.h:303
    #23 0x61583e977a97 in std::thread::_Invoker<std::tuple<mp::test::TestSetup::TestSetup(bool)::{lambda()#1}> >::operator()() /usr/include/c++/15/bits/std_thread.h:310
    #24 0x61583e976029 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<mp::test::TestSetup::TestSetup(bool)::{lambda()#1}> > >::_M_run() /usr/include/c++/15/bits/std_thread.h:255
    #25 0x7da055842ef8  (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0xf5ef8) (BuildId: 3a7a8c6bd922e6314edb7a710fdc0293265c2c42)
    #26 0x7da054e5f0d9  (/usr/lib/x86_64-linux-gnu/libc.so.6+0xa40d9) (BuildId: 90ebd03ae9d9f42b23b4eb82fdf70352cf744198)
    #27 0x7da054ef27ab  (/usr/lib/x86_64-linux-gnu/libc.so.6+0x1377ab) (BuildId: 90ebd03ae9d9f42b23b4eb82fdf70352cf744198)

/tmp/tmp.sFxQecaMfz/git_dir/include/mp/type-data.h:36:11: runtime error: null pointer passed as argument 2, which is declared to never be null
    #0 0x61583ee75afc in _ZN2mp16CustomBuildFieldIOSt6vectorIcSaIcEES3_NS_11StructFieldINS_8AccessorINS_10foo_fields6ResultELi18EEENS_4test8messages12FooInterface15PassDataResults7BuilderEEEEEvNS_8TypeListIJT_EEENS_8PriorityILi2EEERNS_13InvokeContextEOT0_OT1_Qaa9is_same_vIDTcldtfL0p3_3getEEN5capnp4Data7BuilderEE10IsByteSpanISH_E /tmp/tmp.sFxQecaMfz/git_dir/include/mp/type-data.h:36
    #1 0x61583edf4f7a in void mp::BuildField<std::vector<char, std::allocator<char> >&&, mp::InvokeContext, std::vector<char, std::allocator<char> >, mp::StructField<mp::Accessor<mp::foo_fields::Result, 18>, mp::test::messages::FooInterface::PassDataResults::Builder> >(mp::TypeList<std::vector<char, std::allocator<char> >&&>, mp::InvokeContext&, mp::StructField<mp::Accessor<mp::foo_fields::Result, 18>, mp::test::messages::FooInterface::PassDataResults::Builder>&&, std::vector<char, std::allocator<char> >&&) /tmp/tmp.sFxQecaMfz/git_dir/include/mp/proxy-types.h:253
    #2 0x61583ed74581 in void mp::ServerRet<mp::Accessor<mp::foo_fields::Result, 18>, mp::ServerCall>::invoke<mp::ServerInvokeContext<mp::ProxyServer<mp::test::messages::FooInterface>, capnp::CallContext<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults> >, std::vector<char, std::allocator<char> > >(mp::ServerInvokeContext<mp::ProxyServer<mp::test::messages::FooInterface>, capnp::CallContext<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults> >&, mp::TypeList<>, std::vector<char, std::allocator<char> >&&) const /tmp/tmp.sFxQecaMfz/git_dir/include/mp/proxy-types.h:577
    #3 0x61583ecdfeb2 in void mp::PassField<mp::Accessor<mp::foo_fields::Arg, 17>, std::vector<char, std::allocator<char> >, mp::ServerInvokeContext<mp::ProxyServer<mp::test::messages::FooInterface>, capnp::CallContext<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults> >, mp::ServerRet<mp::Accessor<mp::foo_fields::Result, 18>, mp::ServerCall> const&, mp::TypeList<> >(mp::Priority<0>, mp::TypeList<std::vector<char, std::allocator<char> > >, mp::ServerInvokeContext<mp::ProxyServer<mp::test::messages::FooInterface>, capnp::CallContext<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults> >&, mp::ServerRet<mp::Accessor<mp::foo_fields::Result, 18>, mp::ServerCall> const&, mp::TypeList<>&&) /tmp/tmp.sFxQecaMfz/git_dir/include/mp/proxy-types.h:383
    #4 0x61583ec6b087 in decltype(auto) mp::ServerField<1, mp::Accessor<mp::foo_fields::Arg, 17>, mp::ServerRet<mp::Accessor<mp::foo_fields::Result, 18>, mp::ServerCall> >::invoke<mp::ServerInvokeContext<mp::ProxyServer<mp::test::messages::FooInterface>, capnp::CallContext<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults> >, mp::TypeList<std::vector<char, std::allocator<char> > >>(mp::ServerInvokeContext<mp::ProxyServer<mp::test::messages::FooInterface>, capnp::CallContext<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults> >&, mp::TypeList<std::vector<char, std::allocator<char> > >) const /tmp/tmp.sFxQecaMfz/git_dir/include/mp/proxy-types.h:642
    #5 0x61583ec6b01c in mp::serverInvoke<mp::ProxyServer<mp::test::messages::FooInterface>, capnp::CallContext<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>, mp::ServerField<1, mp::Accessor<mp::foo_fields::Arg, 17>, mp::ServerRet<mp::Accessor<mp::foo_fields::Result, 18>, mp::ServerCall> > >(mp::ProxyServer<mp::test::messages::FooInterface>&, capnp::CallContext<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>&, mp::ServerField<1, mp::Accessor<mp::foo_fields::Arg, 17>, mp::ServerRet<mp::Accessor<mp::foo_fields::Result, 18>, mp::ServerCall> >)::{lambda()#1}::operator()() const /tmp/tmp.sFxQecaMfz/git_dir/include/mp/proxy-types.h:823
    #6 0x61583ec6b234 in auto mp::ReplaceVoid<mp::serverInvoke<mp::ProxyServer<mp::test::messages::FooInterface>, capnp::CallContext<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>, mp::ServerField<1, mp::Accessor<mp::foo_fields::Arg, 17>, mp::ServerRet<mp::Accessor<mp::foo_fields::Result, 18>, mp::ServerCall> > >(mp::ProxyServer<mp::test::messages::FooInterface>&, capnp::CallContext<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>&, mp::ServerField<1, mp::Accessor<mp::foo_fields::Arg, 17>, mp::ServerRet<mp::Accessor<mp::foo_fields::Result, 18>, mp::ServerCall> >)::{lambda()#1}, mp::serverInvoke<mp::ProxyServer<mp::test::messages::FooInterface>, capnp::CallContext<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>, mp::ServerField<1, mp::Accessor<mp::foo_fields::Arg, 17>, mp::ServerRet<mp::Accessor<mp::foo_fields::Result, 18>, mp::ServerCall> > >(mp::ProxyServer<mp::test::messages::FooInterface>&, capnp::CallContext<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>&, mp::ServerField<1, mp::Accessor<mp::foo_fields::Arg, 17>, mp::ServerRet<mp::Accessor<mp::foo_fields::Result, 18>, mp::ServerCall> >)::{lambda()#2}>(mp::ProxyServer<mp::test::messages::FooInterface>&&, capnp::CallContext<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>&&) /tmp/tmp.sFxQecaMfz/git_dir/include/mp/proxy-types.h:782
    #7 0x61583ec6c6df in kj::Promise<void> mp::serverInvoke<mp::ProxyServer<mp::test::messages::FooInterface>, capnp::CallContext<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>, mp::ServerField<1, mp::Accessor<mp::foo_fields::Arg, 17>, mp::ServerRet<mp::Accessor<mp::foo_fields::Result, 18>, mp::ServerCall> > >(mp::ProxyServer<mp::test::messages::FooInterface>&, capnp::CallContext<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>&, mp::ServerField<1, mp::Accessor<mp::foo_fields::Arg, 17>, mp::ServerRet<mp::Accessor<mp::foo_fields::Result, 18>, mp::ServerCall> >) /tmp/tmp.sFxQecaMfz/git_dir/include/mp/proxy-types.h:823
    #8 0x61583ec161b5 in mp::ProxyServer<mp::test::messages::FooInterface>::passData(capnp::CallContext<mp::test::messages::FooInterface::PassDataParams, mp::test::messages::FooInterface::PassDataResults>) /tmp/tmp.sFxQecaMfz/git_dir/build-ubsan-gcc/test/mp/test/foo.capnp.proxy-server.c++:93
    #9 0x61583e991105 in mp::test::messages::FooInterface::Server::dispatchCallInternal(unsigned short, capnp::CallContext<capnp::AnyPointer, capnp::AnyPointer>) /tmp/tmp.sFxQecaMfz/git_dir/build-ubsan-gcc/test/mp/test/foo.capnp.c++:4642
    #10 0x61583e984728 in mp::test::messages::FooInterface::Server::dispatchCall(unsigned long, unsigned short, capnp::CallContext<capnp::AnyPointer, capnp::AnyPointer>) /tmp/tmp.sFxQecaMfz/git_dir/build-ubsan-gcc/test/mp/test/foo.capnp.c++:4452
    #11 0x7da055c49874  (/usr/lib/x86_64-linux-gnu/libcapnp-rpc-1.1.0.so+0x58874) (BuildId: 4bc3b60e77961fd7bf5b0656724a4b009a1cdc60)
    #12 0x7da055c58933  (/usr/lib/x86_64-linux-gnu/libcapnp-rpc-1.1.0.so+0x67933) (BuildId: 4bc3b60e77961fd7bf5b0656724a4b009a1cdc60)
    #13 0x7da055ab51bd in kj::_::TransformPromiseNodeBase::get(kj::_::ExceptionOrValue&) (/usr/lib/x86_64-linux-gnu/libkj-async-1.1.0.so+0x421bd) (BuildId: 11e33396b3aedb25ab73f8c546c7af5db001c789)
    #14 0x7da055abff57 in kj::_::ChainPromiseNode::fire() (/usr/lib/x86_64-linux-gnu/libkj-async-1.1.0.so+0x4cf57) (BuildId: 11e33396b3aedb25ab73f8c546c7af5db001c789)
    #15 0x7da055aac852 in kj::EventLoop::turn() (/usr/lib/x86_64-linux-gnu/libkj-async-1.1.0.so+0x39852) (BuildId: 11e33396b3aedb25ab73f8c546c7af5db001c789)
    #16 0x7da055ab2968 in kj::_::waitImpl(kj::Own<kj::_::PromiseNode, kj::_::PromiseDisposer>&&, kj::_::ExceptionOrValue&, kj::WaitScope&, kj::SourceLocation) (/usr/lib/x86_64-linux-gnu/libkj-async-1.1.0.so+0x3f968) (BuildId: 11e33396b3aedb25ab73f8c546c7af5db001c789)
    #17 0x61583f1239ea in kj::Promise<unsigned long>::wait(kj::WaitScope&, kj::SourceLocation) /usr/include/kj/async-inl.h:1357
    #18 0x61583f10d753 in mp::EventLoop::loop() /tmp/tmp.sFxQecaMfz/git_dir/src/mp/proxy.cpp:247
    #19 0x61583e9153aa in mp::test::TestSetup::TestSetup(bool)::{lambda()#1}::operator()() const /tmp/tmp.sFxQecaMfz/git_dir/test/mp/test/test.cpp:125
    #20 0x61583e97cacc in void std::__invoke_impl<void, mp::test::TestSetup::TestSetup(bool)::{lambda()#1}>(std::__invoke_other, mp::test::TestSetup::TestSetup(bool)::{lambda()#1}&&) /usr/include/c++/15/bits/invoke.h:63
    #21 0x61583e97adaf in std::__invoke_result<mp::test::TestSetup::TestSetup(bool)::{lambda()#1}>::type std::__invoke<mp::test::TestSetup::TestSetup(bool)::{lambda()#1}>(mp::test::TestSetup::TestSetup(bool)::{lambda()#1}&&) /usr/include/c++/15/bits/invoke.h:98
    #22 0x61583e979782 in void std::thread::_Invoker<std::tuple<mp::test::TestSetup::TestSetup(bool)::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) /usr/include/c++/15/bits/std_thread.h:303
    #23 0x61583e977a97 in std::thread::_Invoker<std::tuple<mp::test::TestSetup::TestSetup(bool)::{lambda()#1}> >::operator()() /usr/include/c++/15/bits/std_thread.h:310
    #24 0x61583e976029 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<mp::test::TestSetup::TestSetup(bool)::{lambda()#1}> > >::_M_run() /usr/include/c++/15/bits/std_thread.h:255
    #25 0x7da055842ef8  (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0xf5ef8) (BuildId: 3a7a8c6bd922e6314edb7a710fdc0293265c2c42)
    #26 0x7da054e5f0d9  (/usr/lib/x86_64-linux-gnu/libc.so.6+0xa40d9) (BuildId: 90ebd03ae9d9f42b23b4eb82fdf70352cf744198)
    #27 0x7da054ef27ab  (/usr/lib/x86_64-linux-gnu/libc.so.6+0x1377ab) (BuildId: 90ebd03ae9d9f42b23b4eb82fdf70352cf744198)

[ PASS ] test.cpp:143: Call FooInterface methods (627953 μs)
[ TEST ] test.cpp:274: Call IPC method after client connection is closed
[ PASS ] test.cpp:274: Call IPC method after client connection is closed (3349 μs)
[ TEST ] test.cpp:284: Calling IPC method after server connection is closed
[ PASS ] test.cpp:284: Calling IPC method after server connection is closed (4292 μs)
[ TEST ] test.cpp:294: Calling IPC method and disconnecting during the call
[ PASS ] test.cpp:294: Calling IPC method and disconnecting during the call (5566 μs)
[ TEST ] test.cpp:307: Calling IPC method, disconnecting and blocking during the call
[ PASS ] test.cpp:307: Calling IPC method, disconnecting and blocking during the call (11115 μs)
[ TEST ] test.cpp:349: Worker thread destroyed before it is initialized
[ PASS ] test.cpp:349: Worker thread destroyed before it is initialized (21340 μs)
[ TEST ] test.cpp:379: Calling async IPC method, with server disconnect racing the call
[ PASS ] test.cpp:379: Calling async IPC method, with server disconnect racing the call (20475 μs)
[ TEST ] test.cpp:404: Calling async IPC method, with server disconnect after cleanup
[ PASS ] test.cpp:404: Calling async IPC method, with server disconnect after cleanup (5119 μs)
[ TEST ] test.cpp:428: Destroying ProxyClient<> with destroy method after peer disconnect
[ PASS ] test.cpp:428: Destroying ProxyClient<> with destroy method after peer disconnect (14057 μs)
[ TEST ] test.cpp:454: Make simultaneous IPC calls on single remote thread
[ PASS ] test.cpp:454: Make simultaneous IPC calls on single remote thread (38471 μs)
[ TEST ] test.cpp:509: Call async IPC method dispatched to pool thread
[ PASS ] test.cpp:509: Call async IPC method dispatched to pool thread (16066 μs)
[ TEST ] test.cpp:553: Call async IPC method without thread or pool errors correctly
[ PASS ] test.cpp:553: Call async IPC method without thread or pool errors correctly (17293 μs)
16 test(s) passed 

@Sjors

Sjors commented Jul 10, 2026

Copy link
Copy Markdown
Member

Concept ACK on replacing memcpy.

@Sjors

Sjors commented Jul 10, 2026

Copy link
Copy Markdown
Member

ACK fac7b9b

I was also able to reproduce the error that the new test triggers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants