From c4d30221047e54896b384b6866a9d00dec0c6207 Mon Sep 17 00:00:00 2001 From: William Woodall Date: Mon, 14 Dec 2015 16:08:45 -0800 Subject: [PATCH] implement memory tools on linux and fixes --- rcl/CMakeLists.txt | 3 -- rcl/src/rcl/rcl.c | 6 ++- rcl/src/rcl/stdatomic_helper/gcc/stdatomic.h | 18 ++++---- rcl/src/rcl/time_unix.c | 6 ++- rcl/src/rcl/wait.c | 10 +++-- rcl/test/CMakeLists.txt | 6 ++- rcl/test/memory_tools.cpp | 46 +++++++++++++++++++- rcl/test/memory_tools_common.cpp | 2 +- 8 files changed, 75 insertions(+), 22 deletions(-) diff --git a/rcl/CMakeLists.txt b/rcl/CMakeLists.txt index f4cf14a..3baf6cb 100644 --- a/rcl/CMakeLists.txt +++ b/rcl/CMakeLists.txt @@ -37,9 +37,6 @@ macro(target) "${rmw_implementation}" ) - if(NOT WIN32) - set_target_properties(${PROJECT_NAME}${target_suffix} PROPERTIES COMPILE_FLAGS "-std=c11") - endif() # Causes the visibility macros to use dllexport rather than dllimport, # which is appropriate when building the dll but not consuming it. target_compile_definitions(${PROJECT_NAME}${target_suffix} PRIVATE "RCL_BUILDING_LIBRARY") diff --git a/rcl/src/rcl/rcl.c b/rcl/src/rcl/rcl.c index 72a8a12..839a81c 100644 --- a/rcl/src/rcl/rcl.c +++ b/rcl/src/rcl/rcl.c @@ -35,7 +35,8 @@ static void __clean_up_init() { if (__rcl_argv) { - for (size_t i = 0; i < __rcl_argc; ++i) { + size_t i; + for (i = 0; i < __rcl_argc; ++i) { if (__rcl_argv[i]) { __rcl_allocator.deallocate(__rcl_argv[i], __rcl_allocator.state); } @@ -62,7 +63,8 @@ rcl_init(int argc, char ** argv, rcl_allocator_t allocator) goto fail; } memset(__rcl_argv, 0, sizeof(char **) * argc); - for (size_t i = 0; i < argc; ++i) { + size_t i; + for (i = 0; i < argc; ++i) { __rcl_argv[i] = (char *)__rcl_allocator.allocate(strlen(argv[i]), __rcl_allocator.state); memcpy(__rcl_argv[i], argv[i], strlen(argv[i])); } diff --git a/rcl/src/rcl/stdatomic_helper/gcc/stdatomic.h b/rcl/src/rcl/stdatomic_helper/gcc/stdatomic.h index e6c318a..9b6cb20 100644 --- a/rcl/src/rcl/stdatomic_helper/gcc/stdatomic.h +++ b/rcl/src/rcl/stdatomic_helper/gcc/stdatomic.h @@ -20,6 +20,8 @@ * https://github.com/freebsd/freebsd/blob/release/10.2.0/sys/sys/stdatomic.h */ +// *INDENT-OFF* (disable uncrustify) + /**** Start included file. ****/ /* @@ -69,7 +71,7 @@ * $FreeBSD: src/include/stdatomic.h,v 1.10.2.2 2012/05/30 19:21:54 theraven Exp $ */ -#ifndef _STDATOMIC_H_ +#ifndef _STDATOMIC_H_ // NOLINT #define _STDATOMIC_H_ #include @@ -199,14 +201,14 @@ typedef _Atomic(_Bool) atomic_bool; typedef _Atomic(char) atomic_char; typedef _Atomic(signed char) atomic_schar; typedef _Atomic(unsigned char) atomic_uchar; -typedef _Atomic(short) atomic_short; -typedef _Atomic(unsigned short) atomic_ushort; +typedef _Atomic(short) atomic_short; // NOLINT +typedef _Atomic(unsigned short) atomic_ushort; // NOLINT typedef _Atomic(int) atomic_int; typedef _Atomic(unsigned int) atomic_uint; -typedef _Atomic(long) atomic_long; -typedef _Atomic(unsigned long) atomic_ulong; -typedef _Atomic(long long) atomic_llong; -typedef _Atomic(unsigned long long) atomic_ullong; +typedef _Atomic(long) atomic_long; // NOLINT +typedef _Atomic(unsigned long) atomic_ulong; // NOLINT +typedef _Atomic(long long) atomic_llong; // NOLINT +typedef _Atomic(unsigned long long) atomic_ullong; // NOLINT #if 0 typedef _Atomic(char16_t) atomic_char16_t; typedef _Atomic(char32_t) atomic_char32_t; @@ -390,4 +392,4 @@ typedef atomic_bool atomic_flag; #define atomic_flag_test_and_set(object) \ atomic_flag_test_and_set_explicit(object, memory_order_seq_cst) -#endif /* !_STDATOMIC_H_ */ \ No newline at end of file +#endif /* !_STDATOMIC_H_ */ // NOLINT diff --git a/rcl/src/rcl/time_unix.c b/rcl/src/rcl/time_unix.c index c89f295..7cd438d 100644 --- a/rcl/src/rcl/time_unix.c +++ b/rcl/src/rcl/time_unix.c @@ -29,16 +29,18 @@ extern "C" #endif #include #include +#include #include "./common.h" #include "rcl/error_handling.h" +#if !defined(__MACH__) // Assume clock_get_time is available on OS X. // This id an appropriate check for clock_gettime() according to: // http://man7.org/linux/man-pages/man2/clock_gettime.2.html -#define HAS_CLOCK_GETTIME (_POSIX_C_SOURCE >= 199309L) -#if !HAS_CLOCK_GETTIME && !defined(__MACH__) +#if (!defined(_POSIX_TIMERS) || !_POSIX_TIMERS) #error no monotonic clock function available #endif +#endif #define __WOULD_BE_NEGATIVE(seconds, subseconds) (seconds < 0 || (subseconds < 0 && seconds == 0)) diff --git a/rcl/src/rcl/wait.c b/rcl/src/rcl/wait.c index 9e6589f..c14178a 100644 --- a/rcl/src/rcl/wait.c +++ b/rcl/src/rcl/wait.c @@ -369,7 +369,8 @@ rcl_wait(rcl_wait_set_t * wait_set, int64_t timeout) // Determine the nearest timeout (given or a timer). uint64_t min_timeout = timeout; if (min_timeout > 0) { // Do not consider timer timeouts if non-blocking. - for (size_t i = 0; i < wait_set->size_of_timers; ++i) { + size_t i; + for (i = 0; i < wait_set->size_of_timers; ++i) { if (!wait_set->timers[i]) { continue; // Skip NULL timers. } @@ -407,7 +408,8 @@ rcl_wait(rcl_wait_set_t * wait_set, int64_t timeout) return RCL_RET_ERROR; } // Check for ready timers next, and set not ready timers to NULL. - for (size_t i = 0; i < wait_set->size_of_timers; ++i) { + size_t i; + for (i = 0; i < wait_set->size_of_timers; ++i) { bool is_ready = false; rcl_ret_t ret = rcl_timer_is_ready(wait_set->timers[i], &is_ready); if (ret != RCL_RET_OK) { @@ -425,14 +427,14 @@ rcl_wait(rcl_wait_set_t * wait_set, int64_t timeout) return RCL_RET_TIMEOUT; } // Set corresponding rcl subscription handles NULL. - for (size_t i = 0; i < wait_set->size_of_subscriptions; ++i) { + for (i = 0; i < wait_set->size_of_subscriptions; ++i) { assert(i < wait_set->impl->rmw_subscriptions.subscriber_count); // Defensive. if (!wait_set->impl->rmw_subscriptions.subscribers[i]) { wait_set->subscriptions[i] = NULL; } } // Set corresponding rcl guard_condition handles NULL. - for (size_t i = 0; i < wait_set->size_of_guard_conditions; ++i) { + for (i = 0; i < wait_set->size_of_guard_conditions; ++i) { assert(i < wait_set->impl->rmw_guard_conditions.guard_condition_count); // Defensive. if (!wait_set->impl->rmw_guard_conditions.guard_conditions[i]) { wait_set->guard_conditions[i] = NULL; diff --git a/rcl/test/CMakeLists.txt b/rcl/test/CMakeLists.txt index 5fbd8dc..11f393a 100644 --- a/rcl/test/CMakeLists.txt +++ b/rcl/test/CMakeLists.txt @@ -15,7 +15,11 @@ if(AMENT_ENABLE_TESTING) if(NOT WIN32) set_target_properties(${PROJECT_NAME}_memory_tools PROPERTIES COMPILE_FLAGS "-std=c++11") endif() - target_link_libraries(${PROJECT_NAME}_memory_tools ${GTEST_LIBRARIES} ${extra_test_libraries}) + if(UNIX AND NOT APPLE) + list(APPEND extra_test_libraries dl) + list(APPEND extra_memory_tools_env DL_PRELOAD=$) + endif() + target_link_libraries(${PROJECT_NAME}_memory_tools ${extra_test_libraries}) target_compile_definitions(${PROJECT_NAME}_memory_tools PRIVATE "RCL_MEMORY_TOOLS_BUILDING_DLL") list(APPEND extra_test_libraries ${PROJECT_NAME}_memory_tools) diff --git a/rcl/test/memory_tools.cpp b/rcl/test/memory_tools.cpp index 5e1887d..e87c67e 100644 --- a/rcl/test/memory_tools.cpp +++ b/rcl/test/memory_tools.cpp @@ -17,10 +17,54 @@ * Begin Linux *****************************************************************************/ -// TODO(wjwwood): install custom malloc (and others) for Linux. +#include +#include +#include #include "./memory_tools_common.cpp" +void * +malloc(size_t size) +{ + void * (* libc_malloc)(size_t) = (void *(*)(size_t))dlsym(RTLD_NEXT, "malloc"); + if (enabled.load()) { + return custom_malloc(size); + } + return libc_malloc(size); +} + +void * +realloc(void * pointer, size_t size) +{ + void * (* libc_realloc)(void *, size_t) = (void *(*)(void *, size_t))dlsym(RTLD_NEXT, "realloc"); + if (enabled.load()) { + return custom_realloc(pointer, size); + } + return libc_realloc(pointer, size); +} + +void +free(void * pointer) +{ + void (* libc_free)(void *) = (void (*)(void *))dlsym(RTLD_NEXT, "free"); + if (enabled.load()) { + return custom_free(pointer); + } + return libc_free(pointer); +} + +void start_memory_checking() +{ + printf("starting memory checking...\n"); + enabled.store(true); +} + +void stop_memory_checking() +{ + printf("stopping memory checking...\n"); + enabled.store(false); +} + /****************************************************************************** * End Linux *****************************************************************************/ diff --git a/rcl/test/memory_tools_common.cpp b/rcl/test/memory_tools_common.cpp index ab49f65..30949b4 100644 --- a/rcl/test/memory_tools_common.cpp +++ b/rcl/test/memory_tools_common.cpp @@ -142,8 +142,8 @@ custom_free(void * memory) (*unexpected_free_callback)(); } } - free(memory); MALLOC_PRINTF("free expected(%s): %p\n", malloc_expected ? "true " : "false", memory); + free(memory); } void assert_no_malloc_begin() {malloc_expected = false;}