Bug with hpx::collectives::set on macOS (arm64)
Example libs/full/collectives/examples/channel_communicator.cpp exits with a segmentation fault in Debug mode.
Stacktrace from lldb ./main.
* thread #12, stop reason = EXC_BAD_ACCESS (code=1, address=0x3c04)
* frame #0: 0x0000000000003c04
frame #1: 0x00000001008cbce8 main`hpx::util::one_size_heap_list::alloc(this=0x0000000100ee81a8, count=1) at one_size_heap_list.cpp:97:16
frame #2: 0x00000001000267d4 main`hpx::lcos::detail::promise_base<void, hpx::util::unused_type, hpx::lcos::detail::promise_data<void>>::init_shared_state(this=0x0000000130047618) at promise_base.hpp:327:73
frame #3: 0x00000001000265f0 main`hpx::lcos::detail::promise_base<void, hpx::util::unused_type, hpx::lcos::detail::promise_data<void>>::promise_base<hpx::util::thread_local_caching_allocator<hpx::lockfree::variable_size_stack, char, std::__1::allocator<char>>>(this=0x0000000130047618, (null)=allocator_arg_t @ 0x00000001300474ff, a=0x0000000130047616) at promise_base.hpp:186:13
frame #4: 0x0000000100026598 main`hpx::distributed::promise<void, hpx::util::unused_type>::promise<hpx::util::thread_local_caching_allocator<hpx::lockfree::variable_size_stack, char, std::__1::allocator<char>>>(this=0x0000000130047618, (null)=allocator_arg_t @ 0x000000013004753f, a=0x0000000130047616) at promise.hpp:164:13
frame #5: 0x0000000100026564 main`hpx::lcos::packaged_action<hpx::collectives::detail::channel_communicator_server::set_action<int>, void, false>::packaged_action<hpx::util::thread_local_caching_allocator<hpx::lockfree::variable_size_stack, char, std::__1::allocator<char>>>(this=0x0000000130047618, (null)=allocator_arg_t @ 0x000000013004757f, alloc=0x0000000130047616) at packaged_action.hpp:278:13
frame #6: 0x0000000100025b94 main`hpx::lcos::packaged_action<hpx::collectives::detail::channel_communicator_server::set_action<int>, void, false>::packaged_action<hpx::util::thread_local_caching_allocator<hpx::lockfree::variable_size_stack, char, std::__1::allocator<char>>>(this=0x0000000130047618, (null)=allocator_arg_t @ 0x00000001300475af, alloc=0x0000000130047616) at packaged_action.hpp:279:9
frame #7: 0x0000000100015058 main`hpx::future<hpx::traits::extract_action<hpx::collectives::detail::channel_communicator_server::set_action<int>, void>::type::local_result_type> hpx::detail::async_remote_impl<hpx::collectives::detail::channel_communicator_server::set_action<int>, unsigned long&, int&, unsigned long&>(policy=hpx::launch::async_policy @ 0x00000001300476b0, id=0x000060000015b2e8, addr=0x0000000130047750, vs=0x0000600003a922d8, vs=0x0000000130047a6c, vs=0x0000000130047808) at async_implementations.hpp:266:61
frame #8: 0x0000000100012f04 main`hpx::future<hpx::traits::extract_action<hpx::collectives::detail::channel_communicator_server::set_action<int>, void>::type::local_result_type> hpx::detail::async_impl<hpx::collectives::detail::channel_communicator_server::set_action<int>, hpx::detail::async_policy const&, unsigned long&, int&, unsigned long&>(policy=0x0000000100e07892, id=0x000060000015b2e8, vs=0x0000600003a922d8, vs=0x0000000130047a6c, vs=0x0000000130047808) at async_implementations.hpp:475:16
frame #9: 0x0000000100012cd0 main`hpx::future<void> hpx::collectives::detail::channel_communicator::set<int&>(unsigned long, int&, unsigned long) [inlined] hpx::future<void> hpx::detail::async_action_dispatch<hpx::collectives::detail::channel_communicator_server::set_action<int>, hpx::detail::async_policy, void>::call<hpx::detail::async_policy const&, hpx::components::client<hpx::collectives::detail::channel_communicator_server, void>, hpx::collectives::detail::channel_communicator_server, void, unsigned long&, int&, unsigned long&>(launch_policy=0x0000000100e07892, c=0x0000600002d54060, ts=0x0000600003a922d8, ts=0x0000000130047a6c, ts=0x0000000130047808) at async.hpp:119:24
frame #10: 0x0000000100012c84 main`hpx::future<void> hpx::collectives::detail::channel_communicator::set<int&>(unsigned long, int&, unsigned long) [inlined] hpx::future<void> hpx::detail::async_action_dispatch<hpx::collectives::detail::channel_communicator_server::set_action<int>, hpx::components::client<hpx::collectives::detail::channel_communicator_server, void>, void>::call<hpx::components::client<hpx::collectives::detail::channel_communicator_server, void>, hpx::collectives::detail::channel_communicator_server, void, unsigned long&, int&, unsigned long&>(c=0x0000600002d54060, ts=0x0000600003a922d8, ts=0x0000000130047a6c, ts=0x0000000130047808) at async.hpp:170:20
frame #11: 0x0000000100012c54 main`hpx::future<void> hpx::collectives::detail::channel_communicator::set<int&>(unsigned long, int&, unsigned long) [inlined] decltype(detail::async_action_dispatch<hpx::collectives::detail::channel_communicator_server::set_action<int>, __decay(hpx::components::client<hpx::collectives::detail::channel_communicator_server, void> const&)>::call(std::forward<hpx::components::client<hpx::collectives::detail::channel_communicator_server, void> const&>(fp), std::forward<unsigned long&>(fp0), std::forward<int&>(fp0), std::forward<unsigned long&>(fp0))) hpx::async<hpx::collectives::detail::channel_communicator_server::set_action<int>, hpx::components::client<hpx::collectives::detail::channel_communicator_server, void> const&, unsigned long&, int&, unsigned long&>(f=0x0000600002d54060, ts=0x0000600003a922d8, ts=0x0000000130047a6c, ts=0x0000000130047808) at async.hpp:223:16
frame #12: 0x0000000100012c2c main`hpx::future<void> hpx::collectives::detail::channel_communicator::set<int&>(unsigned long, int&, unsigned long) [inlined] decltype(auto) hpx::detail::async_dispatch<hpx::collectives::detail::channel_communicator_server::set_action<int>, void>::call<hpx::collectives::detail::channel_communicator_server, void (unsigned long, int, unsigned long), hpx::collectives::detail::channel_communicator_server::set_action<int>, hpx::components::client<hpx::collectives::detail::channel_communicator_server, void>, unsigned long&, int&, unsigned long&>((null)=0x0000000130047807, policy=0x0000600002d54060, vs=0x0000600003a922d8, vs=0x0000000130047a6c, vs=0x0000000130047808) at async.hpp:277:20
frame #13: 0x0000000100012c04 main`hpx::future<void> hpx::collectives::detail::channel_communicator::set<int&>(unsigned long, int&, unsigned long) [inlined] decltype(auto) hpx::async<hpx::collectives::detail::channel_communicator_server::set_action<int>, hpx::components::client<hpx::collectives::detail::channel_communicator_server, void>&, unsigned long&, int&, unsigned long&>(f=0x0000000130047807, ts=0x0000600002d54060, ts=0x0000600003a922d8, ts=0x0000000130047a6c, ts=0x0000000130047808) at async.hpp:83:16
frame #14: 0x0000000100012bd4 main`hpx::future<void> hpx::collectives::detail::channel_communicator::set<int&>(this=0x0000600003a922d8, site=0, value=0x0000000130047a6c, tag=1) at channel_communicator.hpp:147:20
frame #15: 0x00000001000023d8 main`hpx::future<void> hpx::collectives::set<int&>(comm=hpx::collectives::channel_communicator @ 0x0000000130047a50, site=(argument_ = 0), value=0x0000000130047a6c, tag=(argument_ = 1)) at channel_communicator.hpp:230:28
frame #16: 0x000000010000e1b8 main`_ZZ8hpx_mainvENK3$_0clIN3hpx6futureIiEEEEDaOT_(this=0x0000600001a40080, f=0x0000000130047c48) at channel_communicator.cpp:67:17
frame #17: 0x000000010000e028 main`void hpx::lcos::detail::invoke_continuation_nounwrap<hpx_main()::$_0, hpx::future<int>, hpx::lcos::detail::continuation<hpx::future<int>, hpx_main()::$_0, void>>(this=0x0000000130047b20)::$_0&, hpx::future<int>&&, hpx::lcos::detail::continuation<hpx::future<int>, hpx_main()::$_0, void>&)::'lambda'()::operator()() const at packaged_continuation.hpp:66:21
frame #18: 0x000000010000de30 main`void hpx::lcos::detail::invoke_continuation_nounwrap<hpx_main()::$_0, hpx::future<int>, hpx::lcos::detail::continuation<hpx::future<int>, hpx_main()::$_0, void>>(hpx_main()::$_0&, hpx::future<int>&&, hpx::lcos::detail::continuation<hpx::future<int>, hpx_main()::$_0, void>&) [inlined] decltype(auto) hpx::detail::try_catch_exception_ptr<void hpx::lcos::detail::invoke_continuation_nounwrap<hpx_main()::$_0, hpx::future<int>, hpx::lcos::detail::continuation<hpx::future<int>, hpx_main()::$_0, void>>(hpx_main()::$_0&, hpx::future<int>&&, hpx::lcos::detail::continuation<hpx::future<int>, hpx_main()::$_0, void>&)::'lambda'(), void hpx::lcos::detail::invoke_continuation_nounwrap<hpx_main()::$_0, hpx::future<int>, hpx::lcos::detail::continuation<hpx::future<int>, hpx_main()::$_0, void>>(hpx_main()::$_0&, hpx::future<int>&&, hpx::lcos::detail::continuation<hpx::future<int>, hpx_main()::$_0, void>&)::'lambda'(std::exception_ptr)>(t=0x0000000130047b20, c=0x0000000130047b18) at try_catch_exception_ptr.hpp:37:20
frame #19: 0x000000010000de1c main`void hpx::lcos::detail::invoke_continuation_nounwrap<hpx_main()::$_0, hpx::future<int>, hpx::lcos::detail::continuation<hpx::future<int>, hpx_main()::$_0, void>>(func=0x0000600001a40080, future=0x0000000130047c48, cont=0x0000600001a40000) at packaged_continuation.hpp:59:9
frame #20: 0x000000010000dca8 main`void hpx::lcos::detail::invoke_continuation<hpx_main()::$_0, hpx::future<int>, hpx::lcos::detail::continuation<hpx::future<int>, hpx_main()::$_0, void>>(func=0x0000600001a40080, future=0x0000000130047c48, cont=0x0000600001a40000) at packaged_continuation.hpp:87:13
frame #21: 0x000000010000dc00 main`void hpx::lcos::detail::continuation<hpx::future<int>, hpx_main()::$_0, void>::run_impl<true>(this=0x0000600001a40000, f=0x0000000156307990) at packaged_continuation.hpp:218:17
frame #22: 0x000000010000dbb4 main`void hpx::lcos::detail::continuation<hpx::future<int>, hpx_main()::$_0, void>::async<true, hpx::lcos::detail::post_policy_spawner>(this=0x0000000156307988)::'lambda'()::operator()() at packaged_continuation.hpp:245:37
frame #23: 0x000000010000db6c main`hpx::threads::detail::thread_function_nullary<void hpx::lcos::detail::continuation<hpx::future<int>, hpx_main()::$_0, void>::async<true, hpx::lcos::detail::post_policy_spawner>(hpx::intrusive_ptr<hpx::lcos::detail::future_data_base<int>>&&, hpx::lcos::detail::post_policy_spawner&&)::'lambda'()>::operator()(this=0x0000000156307988, (null)=signaled) at register_thread.hpp:50:17
frame #24: 0x000000010000db34 main`std::__1::pair<hpx::threads::thread_schedule_state, hpx::threads::thread_id> hpx::util::detail::callable_vtable<std::__1::pair<hpx::threads::thread_schedule_state, hpx::threads::thread_id> (hpx::threads::thread_restart_state)>::_invoke<hpx::threads::detail::thread_function_nullary<void hpx::lcos::detail::continuation<hpx::future<int>, hpx_main()::$_0, void>::async<true, hpx::lcos::detail::post_policy_spawner>(hpx::intrusive_ptr<hpx::lcos::detail::future_data_base<int>>&&, hpx::lcos::detail::post_policy_spawner&&)::'lambda'()>>(f=0x0000000156307988, vs=0x0000000130047e8f) at callable_vtable.hpp:88:20
frame #25: 0x0000000100b37e3c main`hpx::threads::coroutines::detail::coroutine_impl::operator()() [inlined] hpx::util::detail::basic_function<std::__1::pair<hpx::threads::thread_schedule_state, hpx::threads::thread_id> (hpx::threads::thread_restart_state), false, false>::operator()(this=0x0000000156307978, vs=signaled) const at basic_function.hpp:244:20
frame #26: 0x0000000100b37e24 main`hpx::threads::coroutines::detail::coroutine_impl::operator()(this=0x00000001563078c0) at coroutine_impl.cpp:81:35
frame #27: 0x00000001009a5d14 main`void hpx::threads::coroutines::detail::generic_context::trampoline<hpx::threads::coroutines::detail::coroutine_impl>(tr=(fctx = 0x00000001703fd250, data = 0x00000001563078c0)) at context_generic_context.hpp:185:13
frame #28: 0x0000000100b73528 main`make_fcontext at make_arm64_aapcs_macho_gas.S:76
System configuration: macOS 15.6.1, clang-1700.0.13.5, arm64-apple-darwin24.6.0.
Vcpkg is used to build HPX (I assume that #6772 is fixed).
The correct behavior is observed in version 1.9.1 and in Release mode only in 1.10 and 1.11.
In Debug mode, both 1.10 and 1.11 produce a segmentation fault.
Additionally, Illegal instruction: 4 is printed for HPX v1.11.
Minimal reproducible example
CMakeLists.txt:
cmake_minimum_required(VERSION 3.18)
project(tmp)
find_package(HPX REQUIRED)
add_executable(main main.cpp)
target_link_libraries(
main
PUBLIC HPX::hpx HPX::wrap_main
)
vcpkg.json:
{
"name": "tmp",
"dependencies": [
"hpx"
]
}
main.cpp:
#include <hpx/hpx_main.hpp>
#include <hpx/collectives/channel_communicator.hpp>
void f() {
hpx::collectives::channel_communicator comm;
hpx::collectives::set(comm, hpx::collectives::that_site_arg(0), 0);
}
int main() {}
Shell commands:
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=~/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Debug
$ make && ./main
In this example hpx::collectives::set is not called, but its instantiation is enough to produce a segmentation fault in the destructors of static variables.
Thanks for this report. This looks like a sequencing issue of destructors of global objects being called in undefined order. I'll try to reproduce this. BTW, I doubt that this is related to vcpkg.