rclpy icon indicating copy to clipboard operation
rclpy copied to clipboard

Crash on shutdown: rcl_shutdown already called on the given context

Open whoutman opened this issue 2 years ago • 3 comments

Bug report

Required Info:

  • Operating System:
    • Ubuntu 22.04.1 LTS
  • Installation type:
    • binaries
  • Version or commit hash:
    • rclpy 3.3.7
  • DDS implementation:
    • rmw_fastrtps_cpp
  • Client library (if applicable):
    • rqt_reconfigure v 1.1.1, rqt_gui_py v1.1.4, qt_gui v2.2.2

Steps to reproduce issue

ros2 run rqt_reconfigure rqt_reconfigure 
CTRL+C

Similar behavior is seen when running rqt_graph

Expected behavior

Shutdown without errors, which is seen when clicking on the cross of the GUI.

Actual behavior

The following errors are printed:

PluginHandler.shutdown_plugin() plugin "rqt_graph/RosGraph#0" raised an exception:
Traceback (most recent call last):
  File "/home/noblean/ros_ws/install/qt_gui/local/lib/python3.10/dist-packages/qt_gui/plugin_handler.py", line 137, in shutdown_plugin
    self._shutdown_plugin()
  File "/home/noblean/ros_ws/install/qt_gui/local/lib/python3.10/dist-packages/qt_gui/plugin_handler_direct.py", line 92, in _shutdown_plugin
    self.emit_shutdown_plugin_completed()
  File "/home/noblean/ros_ws/install/qt_gui/local/lib/python3.10/dist-packages/qt_gui/plugin_handler.py", line 151, in emit_shutdown_plugin_completed
    callback(self._instance_id)
  File "/home/noblean/ros_ws/install/qt_gui/local/lib/python3.10/dist-packages/qt_gui/plugin_manager.py", line 480, in _close_application_shutdown_callback
    self._close_application_signal()
  File "/home/noblean/ros_ws/install/qt_gui/local/lib/python3.10/dist-packages/qt_gui/plugin_manager.py", line 483, in _close_application_signal
    self._plugin_provider.shutdown()
  File "/home/noblean/ros_ws/install/qt_gui/local/lib/python3.10/dist-packages/qt_gui/composite_plugin_provider.py", line 87, in shutdown
    plugin_provider.shutdown()
  File "/home/noblean/ros_ws/install/qt_gui/local/lib/python3.10/dist-packages/qt_gui/composite_plugin_provider.py", line 87, in shutdown
    plugin_provider.shutdown()
  File "/home/noblean/ros_ws/build/rqt_gui_py/src/rqt_gui_py/ros_py_plugin_provider.py", line 65, in shutdown
    self._destroy_node()
  File "/home/noblean/ros_ws/build/rqt_gui_py/src/rqt_gui_py/ros_py_plugin_provider.py", line 100, in _destroy_node
    rclpy.shutdown()
  File "/home/noblean/ros_ws/install/rclpy/local/lib/python3.10/dist-packages/rclpy/__init__.py", line 126, in shutdown
    _shutdown(context=context)
  File "/home/noblean/ros_ws/install/rclpy/local/lib/python3.10/dist-packages/rclpy/utilities.py", line 58, in shutdown
    return context.shutdown()
  File "/home/noblean/ros_ws/install/rclpy/local/lib/python3.10/dist-packages/rclpy/context.py", line 103, in shutdown
    self.__context.shutdown()
rclpy._rclpy_pybind11.RCLError: failed to shutdown: rcl_shutdown already called on the given context, at ./src/rcl/init.c:241

Additional information and considerations

I have been playing around a bit with this issue.

  • When commenting out rclpy.shutdown() in this file the issue did not show up
  • Calling rclpy.ok() before the same line gave different results for stopping rqt_reconfigure with CTRL+C versus stopping it with by clicking on the cross in the GUI.

whoutman avatar Feb 07 '23 13:02 whoutman

Thanks for reporting, and the initial investigation. I think that this is relatively consistent across the uses of rclpy. I believe I have some time to look into this in the near future.

mjcarroll avatar Feb 07 '23 14:02 mjcarroll

After some inspection, here are some (unordered) thoughts about what is going on here.

rqt installs a global signal handler as part of the rclcpp::init call in RosCppPluginProvider: https://github.com/ros-visualization/rqt/blob/568d8fa2d971698a5dea0fb678448f7bd5d0c5e5/rqt_gui_cpp/src/rqt_gui_cpp/roscpp_plugin_provider.cpp#L93-L97

The python plugin in question (in this case rqt_reconfigure) also installs it's global signal handler.

What we are seeing is that both c++ and python are calling shutdown on the context, without being aware of the other implementation doing the same.

I think that my general strategy forward is to make RosCppPluginProvider pass it's initialized context forward to the plugins, and prevent the plugins themselves from performing shutdown calls on that context, instead leaving it to the provider.

mjcarroll avatar May 10 '23 12:05 mjcarroll

Can we use try_shutdown instead, https://github.com/ros-visualization/rqt/blob/6cf57076b8501264497fd7355997335b3d05d511/rqt_gui_py/src/rqt_gui_py/ros_py_plugin_provider.py#L89 ?

fujitatomoya avatar May 09 '24 19:05 fujitatomoya