Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

memory leaks in rcl(tests) #721

Closed
Karsten1987 opened this issue Jul 20, 2020 · 24 comments
Closed

memory leaks in rcl(tests) #721

Karsten1987 opened this issue Jul 20, 2020 · 24 comments
Labels
bug Something isn't working

Comments

@Karsten1987
Copy link
Contributor

while debugging #715 I came across that quite some tests are actually leaking memory. I haven't looked into whether these are related to the tests or actually something within rcl itself.

for test_node__rmw_fastrtps_cpp:

==23229== HEAP SUMMARY:
==23229==     in use at exit: 3,132 bytes in 28 blocks
==23229==   total heap usage: 24,212 allocs, 24,184 frees, 19,883,015 bytes allocated
==23229== 
==23229== 208 bytes in 1 blocks are definitely lost in loss record 13 of 16
==23229==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23229==    by 0x5CFD615: __default_allocate (allocator.c:35)
==23229==    by 0x4E4D950: _rcl_allocate_initialized_arguments_impl (arguments.c:1997)
==23229==    by 0x4E463CC: rcl_parse_arguments (arguments.c:274)
==23229==    by 0x176837: TestNodeFixture__rmw_fastrtps_cpp_test_rcl_node_options_fail_Test::TestBody() (test_node.cpp:764)
==23229==    by 0x1D82BF: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23229==    by 0x1D2044: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23229==    by 0x1B0431: testing::Test::Run() (gtest.cc:2522)
==23229==    by 0x1B0DC6: testing::TestInfo::Run() (gtest.cc:2703)
==23229==    by 0x1B146F: testing::TestCase::Run() (gtest.cc:2825)
==23229==    by 0x1BC50D: testing::internal::UnitTestImpl::RunAllTests() (gtest.cc:5216)
==23229==    by 0x1D94B6: bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) (gtest.cc:2447)
==23229== 
==23229== 784 (168 direct, 616 indirect) bytes in 7 blocks are definitely lost in loss record 15 of 16
==23229==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23229==    by 0x5CFD615: __default_allocate (allocator.c:35)
==23229==    by 0x797FF24: rmw_allocate (allocators.c:29)
==23229==    by 0x79800C0: rmw_wait_set_allocate (allocators.c:133)
==23229==    by 0x84254B9: rmw_fastrtps_shared_cpp::__rmw_create_wait_set(char const*, rmw_context_t*, unsigned long) (rmw_wait_set.cpp:38)
==23229==    by 0x83EEAEA: node_listener(rmw_context_t*) (listener_thread.cpp:132)
==23229==    by 0x83EF3B6: void std::__invoke_impl<void, void (*)(rmw_context_t*), rmw_context_t*>(std::__invoke_other, void (*&&)(rmw_context_t*), rmw_context_t*&&) (invoke.h:60)
==23229==    by 0x83EEFDA: std::__invoke_result<void (*)(rmw_context_t*), rmw_context_t*>::type std::__invoke<void (*)(rmw_context_t*), rmw_context_t*>(void (*&&)(rmw_context_t*), rmw_context_t*&&) (invoke.h:95)
==23229==    by 0x83EFA48: decltype (__invoke((_S_declval<0ul>)(), (_S_declval<1ul>)())) std::thread::_Invoker<std::tuple<void (*)(rmw_context_t*), rmw_context_t*> >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) (thread:234)
==23229==    by 0x83EF9E9: std::thread::_Invoker<std::tuple<void (*)(rmw_context_t*), rmw_context_t*> >::operator()() (thread:243)
==23229==    by 0x83EF9B9: std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(rmw_context_t*), rmw_context_t*> > >::_M_run() (thread:186)
==23229==    by 0x64656DE: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==23229== 
==23229== LEAK SUMMARY:
==23229==    definitely lost: 376 bytes in 8 blocks
==23229==    indirectly lost: 616 bytes in 7 blocks
==23229==      possibly lost: 0 bytes in 0 blocks
==23229==    still reachable: 2,140 bytes in 13 blocks
==23229==         suppressed: 0 bytes in 0 blocks

for comparison, the same test with cyclonedds:

==23528== HEAP SUMMARY:
==23528==     in use at exit: 5,285 bytes in 84 blocks
==23528==   total heap usage: 19,309 allocs, 19,225 frees, 45,359,169 bytes allocated
==23528== 
==23528== 29 bytes in 1 blocks are definitely lost in loss record 1 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x1DAA6A: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) (basic_string.tcc:219)
==23528==    by 0x5D45786: cycdeser::deserialize(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) (serdes.hpp:165)
==23528==    by 0x5D450F4: cycdeser::operator>>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) (serdes.hpp:113)
==23528==    by 0x5D4657B: void rmw_cyclonedds_cpp::deserialize_field<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(rosidl_typesupport_introspection_cpp::MessageMember const*, void*, cycdeser&, bool) (TypeSupport_impl.hpp:281)
==23528==    by 0x5D503D6: rmw_cyclonedds_cpp::TypeSupport<rosidl_typesupport_introspection_cpp::MessageMembers>::deserializeROSmessage(cycdeser&, rosidl_typesupport_introspection_cpp::MessageMembers const*, void*, bool) (TypeSupport_impl.hpp:514)
==23528==    by 0x5D5051A: rmw_cyclonedds_cpp::TypeSupport<rosidl_typesupport_introspection_cpp::MessageMembers>::deserializeROSmessage(cycdeser&, rosidl_typesupport_introspection_cpp::MessageMembers const*, void*, bool) (TypeSupport_impl.hpp:542)
==23528==    by 0x5D4AA30: rmw_cyclonedds_cpp::TypeSupport<rosidl_typesupport_introspection_cpp::MessageMembers>::deserializeROSmessage(cycdeser&, void*, std::function<void (cycdeser&)>) (TypeSupport_impl.hpp:669)
==23528==    by 0x5D9734E: serdata_rmw_to_sample(ddsi_serdata const*, void*, void**, void*) (serdata.cpp:288)
==23528==    by 0x80CD643: ddsi_serdata_to_sample (ddsi_serdata.h:230)
==23528==    by 0x814B813: read_take_to_sample (dds_rhc_default.c:1956)
==23528==    by 0x814BF68: take_w_qminv_inst (dds_rhc_default.c:2091)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 38 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D379CF: create_cdds_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*) (rmw_node.cpp:1839)
==23528==    by 0x5D37E25: create_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_publisher_options_t const*) (rmw_node.cpp:1910)
==23528==    by 0x5D34221: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1028)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x161872: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_accessors_Test::TestBody() (test_node.cpp:107)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 39 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D38F3F: create_cdds_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, bool) (rmw_node.cpp:2110)
==23528==    by 0x5D39390: create_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_subscription_options_t const*) (rmw_node.cpp:2177)
==23528==    by 0x5D342C3: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1043)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x161872: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_accessors_Test::TestBody() (test_node.cpp:107)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 40 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D379CF: create_cdds_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*) (rmw_node.cpp:1839)
==23528==    by 0x5D37E25: create_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_publisher_options_t const*) (rmw_node.cpp:1910)
==23528==    by 0x5D34221: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1028)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x161C85: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_accessors_Test::TestBody() (test_node.cpp:131)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 41 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D38F3F: create_cdds_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, bool) (rmw_node.cpp:2110)
==23528==    by 0x5D39390: create_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_subscription_options_t const*) (rmw_node.cpp:2177)
==23528==    by 0x5D342C3: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1043)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x161C85: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_accessors_Test::TestBody() (test_node.cpp:131)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 42 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D379CF: create_cdds_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*) (rmw_node.cpp:1839)
==23528==    by 0x5D37E25: create_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_publisher_options_t const*) (rmw_node.cpp:1910)
==23528==    by 0x5D34221: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1028)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x167BC4: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_life_cycle_Test::TestBody() (test_node.cpp:400)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 43 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D38F3F: create_cdds_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, bool) (rmw_node.cpp:2110)
==23528==    by 0x5D39390: create_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_subscription_options_t const*) (rmw_node.cpp:2177)
==23528==    by 0x5D342C3: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1043)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x167BC4: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_life_cycle_Test::TestBody() (test_node.cpp:400)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 44 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D379CF: create_cdds_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*) (rmw_node.cpp:1839)
==23528==    by 0x5D37E25: create_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_publisher_options_t const*) (rmw_node.cpp:1910)
==23528==    by 0x5D34221: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1028)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x167DC9: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_life_cycle_Test::TestBody() (test_node.cpp:405)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 45 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D38F3F: create_cdds_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, bool) (rmw_node.cpp:2110)
==23528==    by 0x5D39390: create_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_subscription_options_t const*) (rmw_node.cpp:2177)
==23528==    by 0x5D342C3: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1043)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x167DC9: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_life_cycle_Test::TestBody() (test_node.cpp:405)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 46 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D379CF: create_cdds_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*) (rmw_node.cpp:1839)
==23528==    by 0x5D37E25: create_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_publisher_options_t const*) (rmw_node.cpp:1910)
==23528==    by 0x5D34221: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1028)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x16928F: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_name_restrictions_Test::TestBody() (test_node.cpp:445)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 47 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D38F3F: create_cdds_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, bool) (rmw_node.cpp:2110)
==23528==    by 0x5D39390: create_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_subscription_options_t const*) (rmw_node.cpp:2177)
==23528==    by 0x5D342C3: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1043)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x16928F: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_name_restrictions_Test::TestBody() (test_node.cpp:445)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 48 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D379CF: create_cdds_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*) (rmw_node.cpp:1839)
==23528==    by 0x5D37E25: create_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_publisher_options_t const*) (rmw_node.cpp:1910)
==23528==    by 0x5D34221: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1028)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x16A9FE: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_namespace_restrictions_Test::TestBody() (test_node.cpp:513)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 49 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D38F3F: create_cdds_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, bool) (rmw_node.cpp:2110)
==23528==    by 0x5D39390: create_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_subscription_options_t const*) (rmw_node.cpp:2177)
==23528==    by 0x5D342C3: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1043)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x16A9FE: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_namespace_restrictions_Test::TestBody() (test_node.cpp:513)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 50 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D379CF: create_cdds_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*) (rmw_node.cpp:1839)
==23528==    by 0x5D37E25: create_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_publisher_options_t const*) (rmw_node.cpp:1910)
==23528==    by 0x5D34221: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1028)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x16AC39: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_namespace_restrictions_Test::TestBody() (test_node.cpp:522)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 51 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D38F3F: create_cdds_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, bool) (rmw_node.cpp:2110)
==23528==    by 0x5D39390: create_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_subscription_options_t const*) (rmw_node.cpp:2177)
==23528==    by 0x5D342C3: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1043)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x16AC39: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_namespace_restrictions_Test::TestBody() (test_node.cpp:522)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 52 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D379CF: create_cdds_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*) (rmw_node.cpp:1839)
==23528==    by 0x5D37E25: create_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_publisher_options_t const*) (rmw_node.cpp:1910)
==23528==    by 0x5D34221: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1028)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x16AF5E: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_namespace_restrictions_Test::TestBody() (test_node.cpp:532)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 53 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D38F3F: create_cdds_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, bool) (rmw_node.cpp:2110)
==23528==    by 0x5D39390: create_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_subscription_options_t const*) (rmw_node.cpp:2177)
==23528==    by 0x5D342C3: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1043)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x16AF5E: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_namespace_restrictions_Test::TestBody() (test_node.cpp:532)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 54 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D379CF: create_cdds_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*) (rmw_node.cpp:1839)
==23528==    by 0x5D37E25: create_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_publisher_options_t const*) (rmw_node.cpp:1910)
==23528==    by 0x5D34221: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1028)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x16BBB3: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_namespace_restrictions_Test::TestBody() (test_node.cpp:572)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 55 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D38F3F: create_cdds_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, bool) (rmw_node.cpp:2110)
==23528==    by 0x5D39390: create_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_subscription_options_t const*) (rmw_node.cpp:2177)
==23528==    by 0x5D342C3: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1043)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x16BBB3: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_namespace_restrictions_Test::TestBody() (test_node.cpp:572)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 56 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D379CF: create_cdds_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*) (rmw_node.cpp:1839)
==23528==    by 0x5D37E25: create_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_publisher_options_t const*) (rmw_node.cpp:1910)
==23528==    by 0x5D34221: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1028)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x16D034: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_names_Test::TestBody() (test_node.cpp:623)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 57 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D38F3F: create_cdds_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, bool) (rmw_node.cpp:2110)
==23528==    by 0x5D39390: create_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_subscription_options_t const*) (rmw_node.cpp:2177)
==23528==    by 0x5D342C3: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1043)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x16D034: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_names_Test::TestBody() (test_node.cpp:623)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 58 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D379CF: create_cdds_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*) (rmw_node.cpp:1839)
==23528==    by 0x5D37E25: create_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_publisher_options_t const*) (rmw_node.cpp:1910)
==23528==    by 0x5D34221: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1028)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x16D5F3: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_names_Test::TestBody() (test_node.cpp:643)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 59 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D38F3F: create_cdds_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, bool) (rmw_node.cpp:2110)
==23528==    by 0x5D39390: create_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_subscription_options_t const*) (rmw_node.cpp:2177)
==23528==    by 0x5D342C3: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1043)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x16D5F3: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_names_Test::TestBody() (test_node.cpp:643)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 60 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D379CF: create_cdds_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*) (rmw_node.cpp:1839)
==23528==    by 0x5D37E25: create_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_publisher_options_t const*) (rmw_node.cpp:1910)
==23528==    by 0x5D34221: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1028)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x16DBB2: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_names_Test::TestBody() (test_node.cpp:663)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 61 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D38F3F: create_cdds_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, bool) (rmw_node.cpp:2110)
==23528==    by 0x5D39390: create_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_subscription_options_t const*) (rmw_node.cpp:2177)
==23528==    by 0x5D342C3: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1043)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x16DBB2: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_names_Test::TestBody() (test_node.cpp:663)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 62 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D379CF: create_cdds_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*) (rmw_node.cpp:1839)
==23528==    by 0x5D37E25: create_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_publisher_options_t const*) (rmw_node.cpp:1910)
==23528==    by 0x5D34221: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1028)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x16E171: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_names_Test::TestBody() (test_node.cpp:683)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 63 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D38F3F: create_cdds_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, bool) (rmw_node.cpp:2110)
==23528==    by 0x5D39390: create_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_subscription_options_t const*) (rmw_node.cpp:2177)
==23528==    by 0x5D342C3: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1043)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x16E171: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_names_Test::TestBody() (test_node.cpp:683)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 64 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D379CF: create_cdds_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*) (rmw_node.cpp:1839)
==23528==    by 0x5D37E25: create_publisher(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_publisher_options_t const*) (rmw_node.cpp:1910)
==23528==    by 0x5D34221: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1028)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x16E730: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_names_Test::TestBody() (test_node.cpp:703)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 92 (40 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 65 of 72
==23528==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5D9668B: create_message_type_support(void const*, char const*) (serdata.cpp:84)
==23528==    by 0x5D38F3F: create_cdds_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, bool) (rmw_node.cpp:2110)
==23528==    by 0x5D39390: create_subscription(int, int, rosidl_message_type_support_t const*, char const*, rmw_qos_profile_t const*, rmw_subscription_options_t const*) (rmw_node.cpp:2177)
==23528==    by 0x5D342C3: rmw_context_impl_t::init(rmw_init_options_t*) (rmw_node.cpp:1043)
==23528==    by 0x5D357CC: rmw_create_node (rmw_node.cpp:1258)
==23528==    by 0x4E59265: rcl_node_init (node.c:263)
==23528==    by 0x16E730: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_names_Test::TestBody() (test_node.cpp:703)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528== 
==23528== 208 bytes in 1 blocks are definitely lost in loss record 70 of 72
==23528==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23528==    by 0x5A85615: __default_allocate (allocator.c:35)
==23528==    by 0x4E4D950: _rcl_allocate_initialized_arguments_impl (arguments.c:1997)
==23528==    by 0x4E463CC: rcl_parse_arguments (arguments.c:274)
==23528==    by 0x1709A7: TestNodeFixture__rmw_cyclonedds_cpp_test_rcl_node_options_fail_Test::TestBody() (test_node.cpp:764)
==23528==    by 0x1D242F: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2447)
==23528==    by 0x1CC1B4: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2483)
==23528==    by 0x1AA5A1: testing::Test::Run() (gtest.cc:2522)
==23528==    by 0x1AAF36: testing::TestInfo::Run() (gtest.cc:2703)
==23528==    by 0x1AB5DF: testing::TestCase::Run() (gtest.cc:2825)
==23528==    by 0x1B667D: testing::internal::UnitTestImpl::RunAllTests() (gtest.cc:5216)
==23528==    by 0x1D3626: bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) (gtest.cc:2447)
==23528== 
==23528== LEAK SUMMARY:
==23528==    definitely lost: 1,357 bytes in 30 blocks
==23528==    indirectly lost: 1,456 bytes in 28 blocks
==23528==      possibly lost: 0 bytes in 0 blocks
==23528==    still reachable: 2,472 bytes in 26 blocks
==23528==         suppressed: 0 bytes in 0 blo
@Karsten1987 Karsten1987 added the bug Something isn't working label Jul 20, 2020
@iuhilnehc-ynos
Copy link
Collaborator

@Karsten1987

I'd like to contribute to this issue.

@iuhilnehc-ynos
Copy link
Collaborator

iuhilnehc-ynos commented Aug 11, 2020

@Karsten1987

I found there are four issues in your descriptions.

  1. rcl_parse_arguments (not detect. maybe some commit fixed it.)

  2. rmw_fastrtps_shared_cpp::__rmw_create_wait_set

    It seems that https://github.com/ros2/rmw_fastrtps/blob/0d039e6d0f944448ba2d26a6d0b83795745f60fc/rmw_fastrtps_shared_cpp/src/listener_thread.cpp#L171-L175 should move after https://github.com/ros2/rmw_fastrtps/blob/0d039e6d0f944448ba2d26a6d0b83795745f60fc/rmw_fastrtps_shared_cpp/src/listener_thread.cpp#L136-L146.

  3. cycdeser::deserialize into a buf (rmw_cycledds)

    template<>
    inline void deserialize_field<std::string>(
      const rosidl_typesupport_introspection_cpp::MessageMember * member,
      void * field,
      cycdeser & deser,
      bool call_new)
    {
      if (!member->is_array_) {
        if (call_new) {
          // Because std::string is a complex datatype, we need to make sure that
          // the memory is initialized to something reasonable before eventually
          // passing it as a reference.
          new(field) std::string();                         // 1
        }
        deser >> *static_cast<std::string *>(field);        // 2
        ...
    
      inline void deserialize(std::string & x)
      {
        const uint32_t sz = deserialize_len(sizeof(char));
        if (sz == 0) {
          x = std::string("");
        } else {
          validate_str(sz);
          x = std::string(data + pos, sz - 1);              // 3
        }
        pos += sz;
      }
    

    I detected the following code also leak memory:

    void * pbuf = (void*)malloc(100);
    new(pbuf) std::string();
    // *static_cast<std::string*>(pbuf) = "123";
    *static_cast<std::string*>(pbuf) = "12345678901234567890";    // valgrind report this as memory leak.
    free(pbuf);
    
  4. create_message_type_support (rmw_cycledds)

    It seems that https://github.com/ros2/rmw_cyclonedds/blob/49a994e41808b2ebab37b4fc841792dbf6194aa4/rmw_cyclonedds_cpp/src/serdata.cpp#L429-L436 not to delete type_support_.

      if (tp->type_support.type_support_) {
        if (using_introspection_c_typesupport(tp->type_support.typesupport_identifier_)) {
          delete static_cast<MessageTypeSupport_c*>(tp->type_support.type_support_);
        } else if (using_introspection_cpp_typesupport(tp->type_support.typesupport_identifier_)) {
          delete static_cast<MessageTypeSupport_cpp*>(tp->type_support.type_support_);
        }
        tp->type_support.type_support_ = NULL;
      }
    

    To support this, we need to add virtual destructor into TypeSupport.

What do you think about above ideas? If you have some suggestions, could you please share them with me?

@iuhilnehc-ynos
Copy link
Collaborator

I'll try to find a method to solve item 3.

@iuhilnehc-ynos
Copy link
Collaborator

About item 3, it needs static_cast<std::string*>(pbuf)->~basic_string<char>(); before free.
But It seems hard to put it into cyclonedds ( or rmw_cyclonedds).

@fujitatomoya
Copy link
Collaborator

rcl_parse_arguments (not detect. maybe some commit fixed it.)

I confirmed that we don't see this memory leak with ros2/ros2@91d8a43

@fujitatomoya
Copy link
Collaborator

@iuhilnehc-ynos
CC: @Karsten1987

rmw_fastrtps_shared_cpp::__rmw_create_wait_set
It seems that https://github.com/ros2/rmw_fastrtps/blob/0d039e6d0f944448ba2d26a6d0b83795745f60fc/rmw_fastrtps_shared_cpp/src/listener_thread.cpp#L171-L175 should move after https://github.com/ros2/rmw_fastrtps/blob/0d039e6d0f944448ba2d26a6d0b83795745f60fc/rmw_fastrtps_shared_cpp/src/listener_thread.cpp#L136-L146.

I agree on this. if the message taken via rmw_take is local(same participant), it will continue the loop w/o destroying wait_set.

I did confirm that following patch can avert the memory leak problem observed in valgrind.

diff --git a/rmw_fastrtps_shared_cpp/src/listener_thread.cpp b/rmw_fastrtps_shared_cpp/src/listener_thread.cpp
index 8df2bb7..50be5b3 100644
--- a/rmw_fastrtps_shared_cpp/src/listener_thread.cpp
+++ b/rmw_fastrtps_shared_cpp/src/listener_thread.cpp
@@ -144,6 +144,11 @@ node_listener(rmw_context_t * context)
     {
       TERMINATE_THREAD("rmw_wait failed");
     }
+    if (RMW_RET_OK != rmw_fastrtps_shared_cpp::__rmw_destroy_wait_set(
+        context->implementation_identifier, wait_set))
+    {
+      TERMINATE_THREAD("failed to destroy wait set");
+    }
     if (subscriptions_buffer[0]) {
       rmw_dds_common::msg::ParticipantEntitiesInfo msg;
       bool taken;
@@ -168,10 +173,5 @@ node_listener(rmw_context_t * context)
         common_context->graph_cache.update_participant_entities(msg);
       }
     }
-    if (RMW_RET_OK != rmw_fastrtps_shared_cpp::__rmw_destroy_wait_set(
-        context->implementation_identifier, wait_set))
-    {
-      TERMINATE_THREAD("failed to destroy wait set");
-    }
   }
 }

would you create PR?

@Karsten1987
Copy link
Contributor Author

Great that you've found already some potential improvements. Feel free to open a PR on the related repository and link them to this issue.

@iuhilnehc-ynos
Copy link
Collaborator

@fujitatomoya

would you create PR?

Yes, I'll create it later.

@fujitatomoya
Copy link
Collaborator

@Karsten1987

i think you can close this issue, if we are missing something, let us know.

@iuhilnehc-ynos
Copy link
Collaborator

iuhilnehc-ynos commented Sep 3, 2020

@fujitatomoya

Actually, I am ready to fix all tests in rcl.

make it short

./test_lexer_lookahead__rmw_fastrtps_dynamic_cpp
./test_subscription__rmw_cyclonedds_cpp
./test_info_by_topic__rmw_cyclonedds_cpp
./service_fixture__rmw_fastrtps_cpp
./test_rmw_impl_id_check_exe
./test_logging_rosout__rmw_fastrtps_dynamic_cpp
./test_timer__rmw_fastrtps_cpp
./service_fixture__rmw_fastrtps_dynamic_cpp
./test_lexer_lookahead__rmw_cyclonedds_cpp
./test_rmw_impl_id_check_func__rmw_cyclonedds_cpp
./test_count_matched__rmw_fastrtps_dynamic_cpp
./test_subscription__rmw_fastrtps_cpp
./client_fixture__rmw_fastrtps_cpp
./test_publisher__rmw_fastrtps_dynamic_cpp
./test_context__rmw_fastrtps_dynamic_cpp
./test_service__rmw_fastrtps_dynamic_cpp
./test_service__rmw_cyclonedds_cpp
./test_arguments__rmw_cyclonedds_cpp
./test_get_node_names__rmw_fastrtps_dynamic_cpp
./test_lexer__rmw_fastrtps_dynamic_cpp
./test_context__rmw_cyclonedds_cpp
./test_info_by_topic__rmw_fastrtps_cpp
./test_timer__rmw_cyclonedds_cpp
./test_publisher__rmw_fastrtps_cpp
./test_node__rmw_fastrtps_dynamic_cpp
./test_publisher__rmw_cyclonedds_cpp
./test_arguments__rmw_fastrtps_cpp
./test_timer__rmw_fastrtps_dynamic_cpp
./test_client__rmw_cyclonedds_cpp
./test_namespace__rmw_fastrtps_dynamic_cpp
./test_info_by_topic__rmw_fastrtps_dynamic_cpp
./test_namespace__rmw_fastrtps_cpp
./test_graph__rmw_fastrtps_cpp
./test_rmw_impl_id_check_func__rmw_fastrtps_dynamic_cpp
./test_validate_enclave_name
./test_common
./test_node__rmw_fastrtps_cpp
./test_guard_condition__rmw_fastrtps_dynamic_cpp
./test_arguments__rmw_fastrtps_dynamic_cpp
./test_remap__rmw_fastrtps_cpp
./test_get_actual_qos__rmw_fastrtps_dynamic_cpp
./test_node__rmw_cyclonedds_cpp
./test_events__rmw_fastrtps_cpp
./test_time__rmw_cyclonedds_cpp
./test_time__rmw_fastrtps_cpp
./test_wait__rmw_fastrtps_cpp
./test_validate_topic_name
./test_remap__rmw_cyclonedds_cpp
./test_lexer_lookahead__rmw_fastrtps_cpp
./test_remap_integration__rmw_fastrtps_dynamic_cpp
./test_get_node_names__rmw_cyclonedds_cpp
./test_remap_integration__rmw_fastrtps_cpp
./test_security
./test_init__rmw_fastrtps_cpp
./test_rmw_impl_id_check_func__rmw_fastrtps_cpp
./test_context__rmw_fastrtps_cpp
./test_wait__rmw_cyclonedds_cpp
./test_log_level
./test_expand_topic_name
./test_localhost
./test_wait__rmw_fastrtps_dynamic_cpp
./test_remap_integration__rmw_cyclonedds_cpp
./test_graph__rmw_cyclonedds_cpp
./test_get_actual_qos__rmw_fastrtps_cpp
./client_fixture__rmw_fastrtps_dynamic_cpp
./test_client__rmw_fastrtps_dynamic_cpp
./test_time__rmw_fastrtps_dynamic_cpp
./test_lexer__rmw_cyclonedds_cpp
./test_events__rmw_cyclonedds_cpp
./client_fixture__rmw_cyclonedds_cpp
./test_client__rmw_fastrtps_cpp
./test_guard_condition__rmw_cyclonedds_cpp
./test_domain_id
./test_remap__rmw_fastrtps_dynamic_cpp
./test_logging_rosout__rmw_fastrtps_cpp
./test_count_matched__rmw_cyclonedds_cpp
./test_init__rmw_cyclonedds_cpp
./test_guard_condition__rmw_fastrtps_cpp
./test_subscription__rmw_fastrtps_dynamic_cpp
./service_fixture__rmw_cyclonedds_cpp
./test_lexer__rmw_fastrtps_cpp
./test_namespace__rmw_cyclonedds_cpp
./test_get_node_names__rmw_fastrtps_cpp
./test_logging
./test_init__rmw_fastrtps_dynamic_cpp
./test_graph__rmw_fastrtps_dynamic_cpp
./test_count_matched__rmw_fastrtps_cpp
./test_get_actual_qos__rmw_cyclonedds_cpp
./test_logging_rosout__rmw_cyclonedds_cpp
./test_service__rmw_fastrtps_cpp
./test_events__rmw_fastrtps_dynamic_cpp

@fujitatomoya
Copy link
Collaborator

@iuhilnehc-ynos

in that case, we should make another issue to address? i thought this issue is to fix the #721 (comment). i think that it would be nice to keep the history clearly. and maybe the problem could not be rcl, so maybe we could create meta-ticket to manage sub-issues for each component? what do you think?

@iuhilnehc-ynos
Copy link
Collaborator

iuhilnehc-ynos commented Sep 3, 2020

@fujitatomoya

I was thinking to make a new issue and then relate it to this manager issue if I found that memory leaks in a specific test executable file.

i think that it would be nice to keep the history clearly.

I agree with it.

@Barry-Xu-2018
Copy link
Contributor

Barry-Xu-2018 commented Sep 4, 2020

@Karsten1987 @fujitatomoya @iuhilnehc-ynos

Based master branch, we find memory leak in below test cases.
We will create sub-issues for these memory leak problems. Now #789 has been created by iuhilnehc-ynos.

test executable file memory leak Created sub-issues(Created PR)
./test_client__rmw_cyclonedds_cpp YES ros2/rmw_cyclonedds#235(ros2/rmw_cyclonedds#236)
./test_events__rmw_cyclonedds_cpp YES #789(#790)
./test_events__rmw_fastrtps_cpp YES #789(#790)
./test_events__rmw_fastrtps_dynamic_cpp YES #789(#790)
./test_expand_topic_name YES #791
./test_get_node_names__rmw_cyclonedds_cpp YES #791
./test_get_node_names__rmw_fastrtps_cpp YES #791
./test_get_node_names__rmw_fastrtps_dynamic_cpp YES #791
./test_graph__rmw_cyclonedds_cpp YES #791
./test_graph__rmw_fastrtps_cpp YES #791
./test_graph__rmw_fastrtps_dynamic_cpp YES #791
./test_info_by_topic__rmw_cyclonedds_cpp YES Since valgrind trace execution, execution become slow which lead ASSERT_EQ() failure and directly exit without clearing resource. Not a real memory leak.
./test_init__rmw_cyclonedds_cpp YES #799(#800)
./test_init__rmw_fastrtps_cpp YES #799(#800)
./test_init__rmw_fastrtps_dynamic_cpp YES #799(#800)
./test_log_level YES #791
./test_namespace__rmw_cyclonedds_cpp YES ros2/rmw_cyclonedds#235(ros2/rmw_cyclonedds#236)
./test_node__rmw_fastrtps_cpp YES ros2/rmw_fastrtps#433(ros2/rmw_fastrtps#434)
./test_node__rmw_fastrtps_dynamic_cpp YES ros2/rmw_fastrtps#433(ros2/rmw_fastrtps#434)
./test_publisher__rmw_cyclonedds_cpp YES #793(#794)
Fix test codes (#801)
./test_publisher__rmw_fastrtps_cpp YES #793(#794)
Fix test codes (#801)
./test_publisher__rmw_fastrtps_dynamic_cpp YES #793(#794)
Fix test codes (#801)
./test_security YES #791
./test_service__rmw_cyclonedds_cpp YES #791
./test_service__rmw_fastrtps_cpp YES #791
./test_service__rmw_fastrtps_dynamic_cpp YES #791
./test_subscription__rmw_cyclonedds_cpp YES #793(#794)
Fix test codes (#801)
./test_subscription__rmw_fastrtps_cpp YES #793(#794)
Fix test codes (#801)
./test_subscription__rmw_fastrtps_dynamic_cpp YES #793(#794)
Fix test codes (#801)
./test_wait__rmw_cyclonedds_cpp YES #721 (comment)
./test_wait__rmw_fastrtps_cpp YES #721 (comment)
./test_wait__rmw_fastrtps_dynamic_cpp YES #721 (comment)

@fujitatomoya
Copy link
Collaborator

@Barry-Xu-2018
CC: @iuhilnehc-ynos @Ada-King

sounds good to me, thanks. but maybe maintainer would prefer to create dedicated issue.

@Barry-Xu-2018
Copy link
Contributor

Barry-Xu-2018 commented Sep 7, 2020

@Karsten1987 @fujitatomoya

@iuhilnehc-ynos and I have finished analyzing all memory leak cases in above table.
For current implementation problem (Not test codes problem), we create below 2 issues. Other problems are related to test codes, etc. We wait for Karsten1987 suggestion on how to deal with these problems (Whether create sub-issues ?)

@Barry-Xu-2018
Copy link
Contributor

The cause for test_wait__rmw_cyclonedds_cpp/test_wait__rmw_fastrtps_cpp/ test_wait__rmw_fastrtps_dynamic_cpp

The test leading memory leak is

TEST_F(CLASSNAME(WaitSetTestFixture, RMW_IMPLEMENTATION), test_failed_resize) {
// Initialize a wait set with a subscription and then resize it to zero.
rcl_allocator_t allocator = get_failing_allocator();
rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set();
set_failing_allocator_is_failing(allocator, false);
rcl_ret_t ret =
rcl_wait_set_init(&wait_set, 1, 1, 1, 1, 1, 0, context_ptr, allocator);
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
set_failing_allocator_is_failing(allocator, true);
ret = rcl_wait_set_resize(&wait_set, 0, 1, 0, 0, 0, 0);
EXPECT_EQ(RCL_RET_BAD_ALLOC, ret);
rcl_reset_error();
set_failing_allocator_is_failing(allocator, false);
ret = rcl_wait_set_fini(&wait_set);
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
}

After call set_failing_allocator_is_failing(allocator, true);, rcl_wait_set_resize() will execute below macro.

rcl/rcl/src/rcl/wait.c

Lines 385 to 391 in 8bcada7

SET_RESIZE(
subscription,
SET_RESIZE_RMW_DEALLOC(
rmw_subscriptions.subscribers, rmw_subscriptions.subscriber_count),
SET_RESIZE_RMW_REALLOC(
subscription, rmw_subscriptions.subscribers, rmw_subscriptions.subscriber_count)
);

For SET_RESIZE_RMW_DEALLOC, It tries to free allocated memory but fails.
And pointer to allocated memory is set to NULL. This leads memory leak.

rcl/rcl/src/rcl/wait.c

Lines 288 to 294 in 8bcada7

#define SET_RESIZE_RMW_DEALLOC(RMWStorage, RMWCount) \
/* Also deallocate the rmw storage. */ \
if (wait_set->impl->RMWStorage) { \
allocator.deallocate((void *)wait_set->impl->RMWStorage, allocator.state); \
wait_set->impl->RMWStorage = NULL; \
wait_set->impl->RMWCount = 0; \
}

allocator.reallocate() return fail. And count is set to 0. This leads memory leak.

rcl/rcl/src/rcl/wait.c

Lines 296 to 307 in 8bcada7

#define SET_RESIZE_RMW_REALLOC(Type, RMWStorage, RMWCount) \
/* Also resize the rmw storage. */ \
wait_set->impl->RMWCount = 0; \
wait_set->impl->RMWStorage = (void **)allocator.reallocate( \
wait_set->impl->RMWStorage, sizeof(void *) * Type ## s_size, allocator.state); \
if (!wait_set->impl->RMWStorage) { \
allocator.deallocate((void *)wait_set->Type ## s, allocator.state); \
wait_set->Type ## s = NULL; \
wait_set->size_of_ ## Type ## s = 0; \
RCL_SET_ERROR_MSG("allocating memory failed"); \
return RCL_RET_BAD_ALLOC; \
} \

If modify below 2 points in test_wait.cpp, memory leak can be avoided.

void *
failing_realloc(void * pointer, size_t size, void * state)
{
  if (((__failing_allocator_state *)state)->is_failing) {
    // New added below line to make sure free allocated memory
    rcutils_get_default_allocator().deallocate(pointer, rcutils_get_default_allocator().state);
    return nullptr;
  }
  return rcutils_get_default_allocator().reallocate(
    pointer, size, rcutils_get_default_allocator().state);
}

void
failing_free(void * pointer, void * state)
{
  #if 0 // Avoid exiting to make sure free allocated memory
  if (((__failing_allocator_state *)state)->is_failing) {
    return;
  }
  #endif
  RCUTILS_UNUSED(state);
  rcutils_get_default_allocator().deallocate(pointer, rcutils_get_default_allocator().state);
}

@Barry-Xu-2018
Copy link
Contributor

@Karsten1987 @fujitatomoya

All analysis has been finished.
Please look at table in #721 (comment).
The problem which we think it should fix has created issue and submitted fix.
Other problem which we think it doesn't need to fix are explained in that table.

@fujitatomoya
Copy link
Collaborator

If modify below 2 points in test_wait.cpp, memory leak can be avoided.

  • failing_realloc()
    lgtm, i think this makes sense, deallocate is necessary to free previous memory, and the fails on realloc.

  • failing_free()
    with your fix, it doesn't actually fail free memory. but failing free memory is supposed to mean memory leak to me. I do not see the purpose of failing_allocator is not memory leak, so i think i agree with it.

I'd like to hear from others though.

@Barry-Xu-2018
Copy link
Contributor

@fujitatomoya

failing_realloc()
lgtm, i think this makes sense, deallocate is necessary to free previous memory, and the fails on realloc.

Refer to the manual of remalloc(), there is below sentence
If realloc() fails, the original block is left untouched; it is not freed or moved.

So failing_realloc() doesn't free original block is the same behavior like realloc().
Beside, consider failing_free(), I think current test with memory leak is acceptable.
Therefore, I tend to keep it as it is (Need not to fix anything)

@fujitatomoya
Copy link
Collaborator

@Barry-Xu-2018

okay, i think memory leak could be acceptable only in test with purpose, if we keep the consistency of failing functions.
but at least we should be able to tell this problem for future because we do not want to re-do the same investigation when valgrind detects it. at least doc should be added in test code to tell us test can lead to memory leak.

anyway, we can wait for the comments from other people on this!

@fujitatomoya
Copy link
Collaborator

@Karsten1987 @Barry-Xu-2018

i think we can close this, since #721 (comment) all problems have been addressed.

@fujitatomoya
Copy link
Collaborator

@Karsten1987

ping friendly.

@clalancette
Copy link
Contributor

I'm going to go ahead and close this; please feel free to reopen if that is in error. Thanks for all of the work fixing this!

@fujitatomoya
Copy link
Collaborator

@clalancette thanks for checking on this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants