From e78e40001879fad06656936f73cc58c03db2cc47 Mon Sep 17 00:00:00 2001 From: Shane Loretz Date: Thu, 6 Sep 2018 14:06:45 -0700 Subject: [PATCH] Null deallocated jump callbacks (#294) * Add failing test for add-remove-add callback * Fix crash when adding callback after last was removed --- rcl/src/rcl/time.c | 1 + rcl/test/rcl/test_time.cpp | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/rcl/src/rcl/time.c b/rcl/src/rcl/time.c index 3beecb8..788a61b 100644 --- a/rcl/src/rcl/time.c +++ b/rcl/src/rcl/time.c @@ -464,6 +464,7 @@ rcl_clock_remove_jump_callback( // Shrink size of the callback array if (clock->num_jump_callbacks == 1) { clock->allocator.deallocate(clock->jump_callbacks, clock->allocator.state); + clock->jump_callbacks = NULL; } else { rcl_jump_callback_info_t * callbacks = clock->allocator.reallocate( clock->jump_callbacks, sizeof(rcl_jump_callback_info_t) * (clock->num_jump_callbacks - 1), diff --git a/rcl/test/rcl/test_time.cpp b/rcl/test/rcl/test_time.cpp index f942101..4e6ef34 100644 --- a/rcl/test/rcl/test_time.cpp +++ b/rcl/test/rcl/test_time.cpp @@ -670,3 +670,33 @@ TEST(CLASSNAME(rcl_time, RMW_IMPLEMENTATION), rcl_clock_remove_jump_callback) { EXPECT_EQ(RCL_RET_OK, rcl_clock_remove_jump_callback(clock, cb, user_data2)); EXPECT_EQ(0u, clock->num_jump_callbacks); } + +TEST(CLASSNAME(rcl_time, RMW_IMPLEMENTATION), add_remove_add_jump_callback) { + rcl_allocator_t allocator = rcl_get_default_allocator(); + rcl_clock_t * clock = + reinterpret_cast(allocator.allocate(sizeof(rcl_clock_t), allocator.state)); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ + allocator.deallocate(clock, allocator.state); + }); + rcl_ret_t retval = rcl_ros_clock_init(clock, &allocator); + ASSERT_EQ(RCL_RET_OK, retval) << rcl_get_error_string_safe(); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ + EXPECT_EQ(RCL_RET_OK, rcl_clock_fini(clock)); + }); + + rcl_jump_threshold_t threshold; + threshold.on_clock_change = false; + threshold.min_forward.nanoseconds = 0; + threshold.min_backward.nanoseconds = 0; + rcl_jump_callback_t cb = reinterpret_cast(0xBEEF); + void * user_data = reinterpret_cast(0xCAFE); + + ASSERT_EQ(RCL_RET_OK, rcl_clock_add_jump_callback(clock, threshold, cb, user_data)) << + rcl_get_error_string_safe(); + EXPECT_EQ(1u, clock->num_jump_callbacks); + EXPECT_EQ(RCL_RET_OK, rcl_clock_remove_jump_callback(clock, cb, user_data)); + EXPECT_EQ(0u, clock->num_jump_callbacks); + EXPECT_EQ(RCL_RET_OK, rcl_clock_add_jump_callback(clock, threshold, cb, user_data)) << + rcl_get_error_string_safe(); + EXPECT_EQ(1u, clock->num_jump_callbacks); +}