Skip to content

[rcl_logging_spdlog] segfault when rclcpp context is not shut down explicitly (GCC 15.1.1, spdlog 1.15.3) #131

@oysstu

Description

@oysstu

Operating System:

Archlinux

ROS version or commit hash:

Kilted 2025.05.23

RMW implementation (if applicable):

rmw_zenoh_cpp

'ros2 doctor --report' output

ros2 doctor --report
PACKAGE VERSIONS
turtlesim                                 : latest=1.9.3, local=1.9.3
turtlesim_msgs                            : latest=1.9.3, local=1.9.3
tf2_kdl                                   : latest=0.41.1, local=0.41.0
libyaml_vendor                            : latest=1.7.1, local=1.7.1
ros2bag                                   : latest=0.32.0, local=0.32.0
ament_cmake_google_benchmark              : latest=2.7.3, local=2.7.3
ament_cmake_export_libraries              : latest=2.7.3, local=2.7.3
ament_cmake_copyright                     : latest=0.19.2, local=0.19.2
rosidl_cmake                              : latest=4.9.5, local=4.9.4
ament_package                             : latest=0.17.2, local=0.17.2
rosidl_core_generators                    : latest=0.3.1, local=0.3.1
rmw_connextdds_common                     : latest=1.1.0, local=1.1.0
geometry_msgs                             : latest=5.5.0, local=5.5.0
performance_test_fixture                  : latest=0.3.1, local=0.3.1
urdf_parser_plugin                        : latest=2.12.2, local=2.12.2
ament_cmake_mypy                          : latest=0.19.2, local=0.19.2
launch_testing                            : latest=3.8.2, local=3.8.1
urdf                                      : latest=2.12.2, local=2.12.2
test_interface_files                      : latest=0.13.0, local=0.13.0
ament_cmake_export_link_flags             : latest=2.7.3, local=2.7.3
rosbag2_interfaces                        : latest=0.32.0, local=0.32.0
rosidl_pycommon                           : latest=4.9.5, local=4.9.4
kdl_parser                                : latest=2.12.1, local=2.12.1
ament_cmake_export_definitions            : latest=2.7.3, local=2.7.3
ros2lifecycle                             : latest=0.38.0, local=0.38.0
diagnostic_msgs                           : latest=5.5.0, local=5.5.0
rmw_fastrtps_shared_cpp                   : latest=9.3.2, local=9.3.2
ros2cli_test_interfaces                   : latest=0.38.0, local=0.38.0
rclpy                                     : latest=9.1.1, local=9.1.0
ament_cmake_cpplint                       : latest=0.19.2, local=0.19.2
rosidl_default_generators                 : latest=1.7.1, local=1.7.1
ament_cmake_export_include_directories    : latest=2.7.3, local=2.7.3
ament_lint_common                         : latest=0.19.2, local=0.19.2
ament_index_cpp                           : latest=1.11.0, local=1.11.0
ament_cmake_core                          : latest=2.7.3, local=2.7.3
rcl_action                                : latest=10.1.1, local=10.1.0
rmw_test_fixture                          : latest=0.14.3, local=0.14.3
rosidl_dynamic_typesupport                : latest=0.3.1, local=0.3.1
rpyutils                                  : latest=0.6.2, local=0.6.2
ament_cmake_export_dependencies           : latest=2.7.3, local=2.7.3
ament_flake8                              : latest=0.19.2, local=0.19.2
rosidl_runtime_cpp                        : latest=4.9.5, local=4.9.4
message_filters                           : latest=7.1.1, local=7.1.0
rclcpp_components                         : latest=29.5.2, local=29.5.0
std_srvs                                  : latest=5.5.0, local=5.5.0
ament_cmake_export_targets                : latest=2.7.3, local=2.7.3
launch_ros                                : latest=0.28.2, local=0.28.1
rcl_logging_interface                     : latest=3.2.2, local=3.2.2
rosidl_cli                                : latest=4.9.5, local=4.9.4
orocos_kdl_vendor                         : latest=0.7.1, local=0.7.1
tf2_bullet                                : latest=0.41.1, local=0.41.0
rosidl_parser                             : latest=4.9.5, local=4.9.4
ament_cmake_pep257                        : latest=0.19.2, local=0.19.2
ament_cmake_libraries                     : latest=2.7.3, local=2.7.3
eigen3_cmake_module                       : latest=0.4.0, local=0.4.0
rmw_implementation_cmake                  : latest=7.8.2, local=7.8.2
rosbag2_cpp                               : latest=0.32.0, local=0.32.0
type_description_interfaces               : latest=2.3.0, local=2.3.0
yaml_cpp_vendor                           : latest=9.1.0, local=9.1.0
rclcpp_lifecycle                          : latest=29.5.2, local=29.5.0
lifecycle_msgs                            : latest=2.3.0, local=2.3.0
rmw_security_common                       : latest=7.8.2, local=7.8.2
rosbag2_test_msgdefs                      : latest=0.32.0, local=0.32.0
ament_cmake_uncrustify                    : latest=0.19.2, local=0.19.2
ros2node                                  : latest=0.38.0, local=0.38.0
rosidl_generator_py                       : latest=0.24.1, local=0.24.1
ros2service                               : latest=0.38.0, local=0.38.0
ament_cmake_target_dependencies           : latest=2.7.3, local=2.7.3
sros2                                     : latest=0.15.2, local=0.15.2
ros2param                                 : latest=0.38.0, local=0.38.0
keyboard_handler                          : latest=0.4.0, local=0.4.0
rosbag2_storage_mcap                      : latest=0.32.0, local=0.32.0
tf2_geometry_msgs                         : latest=0.41.1, local=0.41.0
mcap_vendor                               : latest=0.32.0, local=0.32.0
rosidl_adapter                            : latest=4.9.5, local=4.9.4
rosbag2_py                                : latest=0.32.0, local=0.32.0
launch_yaml                               : latest=3.8.2, local=3.8.1
rcl_logging_noop                          : latest=3.2.2, local=3.2.2
rosgraph_msgs                             : latest=2.3.0, local=2.3.0
statistics_msgs                           : latest=2.3.0, local=2.3.0
ros2doctor                                : latest=0.38.0, local=0.38.0
ros2lifecycle_test_fixtures               : latest=0.38.0, local=0.38.0
tf2_ros                                   : latest=0.41.1, local=0.41.0
rosbag2                                   : latest=0.32.0, local=0.32.0
ament_cmake_vendor_package                : latest=2.7.3, local=2.7.3
rosbag2_storage                           : latest=0.32.0, local=0.32.0
ament_cmake_lint_cmake                    : latest=0.19.2, local=0.19.2
tf2_eigen_kdl                             : latest=0.41.1, local=0.41.0
sros2_cmake                               : latest=0.15.2, local=0.15.2
ament_lint                                : latest=0.19.2, local=0.19.2
ament_clang_format                        : latest=0.19.2, local=0.19.2
rmw                                       : latest=7.8.2, local=7.8.2
rosidl_generator_cpp                      : latest=4.9.5, local=4.9.4
visualization_msgs                        : latest=5.5.0, local=5.5.0
action_msgs                               : latest=2.3.0, local=2.3.0
osrf_pycommon                             : latest=2.1.6, local=2.1.6
console_bridge_vendor                     : latest=1.8.0, local=1.8.0
rcl_interfaces                            : latest=2.3.0, local=2.3.0
rcl_lifecycle                             : latest=10.1.1, local=10.1.0
ament_cmake_python                        : latest=2.7.3, local=2.7.3
rosidl_typesupport_interface              : latest=4.9.5, local=4.9.4
ament_mypy                                : latest=0.19.2, local=0.19.2
test_msgs                                 : latest=2.3.0, local=2.3.0
sensor_msgs_py                            : latest=5.5.0, local=5.5.0
ament_cpplint                             : latest=0.19.2, local=0.19.2
rosidl_default_runtime                    : latest=1.7.1, local=1.7.1
ros2cli_common_extensions                 : latest=0.4.0, local=0.4.0
tf2_eigen                                 : latest=0.41.1, local=0.41.0
uncrustify_vendor                         : latest=3.1.0, local=3.1.0
ament_cmake_export_interfaces             : latest=2.7.3, local=2.7.3
rosidl_runtime_py                         : latest=0.14.1, local=0.14.1
ros2cli                                   : latest=0.38.0, local=0.38.0
tf2                                       : latest=0.41.1, local=0.41.0
ament_cppcheck                            : latest=0.19.2, local=0.19.2
ros2multicast                             : latest=0.38.0, local=0.38.0
ament_index_python                        : latest=1.11.0, local=1.11.0
ros2launch                                : latest=0.28.2, local=0.28.1
ros2interface                             : latest=0.38.0, local=0.38.0
rmw_connextdds                            : latest=1.1.0, local=1.1.0
ros_testing                               : latest=0.8.0, local=0.8.0
rosidl_typesupport_fastrtps_c             : latest=3.8.0, local=3.8.0
ament_uncrustify                          : latest=0.19.2, local=0.19.2
rmw_implementation                        : latest=3.0.4, local=3.0.4
rmw_test_fixture_implementation           : latest=0.14.3, local=0.14.3
tinyxml2_vendor                           : latest=0.10.0, local=0.10.0
rosidl_core_runtime                       : latest=0.3.1, local=0.3.1
ament_lint_auto                           : latest=0.19.2, local=0.19.2
service_msgs                              : latest=2.3.0, local=2.3.0
launch_testing_ament_cmake                : latest=3.8.2, local=3.8.1
tf2_sensor_msgs                           : latest=0.41.1, local=0.41.0
rosidl_generator_type_description         : latest=4.9.5, local=4.9.4
python_orocos_kdl_vendor                  : latest=0.7.1, local=0.7.1
ros_core                                  : latest=0.12.0, local=0.12.0
rosbag2_transport                         : latest=0.32.0, local=0.32.0
rosbag2_compression                       : latest=0.32.0, local=0.32.0
ament_cmake_version                       : latest=2.7.3, local=2.7.3
libstatistics_collector                   : latest=2.0.1, local=2.0.1
rcutils                                   : latest=6.9.7, local=6.9.5
sensor_msgs                               : latest=5.5.0, local=5.5.0
rosbag2_storage_default_plugins           : latest=0.32.0, local=0.32.0
rcl                                       : latest=10.1.1, local=10.1.0
ament_cmake_cppcheck                      : latest=0.19.2, local=0.19.2
ament_cmake_xmllint                       : latest=0.19.2, local=0.19.2
ament_cmake_gtest                         : latest=2.7.3, local=2.7.3
builtin_interfaces                        : latest=2.3.0, local=2.3.0
zenoh_cpp_vendor                          : latest=0.6.2, local=0.6.1
rosidl_typesupport_cpp                    : latest=3.3.3, local=3.3.3
shape_msgs                                : latest=5.5.0, local=5.5.0
ros2test                                  : latest=0.8.0, local=0.8.0
std_msgs                                  : latest=5.5.0, local=5.5.0
rosbag2_tests                             : latest=0.32.0, local=0.32.0
ament_cmake_test                          : latest=2.7.3, local=2.7.3
common_interfaces                         : latest=5.5.0, local=5.5.0
mimick_vendor                             : latest=0.8.1, local=0.8.1
ros2action                                : latest=0.38.0, local=0.38.0
ros_base                                  : latest=0.12.0, local=0.12.0
rclcpp                                    : latest=29.5.2, local=29.5.0
rmw_zenoh_cpp                             : latest=0.6.2, local=0.6.1
rcpputils                                 : latest=2.13.4, local=2.13.4
ros_environment                           : latest=4.3.1, local=4.3.1
composition_interfaces                    : latest=2.3.0, local=2.3.0
rmw_fastrtps_dynamic_cpp                  : latest=9.3.2, local=9.3.2
class_loader                              : latest=2.8.0, local=2.8.0
ament_cmake_gmock                         : latest=2.7.3, local=2.7.3
rclcpp_action                             : latest=29.5.2, local=29.5.0
ros2pkg                                   : latest=0.38.0, local=0.38.0
pluginlib                                 : latest=5.6.0, local=5.6.0
ros2topic                                 : latest=0.38.0, local=0.38.0
rmw_connextddsmicro                       : latest=N/A, local=1.1.0
ament_cmake_ros_core                      : latest=0.14.3, local=0.14.3
ament_xmllint                             : latest=0.19.2, local=0.19.2
ros2component                             : latest=0.38.0, local=0.38.0
rosidl_typesupport_fastrtps_cpp           : latest=3.8.0, local=3.8.0
rosidl_typesupport_c                      : latest=3.3.3, local=3.3.3
rti_connext_dds_cmake_module              : latest=1.1.0, local=1.1.0
rosidl_dynamic_typesupport_fastrtps       : latest=0.4.1, local=0.4.1
ament_cmake_pytest                        : latest=2.7.3, local=2.7.3
tf2_py                                    : latest=0.41.1, local=0.41.0
rmw_fastrtps_cpp                          : latest=9.3.2, local=9.3.2
ament_cmake_auto                          : latest=2.7.3, local=2.7.3
rmw_dds_common                            : latest=3.2.1, local=3.2.1
tf2_ros_py                                : latest=0.41.1, local=0.41.0
zstd_vendor                               : latest=0.32.0, local=0.32.0
rosidl_typesupport_introspection_cpp      : latest=4.9.5, local=4.9.4
domain_coordinator                        : latest=0.14.3, local=0.14.3
liblz4_vendor                             : latest=0.32.0, local=0.32.0
ament_cmake_gen_version_h                 : latest=2.7.3, local=2.7.3
launch                                    : latest=3.8.2, local=3.8.1
nav_msgs                                  : latest=5.5.0, local=5.5.0
rosidl_generator_c                        : latest=4.9.5, local=4.9.4
ament_cmake_include_directories           : latest=2.7.3, local=2.7.3
launch_xml                                : latest=3.8.2, local=3.8.1
geometry2                                 : latest=0.41.1, local=0.41.0
sqlite3_vendor                            : latest=0.32.0, local=0.32.0
pybind11_vendor                           : latest=3.2.0, local=3.2.0
rosbag2_storage_sqlite3                   : latest=0.32.0, local=0.32.0
rosidl_runtime_c                          : latest=4.9.5, local=4.9.4
rosbag2_test_common                       : latest=0.32.0, local=0.32.0
rcl_yaml_param_parser                     : latest=10.1.1, local=10.1.0
rcl_logging_spdlog                        : latest=3.2.2, local=3.2.2
tracetools                                : latest=8.6.0, local=8.6.0
ament_cmake_ros                           : latest=0.14.3, local=0.14.3
tf2_msgs                                  : latest=0.41.1, local=0.41.0
unique_identifier_msgs                    : latest=2.7.0, local=2.7.0
ros2run                                   : latest=0.38.0, local=0.38.0
ament_lint_cmake                          : latest=0.19.2, local=0.19.2
robot_state_publisher                     : latest=3.4.2, local=3.4.2
actionlib_msgs                            : latest=5.5.0, local=5.5.0
ament_copyright                           : latest=0.19.2, local=0.19.2
ament_cmake_clang_format                  : latest=0.19.2, local=0.19.2
launch_testing_ros                        : latest=0.28.2, local=0.28.1
ament_pep257                              : latest=0.19.2, local=0.19.2
rmw_cyclonedds_cpp                        : latest=4.0.2, local=4.0.2
rosbag2_compression_zstd                  : latest=0.32.0, local=0.32.0
spdlog_vendor                             : latest=1.7.0, local=1.7.0
tf2_tools                                 : latest=0.41.1, local=0.41.0
ament_cmake                               : latest=2.7.3, local=2.7.3
stereo_msgs                               : latest=5.5.0, local=5.5.0
ament_cmake_flake8                        : latest=0.19.2, local=0.19.2
trajectory_msgs                           : latest=5.5.0, local=5.5.0
rosidl_typesupport_introspection_c        : latest=4.9.5, local=4.9.4
ament_pycodestyle                         : latest=0.19.2, local=0.19.2

   PLATFORM INFORMATION
system           : Linux
platform info    : Linux-6.15.8-arch1-1-x86_64-with-glibc2.41
release          : 6.15.8-arch1-1
processor        : 

   QOS COMPATIBILITY LIST
compatibility status    : No publisher/subscriber pairs found

   RMW MIDDLEWARE
middleware name    : rmw_zenoh_cpp

   ROS 2 INFORMATION
distribution name      : kilted
distribution type      : ros2
distribution status    : active
release platforms      : {'debian': ['bookworm'], 'rhel': ['9'], 'ubuntu': ['noble']}

   TOPIC LIST
topic               : none
publisher count     : 0
subscriber count    : 0

Steps to reproduce issue

  1. Compile ros2 and turtlesim with GCC 15.1.1
  2. Remove the explicit call to rclcpp::shutdown() in the turtlesim destructor
  3. Run turtlesim and exit by closing window

Expected behavior

Graceful exit

Actual behavior

Segfault with the following backtrace

Thread 1 "turtlesim_node" received signal SIGSEGV, Segmentation fault.
std::_Hashtable<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<spdlog::logger> >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<spdlog::logger> > >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_M_erase (this=<optimized out>, __bkt=<optimized out>, __prev_n=0x7ffff29531c8 <spdlog::details::registry::instance()::s_instance+136>, 
    __n=0x555555ccec20) at /usr/include/c++/15.1.1/bits/hashtable.h:2580
2580              __n->_M_nxt ? _M_bucket_index(*__n->_M_next()) : 0);
(gdb) bt
#0  std::_Hashtable<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<spdlog::logger> >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<spdlog::logger> > >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_M_erase (this=<optimized out>, __bkt=<optimized out>, __prev_n=0x7ffff29531c8 <spdlog::details::registry::instance()::s_instance+136>, 
    __n=0x555555ccec20) at /usr/include/c++/15.1.1/bits/hashtable.h:2580
#1  std::_Hashtable<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<spdlog::logger> >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<spdlog::logger> > >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::erase (this=<optimized out>, __k="root") at /usr/include/c++/15.1.1/bits/hashtable.h:2620
#2  std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::shared_ptr<spdlog::logger>, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<spdlog::logger> > > >::erase (this=<optimized out>, __x="root") at /usr/include/c++/15.1.1/bits/unordered_map.h:834
#3  spdlog::details::registry::drop (this=0x7ffff2953140 <spdlog::details::registry::instance()::s_instance>, logger_name="root")
    at /usr/src/debug/spdlog/spdlog-1.15.3/include/spdlog/details/registry-inl.h:191
#4  0x00007ffff525b4e2 in rcl_logging_external_shutdown () from /opt/ros/kilted/lib/librcl_logging_spdlog.so
#5  0x00007ffff64d24b7 in rclcpp::Context::shutdown(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
   from /opt/ros/kilted/lib/librclcpp.so
#6  0x00007ffff64d2725 in rclcpp::Context::~Context() () from /opt/ros/kilted/lib/librclcpp.so
#7  0x00007ffff64ca546 in ?? () from /opt/ros/kilted/lib/librclcpp.so
#8  0x00007ffff5c235e1 in __run_exit_handlers (status=0, listp=0x7ffff5dc9680 <__exit_funcs>, run_list_atexit=run_list_atexit@entry=true, 
    run_dtors=run_dtors@entry=true) at exit.c:118
#9  0x00007ffff5c236be in __GI_exit (status=<optimized out>) at exit.c:148
#10 0x00007ffff5c0a6bc in __libc_start_call_main (main=main@entry=0x5555559fc3f9 <main>, argc=argc@entry=1, argv=argv@entry=0x7fffffffd618)
    at ../sysdeps/nptl/libc_start_call_main.h:74
#11 0x00007ffff5c0a769 in __libc_start_main_impl (main=0x5555559fc3f9 <main>, argc=1, argv=0x7fffffffd618, init=<optimized out>, 
    fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffd608) at ../csu/libc-start.c:360
#12 0x00005555559fc325 in _start ()

Additional information

When rclcpp::shutdown is not called explicitly, the destructor of rclcpp::Context calls rclcpp::Context::shutdown.

This in turn calls rcl_logging_fini
https://github.com/ros2/rcl/blob/06c9ba61513efed8d21fdc6e7719438c04a927ea/rcl/src/rcl/logging.c#L142

Then rcl_logging_external_shutdown

rcl_logging_ret_t rcl_logging_external_shutdown()
{
spdlog::drop("root");
g_root_logger = nullptr;
return RCL_LOGGING_RET_OK;
}

Finally, spdlog::drop is called on the root logger
https://github.com/gabime/spdlog/blob/6fa36017cfd5731d617e1a934f0e5ea9c4445b13/include/spdlog/details/registry-inl.h#L188-L195

Here, a segfault occurs when spdlog calls erase on the map of loggers. My hunch is that this is either due to a bug in GCC 15.1.1 or due to incorrect order of deallocation of global objects somewhere, as the erase call should not segfault like this. I'm opening this ticket to track it and in case anyone else encounter the same issue. Obviously, these are unsupported versions of GCC and spdlog, so I'm not expecting any dev effort on this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghelp wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions