implement memory tools on linux and fixes
This commit is contained in:
parent
536b80cac2
commit
c4d3022104
8 changed files with 75 additions and 22 deletions
|
@ -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")
|
||||||
|
|
|
@ -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]));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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))
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
|
@ -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;}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue