implement memory tools on linux and fixes

This commit is contained in:
William Woodall 2015-12-14 16:08:45 -08:00
parent 536b80cac2
commit c4d3022104
8 changed files with 75 additions and 22 deletions

View file

@ -37,9 +37,6 @@ macro(target)
"${rmw_implementation}" "${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, # Causes the visibility macros to use dllexport rather than dllimport,
# which is appropriate when building the dll but not consuming it. # which is appropriate when building the dll but not consuming it.
target_compile_definitions(${PROJECT_NAME}${target_suffix} PRIVATE "RCL_BUILDING_LIBRARY") target_compile_definitions(${PROJECT_NAME}${target_suffix} PRIVATE "RCL_BUILDING_LIBRARY")

View file

@ -35,7 +35,8 @@ static void
__clean_up_init() __clean_up_init()
{ {
if (__rcl_argv) { 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]) { if (__rcl_argv[i]) {
__rcl_allocator.deallocate(__rcl_argv[i], __rcl_allocator.state); __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; goto fail;
} }
memset(__rcl_argv, 0, sizeof(char **) * argc); 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); __rcl_argv[i] = (char *)__rcl_allocator.allocate(strlen(argv[i]), __rcl_allocator.state);
memcpy(__rcl_argv[i], argv[i], strlen(argv[i])); memcpy(__rcl_argv[i], argv[i], strlen(argv[i]));
} }

View file

@ -20,6 +20,8 @@
* https://github.com/freebsd/freebsd/blob/release/10.2.0/sys/sys/stdatomic.h * https://github.com/freebsd/freebsd/blob/release/10.2.0/sys/sys/stdatomic.h
*/ */
// *INDENT-OFF* (disable uncrustify)
/**** Start included file. ****/ /**** 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 $ * $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_ #define _STDATOMIC_H_
#include <stddef.h> #include <stddef.h>
@ -199,14 +201,14 @@ typedef _Atomic(_Bool) atomic_bool;
typedef _Atomic(char) atomic_char; typedef _Atomic(char) atomic_char;
typedef _Atomic(signed char) atomic_schar; typedef _Atomic(signed char) atomic_schar;
typedef _Atomic(unsigned char) atomic_uchar; typedef _Atomic(unsigned char) atomic_uchar;
typedef _Atomic(short) atomic_short; typedef _Atomic(short) atomic_short; // NOLINT
typedef _Atomic(unsigned short) atomic_ushort; typedef _Atomic(unsigned short) atomic_ushort; // NOLINT
typedef _Atomic(int) atomic_int; typedef _Atomic(int) atomic_int;
typedef _Atomic(unsigned int) atomic_uint; typedef _Atomic(unsigned int) atomic_uint;
typedef _Atomic(long) atomic_long; typedef _Atomic(long) atomic_long; // NOLINT
typedef _Atomic(unsigned long) atomic_ulong; typedef _Atomic(unsigned long) atomic_ulong; // NOLINT
typedef _Atomic(long long) atomic_llong; typedef _Atomic(long long) atomic_llong; // NOLINT
typedef _Atomic(unsigned long long) atomic_ullong; typedef _Atomic(unsigned long long) atomic_ullong; // NOLINT
#if 0 #if 0
typedef _Atomic(char16_t) atomic_char16_t; typedef _Atomic(char16_t) atomic_char16_t;
typedef _Atomic(char32_t) atomic_char32_t; typedef _Atomic(char32_t) atomic_char32_t;
@ -390,4 +392,4 @@ typedef atomic_bool atomic_flag;
#define atomic_flag_test_and_set(object) \ #define atomic_flag_test_and_set(object) \
atomic_flag_test_and_set_explicit(object, memory_order_seq_cst) atomic_flag_test_and_set_explicit(object, memory_order_seq_cst)
#endif /* !_STDATOMIC_H_ */ #endif /* !_STDATOMIC_H_ */ // NOLINT

View file

@ -29,16 +29,18 @@ extern "C"
#endif #endif
#include <math.h> #include <math.h>
#include <time.h> #include <time.h>
#include <unistd.h>
#include "./common.h" #include "./common.h"
#include "rcl/error_handling.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: // This id an appropriate check for clock_gettime() according to:
// http://man7.org/linux/man-pages/man2/clock_gettime.2.html // http://man7.org/linux/man-pages/man2/clock_gettime.2.html
#define HAS_CLOCK_GETTIME (_POSIX_C_SOURCE >= 199309L) #if (!defined(_POSIX_TIMERS) || !_POSIX_TIMERS)
#if !HAS_CLOCK_GETTIME && !defined(__MACH__)
#error no monotonic clock function available #error no monotonic clock function available
#endif #endif
#endif
#define __WOULD_BE_NEGATIVE(seconds, subseconds) (seconds < 0 || (subseconds < 0 && seconds == 0)) #define __WOULD_BE_NEGATIVE(seconds, subseconds) (seconds < 0 || (subseconds < 0 && seconds == 0))

View file

@ -369,7 +369,8 @@ rcl_wait(rcl_wait_set_t * wait_set, int64_t timeout)
// Determine the nearest timeout (given or a timer). // Determine the nearest timeout (given or a timer).
uint64_t min_timeout = timeout; uint64_t min_timeout = timeout;
if (min_timeout > 0) { // Do not consider timer timeouts if non-blocking. 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]) { if (!wait_set->timers[i]) {
continue; // Skip NULL timers. continue; // Skip NULL timers.
} }
@ -407,7 +408,8 @@ rcl_wait(rcl_wait_set_t * wait_set, int64_t timeout)
return RCL_RET_ERROR; return RCL_RET_ERROR;
} }
// Check for ready timers next, and set not ready timers to NULL. // 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; bool is_ready = false;
rcl_ret_t ret = rcl_timer_is_ready(wait_set->timers[i], &is_ready); rcl_ret_t ret = rcl_timer_is_ready(wait_set->timers[i], &is_ready);
if (ret != RCL_RET_OK) { if (ret != RCL_RET_OK) {
@ -425,14 +427,14 @@ rcl_wait(rcl_wait_set_t * wait_set, int64_t timeout)
return RCL_RET_TIMEOUT; return RCL_RET_TIMEOUT;
} }
// Set corresponding rcl subscription handles NULL. // 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. assert(i < wait_set->impl->rmw_subscriptions.subscriber_count); // Defensive.
if (!wait_set->impl->rmw_subscriptions.subscribers[i]) { if (!wait_set->impl->rmw_subscriptions.subscribers[i]) {
wait_set->subscriptions[i] = NULL; wait_set->subscriptions[i] = NULL;
} }
} }
// Set corresponding rcl guard_condition handles 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. assert(i < wait_set->impl->rmw_guard_conditions.guard_condition_count); // Defensive.
if (!wait_set->impl->rmw_guard_conditions.guard_conditions[i]) { if (!wait_set->impl->rmw_guard_conditions.guard_conditions[i]) {
wait_set->guard_conditions[i] = NULL; wait_set->guard_conditions[i] = NULL;

View file

@ -15,7 +15,11 @@ if(AMENT_ENABLE_TESTING)
if(NOT WIN32) if(NOT WIN32)
set_target_properties(${PROJECT_NAME}_memory_tools PROPERTIES COMPILE_FLAGS "-std=c++11") set_target_properties(${PROJECT_NAME}_memory_tools PROPERTIES COMPILE_FLAGS "-std=c++11")
endif() 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=$<TARGET_FILE:${PROJECT_NAME}_memory_tools>)
endif()
target_link_libraries(${PROJECT_NAME}_memory_tools ${extra_test_libraries})
target_compile_definitions(${PROJECT_NAME}_memory_tools target_compile_definitions(${PROJECT_NAME}_memory_tools
PRIVATE "RCL_MEMORY_TOOLS_BUILDING_DLL") PRIVATE "RCL_MEMORY_TOOLS_BUILDING_DLL")
list(APPEND extra_test_libraries ${PROJECT_NAME}_memory_tools) list(APPEND extra_test_libraries ${PROJECT_NAME}_memory_tools)

View file

@ -17,10 +17,54 @@
* Begin Linux * Begin Linux
*****************************************************************************/ *****************************************************************************/
// TODO(wjwwood): install custom malloc (and others) for Linux. #include <dlfcn.h>
#include <stdio.h>
#include <malloc.h>
#include "./memory_tools_common.cpp" #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 * End Linux
*****************************************************************************/ *****************************************************************************/

View file

@ -142,8 +142,8 @@ custom_free(void * memory)
(*unexpected_free_callback)(); (*unexpected_free_callback)();
} }
} }
free(memory);
MALLOC_PRINTF("free expected(%s): %p\n", malloc_expected ? "true " : "false", memory); MALLOC_PRINTF("free expected(%s): %p\n", malloc_expected ? "true " : "false", memory);
free(memory);
} }
void assert_no_malloc_begin() {malloc_expected = false;} void assert_no_malloc_begin() {malloc_expected = false;}