From 195820deca40bb6715cfa22f39de71ea6bd7b9a9 Mon Sep 17 00:00:00 2001 From: Bartosz Burda Date: Sat, 19 Sep 2026 14:06:23 +0200 Subject: [PATCH 1/2] ci: upgrade image packages before installing ROS dependencies The ros:-ros-base images can lag the ROS apt repository. rosdep then installs packages from the current sync next to image packages from an older one, and the two sets do not always link. On lyrical, example_interfaces and test_msgs from the current sync call has_buffer_fields_* and cdr_*_with_endpoint_* functions that the image's service_msgs, builtin_interfaces and unique_identifier_msgs do not export, so every test that loads their FastRTPS type support exits with a symbol lookup error. Run apt-get upgrade in the dependency step of every job whose matrix includes lyrical, so the whole package set comes from one sync. --- .github/workflows/ci.yml | 4 ++++ .github/workflows/opcua-plugin.yml | 2 ++ 2 files changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index db5660890..78f5ab0bf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,6 +58,8 @@ jobs: - name: Install dependencies run: | apt-get update + # Upgrade the image to the apt sync rosdep installs from: packages from two syncs can be ABI-incompatible. + apt-get upgrade -y apt-get install -y ros-${{ matrix.ros_distro }}-test-msgs if [ "${{ matrix.ros_distro }}" = "humble" ]; then apt-get install -y ros-humble-rmw-cyclonedds-cpp @@ -211,6 +213,8 @@ jobs: - name: Install dependencies run: | apt-get update + # Upgrade the image to the apt sync rosdep installs from: packages from two syncs can be ABI-incompatible. + apt-get upgrade -y apt-get install -y ros-${{ matrix.ros_distro }}-test-msgs if [ "${{ matrix.ros_distro }}" = "humble" ] || [ "${{ matrix.ros_distro }}" = "jazzy" ]; then apt-get install -y ros-${{ matrix.ros_distro }}-rmw-cyclonedds-cpp diff --git a/.github/workflows/opcua-plugin.yml b/.github/workflows/opcua-plugin.yml index 84e50cbdd..5d6a2a5c2 100644 --- a/.github/workflows/opcua-plugin.yml +++ b/.github/workflows/opcua-plugin.yml @@ -72,6 +72,8 @@ jobs: - name: Install dependencies run: | apt-get update + # Upgrade the image to the apt sync rosdep installs from: packages from two syncs can be ABI-incompatible. + apt-get upgrade -y apt-get install -y ros-${{ matrix.ros_distro }}-test-msgs libyaml-cpp-dev libssl-dev source /opt/ros/${{ matrix.ros_distro }}/setup.bash for attempt in 1 2 3; do rosdep update && break; [ "$attempt" = 3 ] && exit 1; echo "rosdep update attempt $attempt failed, retrying" >&2; sleep 5; done From 652bc567d236619c12858f8d3fec69a1ebe0ddde Mon Sep 17 00:00:00 2001 From: Bartosz Burda Date: Sat, 19 Sep 2026 15:02:20 +0200 Subject: [PATCH 2/2] test(graph_watchdog): shut rclcpp down after the param_drift integration suite test_param_drift_integration could die with SIGSEGV after all 52 tests had passed. The suite initialises rclcpp and never shuts it down, so the default context is shut down by its own static destructor inside exit(). Since rclcpp 28.1.22, Context::shutdown() first inserts the context into a thread_local set that guards against reentrant calls. exit() destroys the main thread's thread_local objects before it runs static destructors. The case ContextShutdownStopsTheReaderWhileTheDetectorIsStillAlive shuts a context of its own down on the main thread, which creates that set on this thread. At exit the default context's destructor then inserts into the destroyed set and reads its freed bucket array, which crashes whenever the freed memory holds a non-null pointer at that slot. TearDownTestSuite now calls rclcpp::shutdown(). The default context is no longer valid when its destructor runs, and Context::shutdown() returns before it reaches the set. --- .../test/test_param_drift_integration.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/ros2_medkit_plugins/ros2_medkit_graph_watchdog/test/test_param_drift_integration.cpp b/src/ros2_medkit_plugins/ros2_medkit_graph_watchdog/test/test_param_drift_integration.cpp index b541ee98c..d1bbcadb8 100644 --- a/src/ros2_medkit_plugins/ros2_medkit_graph_watchdog/test/test_param_drift_integration.cpp +++ b/src/ros2_medkit_plugins/ros2_medkit_graph_watchdog/test/test_param_drift_integration.cpp @@ -568,6 +568,14 @@ class ParamDriftIntegrationTest : public ::testing::Test { } } + // Shut the default context down before exit(). Its destructor would otherwise call + // Context::shutdown() after exit() has destroyed rclcpp's thread_local state for this thread. + static void TearDownTestSuite() { + if (rclcpp::ok()) { + rclcpp::shutdown(); + } + } + void SetUp() override { gateway_ = std::make_shared("pd_it_gateway"); target_ = std::make_shared("pd_it_target");