Skip to content

Commit 36b8312

Browse files
committed
Keep message libraries loaded in process so zenoh doesn't crash on process exit as it keeps dangling references to the type support.
1 parent f1ceafe commit 36b8312

4 files changed

Lines changed: 25 additions & 3 deletions

File tree

.github/workflows/lint-and-test.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838
matrix:
3939
setup:
4040
- rosdistro: rolling
41-
os: ubuntu-24.04
41+
os: ubuntu-26.04
4242
steps:
4343
- name: install build tools
4444
run: |

ros_babel_fish/src/idl/providers/local_type_support_provider.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
#include <rosidl_typesupport_introspection_cpp/identifier.hpp>
1212
#include <rosidl_typesupport_introspection_cpp/service_introspection.hpp>
1313

14+
#include <mutex>
1415
#include <sstream>
16+
#include <unordered_map>
1517

1618
namespace ros_babel_fish
1719
{
@@ -91,7 +93,18 @@ get_typesupport_library( const std::string &type, const std::string &typesupport
9193
try {
9294
auto package_name = std::get<0>( extract_type_identifier( type ) );
9395
auto library_path = get_typesupport_library_path( package_name, typesupport_identifier );
94-
return std::make_shared<rcpputils::SharedLibrary>( library_path );
96+
// Type-support libraries are cached process-globally and never unloaded for the lifetime of the
97+
// process: the middleware (e.g. rmw_zenoh) may dereference the static type-support data they
98+
// contain while it is being torn down, after the owning BabelFish/entity is already gone.
99+
// Unloading on BabelFish destruction leaves those references dangling.
100+
static std::mutex mutex;
101+
static std::unordered_map<std::string, std::shared_ptr<rcpputils::SharedLibrary>> cache;
102+
std::lock_guard<std::mutex> lock( mutex );
103+
if ( auto it = cache.find( library_path ); it != cache.end() )
104+
return it->second;
105+
auto library = std::make_shared<rcpputils::SharedLibrary>( library_path );
106+
cache.emplace( library_path, library );
107+
return library;
95108
} catch ( TypeSupportException &e ) {
96109
throw TypeSupportException( "Failed to get typesupport library for message type '" + type +
97110
"': " + e.what() );

ros_babel_fish/test/message.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,5 +367,10 @@ int main( int argc, char **argv )
367367
{
368368
testing::InitGoogleTest( &argc, argv );
369369
rclcpp::init( argc, argv );
370-
return RUN_ALL_TESTS();
370+
int result = RUN_ALL_TESTS();
371+
// Shut down rclcpp before the process exits so the middleware (e.g. rmw_zenoh) is
372+
// torn down at a controlled point instead of in a static destructor at process exit,
373+
// which otherwise crashes the process and prevents the gtest result file from being verified.
374+
rclcpp::shutdown();
375+
return result;
371376
}

ros_babel_fish/test/message_encoding.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,10 @@ int main( int argc, char **argv )
317317
rclcpp::init( argc, argv );
318318
node = std::make_shared<rclcpp::Node>( "test_message_decoding" );
319319
int result = RUN_ALL_TESTS();
320+
// Shut down rclcpp before the process exits so the middleware (e.g. rmw_zenoh) is
321+
// torn down at a controlled point instead of in a static destructor at process exit,
322+
// which otherwise crashes the process and prevents the gtest result file from being verified.
323+
rclcpp::shutdown();
320324
node.reset();
321325
return result;
322326
}

0 commit comments

Comments
 (0)