diff --git a/rosidl_typesupport_c/src/type_support_dispatch.hpp b/rosidl_typesupport_c/src/type_support_dispatch.hpp index c7839c2a..106b82ce 100644 --- a/rosidl_typesupport_c/src/type_support_dispatch.hpp +++ b/rosidl_typesupport_c/src/type_support_dispatch.hpp @@ -21,12 +21,12 @@ #include #include -#include #include #include "rcpputils/find_library.hpp" #include "rcpputils/shared_library.hpp" #include "rcutils/error_handling.h" +#include "rcutils/snprintf.h" #include "rosidl_typesupport_c/identifier.h" #include "rosidl_typesupport_c/type_support_map.h" @@ -55,23 +55,27 @@ get_typesupport_handle_function( if (!map->data[i]) { char library_name[1024]; - snprintf( + int ret = rcutils_snprintf( library_name, 1023, "%s__%s", map->package_name, identifier); + if (ret < 0) { + RCUTILS_SET_ERROR_MSG("Failed to format library name"); + return nullptr; + } std::string library_path; try { library_path = rcpputils::find_library_path(library_name); } catch (const std::exception & e) { RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( - "Failed to find library '%s' due to %s\n", + "Failed to find library '%s' due to %s", library_name, e.what()); return nullptr; } if (library_path.empty()) { RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( - "Failed to find library '%s'\n", library_name); + "Failed to find library '%s'", library_name); return nullptr; } @@ -79,11 +83,11 @@ get_typesupport_handle_function( lib = new rcpputils::SharedLibrary(library_path.c_str()); } catch (const std::runtime_error & e) { RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( - "Could not load library %s: %s\n", library_path.c_str(), e.what()); + "Could not load library %s: %s", library_path.c_str(), e.what()); return nullptr; } catch (const std::bad_alloc & e) { RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( - "Could not load library %s: %s\n", library_path.c_str(), e.what()); + "Could not load library %s: %s", library_path.c_str(), e.what()); return nullptr; } map->data[i] = lib; @@ -96,13 +100,13 @@ get_typesupport_handle_function( try { if (!lib->has_symbol(map->symbol_name[i])) { RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( - "Failed to find symbol '%s' in library\n", map->symbol_name[i]); + "Failed to find symbol '%s' in library", map->symbol_name[i]); return nullptr; } sym = lib->get_symbol(map->symbol_name[i]); } catch (const std::exception & e) { RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( - "Failed to get symbol '%s' in library: %s\n", + "Failed to get symbol '%s' in library: %s", map->symbol_name[i], e.what()); return nullptr; } @@ -114,7 +118,7 @@ get_typesupport_handle_function( } } RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( - "Handle's typesupport identifier (%s) is not supported by this library\n", + "Handle's typesupport identifier (%s) is not supported by this library", handle->typesupport_identifier); return nullptr; } diff --git a/rosidl_typesupport_cpp/include/rosidl_typesupport_cpp/message_type_support_dispatch.hpp b/rosidl_typesupport_cpp/include/rosidl_typesupport_cpp/message_type_support_dispatch.hpp index 14020501..00c9cc98 100644 --- a/rosidl_typesupport_cpp/include/rosidl_typesupport_cpp/message_type_support_dispatch.hpp +++ b/rosidl_typesupport_cpp/include/rosidl_typesupport_cpp/message_type_support_dispatch.hpp @@ -35,7 +35,7 @@ namespace rosidl_typesupport_cpp ROSIDL_TYPESUPPORT_CPP_PUBLIC const rosidl_message_type_support_t * get_message_typesupport_handle_function( - const rosidl_message_type_support_t * handle, const char * identifier); + const rosidl_message_type_support_t * handle, const char * identifier) noexcept; } // namespace rosidl_typesupport_cpp diff --git a/rosidl_typesupport_cpp/include/rosidl_typesupport_cpp/service_type_support_dispatch.hpp b/rosidl_typesupport_cpp/include/rosidl_typesupport_cpp/service_type_support_dispatch.hpp index 73d94910..ff4f1132 100644 --- a/rosidl_typesupport_cpp/include/rosidl_typesupport_cpp/service_type_support_dispatch.hpp +++ b/rosidl_typesupport_cpp/include/rosidl_typesupport_cpp/service_type_support_dispatch.hpp @@ -35,7 +35,7 @@ namespace rosidl_typesupport_cpp ROSIDL_TYPESUPPORT_CPP_PUBLIC const rosidl_service_type_support_t * get_service_typesupport_handle_function( - const rosidl_service_type_support_t * handle, const char * identifier); + const rosidl_service_type_support_t * handle, const char * identifier) noexcept; } // namespace rosidl_typesupport_cpp diff --git a/rosidl_typesupport_cpp/src/message_type_support_dispatch.cpp b/rosidl_typesupport_cpp/src/message_type_support_dispatch.cpp index 84448cec..8ea4239c 100644 --- a/rosidl_typesupport_cpp/src/message_type_support_dispatch.cpp +++ b/rosidl_typesupport_cpp/src/message_type_support_dispatch.cpp @@ -21,7 +21,7 @@ namespace rosidl_typesupport_cpp const rosidl_message_type_support_t * get_message_typesupport_handle_function( - const rosidl_message_type_support_t * handle, const char * identifier) + const rosidl_message_type_support_t * handle, const char * identifier) noexcept { return rosidl_typesupport_cpp::get_typesupport_handle_function< rosidl_message_type_support_t>(handle, identifier); diff --git a/rosidl_typesupport_cpp/src/service_type_support_dispatch.cpp b/rosidl_typesupport_cpp/src/service_type_support_dispatch.cpp index 5ccb2ae0..3b725297 100644 --- a/rosidl_typesupport_cpp/src/service_type_support_dispatch.cpp +++ b/rosidl_typesupport_cpp/src/service_type_support_dispatch.cpp @@ -21,7 +21,7 @@ namespace rosidl_typesupport_cpp const rosidl_service_type_support_t * get_service_typesupport_handle_function( - const rosidl_service_type_support_t * handle, const char * identifier) + const rosidl_service_type_support_t * handle, const char * identifier) noexcept { return rosidl_typesupport_cpp::get_typesupport_handle_function< rosidl_service_type_support_t>(handle, identifier); diff --git a/rosidl_typesupport_cpp/src/type_support_dispatch.hpp b/rosidl_typesupport_cpp/src/type_support_dispatch.hpp index 3162d274..184017e6 100644 --- a/rosidl_typesupport_cpp/src/type_support_dispatch.hpp +++ b/rosidl_typesupport_cpp/src/type_support_dispatch.hpp @@ -20,11 +20,12 @@ #include #include #include - #include #include "rcpputils/find_library.hpp" #include "rcpputils/shared_library.hpp" +#include "rcutils/error_handling.h" +#include "rcutils/snprintf.h" #include "rosidl_typesupport_c/type_support_map.h" namespace rosidl_typesupport_cpp @@ -35,7 +36,7 @@ extern const char * typesupport_identifier; template const TypeSupport * get_typesupport_handle_function( - const TypeSupport * handle, const char * identifier) + const TypeSupport * handle, const char * identifier) noexcept { if (strcmp(handle->typesupport_identifier, identifier) == 0) { return handle; @@ -51,44 +52,62 @@ get_typesupport_handle_function( rcpputils::SharedLibrary * lib = nullptr; if (!map->data[i]) { - std::string library_name{map->package_name}; - library_name += "__"; - library_name += identifier; + char library_name[1024]; + int ret = rcutils_snprintf( + library_name, 1023, "%s__%s", + map->package_name, identifier); + if (ret < 0) { + RCUTILS_SET_ERROR_MSG("Failed to format library name"); + return nullptr; + } std::string library_path; try { library_path = rcpputils::find_library_path(library_name); } catch (const std::runtime_error & e) { - const std::string message = - "Failed to find library '" + library_name + "' due to " + e.what(); - throw std::runtime_error(message); + RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( + "Failed to find library '%s' due to %s", + library_name, e.what()); + return nullptr; } if (library_path.empty()) { - fprintf(stderr, "Failed to find library '%s'\n", library_name.c_str()); + RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( + "Failed to find library '%s'", library_name); return nullptr; } try { lib = new rcpputils::SharedLibrary(library_path.c_str()); } catch (const std::runtime_error & e) { - throw std::runtime_error( - "Could not load library " + library_path + ": " + - std::string(e.what())); + RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( + "Could not load library %s: %s", library_name, e.what()); + return nullptr; } catch (const std::bad_alloc & e) { - throw std::runtime_error( - "Could not load library " + library_path + ": " + - std::string(e.what())); + RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( + "Could not load library %s: %s", library_name, e.what()); + return nullptr; } map->data[i] = lib; } auto clib = static_cast(map->data[i]); lib = const_cast(clib); - if (!lib->has_symbol(map->symbol_name[i])) { - fprintf(stderr, "Failed to find symbol '%s' in library\n", map->symbol_name[i]); + + void * sym = nullptr; + + try { + if (!lib->has_symbol(map->symbol_name[i])) { + RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( + "Failed to find symbol '%s' in library", map->symbol_name[i]); + return nullptr; + } + sym = lib->get_symbol(map->symbol_name[i]); + } catch (const std::exception & e) { + RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( + "Failed to get symbol '%s' in library: %s", + map->symbol_name[i], e.what()); return nullptr; } - void * sym = lib->get_symbol(map->symbol_name[i]); typedef const TypeSupport * (* funcSignature)(void); funcSignature func = reinterpret_cast(sym); @@ -96,6 +115,9 @@ get_typesupport_handle_function( return ts; } } + RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( + "Handle's typesupport identifier (%s) is not supported by this library", + handle->typesupport_identifier); return nullptr; } diff --git a/rosidl_typesupport_cpp/test/test_message_type_support_dispatch.cpp b/rosidl_typesupport_cpp/test/test_message_type_support_dispatch.cpp index ef9c71c0..e41b1862 100644 --- a/rosidl_typesupport_cpp/test/test_message_type_support_dispatch.cpp +++ b/rosidl_typesupport_cpp/test/test_message_type_support_dispatch.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include "rcutils/error_handling.h" #include "rcutils/testing/fault_injection.h" #include "rcpputils/shared_library.hpp" #include "rosidl_typesupport_c/type_support_map.h" @@ -84,6 +85,8 @@ TEST(TestMessageTypeSupportDispatch, get_handle_function) { rosidl_typesupport_cpp::get_message_typesupport_handle_function( &type_support, "different_identifier"), nullptr); + EXPECT_TRUE(rcutils_error_is_set()); + rcutils_reset_error(); rosidl_message_type_support_t type_support_cpp_identifier = get_rosidl_message_type_support(rosidl_typesupport_cpp::typesupport_identifier); @@ -113,18 +116,24 @@ TEST(TestMessageTypeSupportDispatch, get_handle_function) { rosidl_typesupport_cpp::get_message_typesupport_handle_function( &type_support_cpp_identifier, "test_type_support2"), nullptr); + EXPECT_TRUE(rcutils_error_is_set()); + rcutils_reset_error(); // Library file exists, but loading shared library fails - EXPECT_THROW( + EXPECT_EQ( rosidl_typesupport_cpp::get_message_typesupport_handle_function( &type_support_cpp_identifier, - "test_type_support3"), std::runtime_error); + "test_type_support3"), nullptr); + EXPECT_TRUE(rcutils_error_is_set()); + rcutils_reset_error(); // Library doesn't exist EXPECT_EQ( rosidl_typesupport_cpp::get_message_typesupport_handle_function( &type_support_cpp_identifier, "test_type_support4"), nullptr); + EXPECT_TRUE(rcutils_error_is_set()); + rcutils_reset_error(); } TEST(TestMessageTypeSupportDispatch, get_message_typesupport_maybe_fail_test) @@ -138,14 +147,12 @@ TEST(TestMessageTypeSupportDispatch, get_message_typesupport_maybe_fail_test) RCUTILS_FAULT_INJECTION_TEST( { // load library and find symbols - try { - auto * result = rosidl_typesupport_cpp::get_message_typesupport_handle_function( - &type_support_cpp_identifier, - "test_type_support1"); - EXPECT_NE(result, nullptr); - } catch (const std::runtime_error &) { - } catch (...) { - ADD_FAILURE() << "Unexpected exception type in fault injection test"; + auto * result = rosidl_typesupport_cpp::get_message_typesupport_handle_function( + &type_support_cpp_identifier, + "test_type_support1"); + if (nullptr == result) { + EXPECT_TRUE(rcutils_error_is_set()); + rcutils_reset_error(); } }); } diff --git a/rosidl_typesupport_cpp/test/test_service_type_support_dispatch.cpp b/rosidl_typesupport_cpp/test/test_service_type_support_dispatch.cpp index faedd41a..e5ddeeee 100644 --- a/rosidl_typesupport_cpp/test/test_service_type_support_dispatch.cpp +++ b/rosidl_typesupport_cpp/test/test_service_type_support_dispatch.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include "rcutils/error_handling.h" #include "rcutils/testing/fault_injection.h" #include "rcpputils/shared_library.hpp" #include "rosidl_typesupport_c/type_support_map.h" @@ -84,6 +85,8 @@ TEST(TestServiceTypeSupportDispatch, get_handle_function) { rosidl_typesupport_cpp::get_service_typesupport_handle_function( &type_support, "different_identifier"), nullptr); + EXPECT_TRUE(rcutils_error_is_set()); + rcutils_reset_error(); rosidl_service_type_support_t type_support_cpp_identifier = get_rosidl_service_type_support(rosidl_typesupport_cpp::typesupport_identifier); @@ -110,18 +113,24 @@ TEST(TestServiceTypeSupportDispatch, get_handle_function) { rosidl_typesupport_cpp::get_service_typesupport_handle_function( &type_support_cpp_identifier, "test_type_support2"), nullptr); + EXPECT_TRUE(rcutils_error_is_set()); + rcutils_reset_error(); // Library file exists, but loading shared library fails - EXPECT_THROW( + EXPECT_EQ( rosidl_typesupport_cpp::get_service_typesupport_handle_function( &type_support_cpp_identifier, - "test_type_support3"), std::runtime_error); + "test_type_support3"), nullptr); + EXPECT_TRUE(rcutils_error_is_set()); + rcutils_reset_error(); // Library doesn't exist EXPECT_EQ( rosidl_typesupport_cpp::get_service_typesupport_handle_function( &type_support_cpp_identifier, "test_type_support4"), nullptr); + EXPECT_TRUE(rcutils_error_is_set()); + rcutils_reset_error(); } TEST(TestServiceTypeSupportDispatch, get_service_typesupport_maybe_fail_test) @@ -135,13 +144,12 @@ TEST(TestServiceTypeSupportDispatch, get_service_typesupport_maybe_fail_test) RCUTILS_FAULT_INJECTION_TEST( { // load library and find symbols - try { - auto * result = rosidl_typesupport_cpp::get_service_typesupport_handle_function( - &type_support_cpp_identifier, - "test_type_support1"); - EXPECT_NE(result, nullptr); - } catch (const std::runtime_error &) { - } catch (...) { + auto * result = rosidl_typesupport_cpp::get_service_typesupport_handle_function( + &type_support_cpp_identifier, + "test_type_support1"); + if (nullptr == result) { + EXPECT_TRUE(rcutils_error_is_set()); + rcutils_reset_error(); } }); }