Skip to content

EventsExecutor segfaults when a task raises any exception #1641

Description

@nadavelkabets

Environment

ROS2 Rolling (tested on both current HEAD and commit 0ce60eb)
Ubuntu 24.04 (Noble), aarch64
Python 3.12.3

Code to reproduce

def test_coroutine_exception_after_await(self) -> None:
    """Exception in a coroutine after awaiting a future must propagate."""
    self.assertIsNotNone(self.node.handle)
    for cls in [EventsExecutor]:
        with self.subTest(cls=cls):
            executor = cls(context=self.context)
            executor.add_node(self.node)

            first_fut = executor.create_future()
            second_fut = executor.create_future()

            async def coro_that_raises() -> None:
                first_fut.set_result(None)
                await second_fut
                raise RuntimeError('Expected error after await')

            task = executor.create_task(coro_that_raises)

            executor.spin_until_future_complete(first_fut, timeout_sec=5)
            self.assertFalse(task.done())
            # Resolve the inner future — triggers resume
            second_fut.set_result(None)

            # The resumed coroutine should raise, and spin must propagate it
            with self.assertRaises(RuntimeError) as cm:
                executor.spin_until_future_complete(task, timeout_sec=5)
            self.assertIn('Expected error after await', str(cm.exception))

GDB backtrace

Thread 1 "python3" received signal SIGSEGV, Segmentation fault.
__strlen_asimd () at ../sysdeps/aarch64/multiarch/strlen_asimd.S:96

#0  __strlen_asimd () at ../sysdeps/aarch64/multiarch/strlen_asimd.S:96
#1  0x000000000052cb68 in PyUnicode_FromString ()
#2  0x0000fffff5e6cb94 [PAC] in pybind11::str::str (this=0xffffffff7228, c=0x0) at /usr/include/pybind11/pytypes.h:1542
#3  0x0000fffff5e8284c in pybind11::detail::object_api<pybind11::handle>::operator[] (this=0x179b858, key=0x0) at /usr/include/pybind11/pytypes.h:2456
#4  0x0000fffff5f5643c in rclpy::events_executor::EventsExecutor::IterateTask (this=0x179b760, task=...) at /home/user/workspace/src/rclpy/rclpy/src/rclpy/events_executor/events_executor.cpp:841
#5  0x0000fffff5f818ac in std::__invoke_impl<void, void (rclpy::events_executor::EventsExecutor::*&)(pybind11::handle), rclpy::events_executor::EventsExecutor*&, pybind11::handle&> (__f=@0x1a5ce00: (void (rclpy::events_executor::EventsExecutor::*)(rclpy::events_executor::EventsExecutor * const, pybind11::handle)) 0xfffff5f561fc <rclpy::events_executor::EventsExecutor::IterateTask(pybind11::handle)>, __t=@0x1a5ce18: 0x179b760) at /usr/include/c++/13/bits/invoke.h:74
#6  0x0000fffff5f7fad8 in std::__invoke<void (rclpy::events_executor::EventsExecutor::*&)(pybind11::handle), rclpy::events_executor::EventsExecutor*&, pybind11::handle&> (__fn=@0x1a5ce00: (void (rclpy::events_executor::EventsExecutor::*)(rclpy::events_executor::EventsExecutor * const, pybind11::handle)) 0xfffff5f561fc <rclpy::events_executor::EventsExecutor::IterateTask(pybind11::handle)>) at /usr/include/c++/13/bits/invoke.h:96
#7  0x0000fffff5f7da60 in std::_Bind<void (rclpy::events_executor::EventsExecutor::*(rclpy::events_executor::EventsExecutor*, pybind11::handle))(pybind11::handle)>::__call<void, , 0ul, 1ul>(std::tuple<>&&, std::_Index_tuple<0ul, 1ul>) (this=0x1a5ce00, __args=...) at /usr/include/c++/13/functional:506
#8  0x0000fffff5f78cac in std::_Bind<void (rclpy::events_executor::EventsExecutor::*(rclpy::events_executor::EventsExecutor*, pybind11::handle))(pybind11::handle)>::operator()<, void>() (this=0x1a5ce00) at /usr/include/c++/13/functional:591
#9  0x0000fffff5f72e2c in std::__invoke_impl<void, std::_Bind<void (rclpy::events_executor::EventsExecutor::*(rclpy::events_executor::EventsExecutor*, pybind11::handle))(pybind11::handle)>&>(std::__invoke_other, std::_Bind<void (rclpy::events_executor::EventsExecutor::*(rclpy::events_executor::EventsExecutor*, pybind11::handle))(pybind11::handle)>&) (__f=...) at /usr/include/c++/13/bits/invoke.h:61
#10 0x0000fffff5f69b28 in std::__invoke_r<void, std::_Bind<void (rclpy::events_executor::EventsExecutor::*(rclpy::events_executor::EventsExecutor*, pybind11::handle))(pybind11::handle)>&>(std::_Bind<void (rclpy::events_executor::EventsExecutor::*(rclpy::events_executor::EventsExecutor*, pybind11::handle))(pybind11::handle)>&) (__fn=...) at /usr/include/c++/13/bits/invoke.h:111
#11 0x0000fffff5f637fc in std::_Function_handler<void (), std::_Bind<void (rclpy::events_executor::EventsExecutor::*(rclpy::events_executor::EventsExecutor*, pybind11::handle))(pybind11::handle)> >::_M_invoke(std::_Any_data const&) (__functor=...) at /usr/include/c++/13/bits/std_function.h:290
#12 0x0000fffff5f84284 in std::function<void()>::operator() (this=0xffffffff7518) at /usr/include/c++/13/bits/std_function.h:591
#13 0x0000fffff5f83e80 in rclpy::events_executor::EventsQueue::RunUntil (this=0x179b790, deadline=std::chrono::_V2::steady_clock time_point = { 5953877619367ns }) at /home/user/workspace/src/rclpy/rclpy/src/rclpy/events_executor/events_queue.cpp:48
#14 0x0000fffff5f50054 in rclpy::events_executor::EventsExecutor::spin (this=0x179b760, timeout_sec=std::optional = {...}, stop_after_user_callback=false) at /home/user/workspace/src/rclpy/rclpy/src/rclpy/events_executor/events_executor.cpp:176
#15 0x0000fffff5f50358 in rclpy::events_executor::EventsExecutor::spin_until_future_complete (this=0x179b760, future=..., timeout_sec=std::optional = {...}, stop_after_user_callback=false) at /home/user/workspace/src/rclpy/rclpy/src/rclpy/events_executor/events_executor.cpp:194

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions