From 1f9cfc52c00ee2adc2c360f3c43fc88b30489d3c Mon Sep 17 00:00:00 2001 From: William Woodall Date: Tue, 12 Jun 2018 00:13:13 -0700 Subject: [PATCH] update to use new memory_tools from osrf_testing_tools_cpp (#101) * remove old memory tools * use new memory tools from osrf_testing_tools_cpp * [style] make lines shorter * change logging macro tests to not need to be manually update anymore * skip allocator test on aarch64 too, for now * address comments * fix skipping logic --- CMakeLists.txt | 60 ++++--- package.xml | 1 + test/memory_tools/CMakeLists.txt | 43 ----- test/memory_tools/memory_tools.cpp | 143 --------------- test/memory_tools/memory_tools.hpp | 107 ----------- test/memory_tools/memory_tools_common.cpp | 166 ------------------ .../memory_tools_osx_interpose.cpp | 57 ------ test/memory_tools/scope_exit.hpp | 40 ----- test/memory_tools/test_memory_tools.cpp | 128 -------------- test/test_allocator.cpp | 85 +++++---- test/test_logging_macros.c | 8 +- test/test_time.cpp | 61 +++---- 12 files changed, 114 insertions(+), 785 deletions(-) delete mode 100644 test/memory_tools/CMakeLists.txt delete mode 100644 test/memory_tools/memory_tools.cpp delete mode 100644 test/memory_tools/memory_tools.hpp delete mode 100644 test/memory_tools/memory_tools_common.cpp delete mode 100644 test/memory_tools/memory_tools_osx_interpose.cpp delete mode 100644 test/memory_tools/scope_exit.hpp delete mode 100644 test/memory_tools/test_memory_tools.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 80bd3f84..daba957f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,12 +63,21 @@ configure_file( set(rcutils_module_path ${CMAKE_CURRENT_SOURCE_DIR}) set(python_code "import em" - "em.invoke(['-o', 'include/rcutils/logging_macros.h', '-D', 'rcutils_module_path=\"${rcutils_module_path}\"', '${CMAKE_CURRENT_SOURCE_DIR}/resource/logging_macros.h.em'])") + "\ +em.invoke( \ + [ \ + '-o', 'include/rcutils/logging_macros.h', \ + '-D', 'rcutils_module_path=\"${rcutils_module_path}\"', \ + '${CMAKE_CURRENT_SOURCE_DIR}/resource/logging_macros.h.em' \ + ] \ +)") string(REPLACE ";" "$" python_code "${python_code}") add_custom_command(OUTPUT include/rcutils/logging_macros.h COMMAND ${CMAKE_COMMAND} -E make_directory "include/rcutils" COMMAND ${PYTHON_EXECUTABLE} ARGS -c "${python_code}" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/logging_macros.h.em.watch" "${CMAKE_CURRENT_BINARY_DIR}/logging.py.watch" + DEPENDS + "${CMAKE_CURRENT_BINARY_DIR}/logging_macros.h.em.watch" + "${CMAKE_CURRENT_BINARY_DIR}/logging.py.watch" COMMENT "Expanding logging_macros.h.em" VERBATIM ) @@ -108,7 +117,7 @@ if(BUILD_TESTING) if(ament_cmake_cppcheck_FOUND) ament_cppcheck( TESTNAME "cppcheck_logging_macros" - "${CMAKE_CURRENT_BINARY_DIR}/include/rcutils/logging_macros.h") + "${CMAKE_CURRENT_BINARY_DIR}/include/rcutils/logging_macros.h") endif() if(ament_cmake_cpplint_FOUND) ament_cpplint( @@ -116,40 +125,36 @@ if(BUILD_TESTING) # the generated code might contain longer lines for templated types MAX_LINE_LENGTH 999 ROOT "${CMAKE_CURRENT_BINARY_DIR}/include" - "${CMAKE_CURRENT_BINARY_DIR}/include/rcutils/logging_macros.h") + "${CMAKE_CURRENT_BINARY_DIR}/include/rcutils/logging_macros.h") endif() if(ament_cmake_uncrustify_FOUND) ament_uncrustify( TESTNAME "uncrustify_logging_macros" # the generated code might contain longer lines for templated types MAX_LINE_LENGTH 999 - "${CMAKE_CURRENT_BINARY_DIR}/include/rcutils/logging_macros.h") + "${CMAKE_CURRENT_BINARY_DIR}/include/rcutils/logging_macros.h") endif() - set(extra_test_libraries) - set(extra_test_env) - set(extra_lib_dirs) + find_package(osrf_testing_tools_cpp REQUIRED) + get_target_property(memory_tools_test_env_vars + osrf_testing_tools_cpp::memory_tools LIBRARY_PRELOAD_ENVIRONMENT_VARIABLE) - ament_add_gtest(test_logging test/test_logging.cpp - APPEND_LIBRARY_DIRS ${extra_lib_dirs}) + ament_add_gtest(test_logging test/test_logging.cpp) target_link_libraries(test_logging ${PROJECT_NAME}) add_executable(test_logging_long_messages test/test_logging_long_messages.cpp) target_link_libraries(test_logging_long_messages ${PROJECT_NAME}) ament_add_pytest_test(test_logging_long_messages "test/test_logging_long_messages.py" - APPEND_LIBRARY_DIRS ${extra_lib_dirs} WORKING_DIRECTORY "$" TIMEOUT 10) ament_add_pytest_test(test_logging_output_format "test/test_logging_output_format.py" - APPEND_LIBRARY_DIRS ${extra_lib_dirs} WORKING_DIRECTORY "$" TIMEOUT 10) - ament_add_gmock(test_logging_macros test/test_logging_macros.cpp - APPEND_LIBRARY_DIRS ${extra_lib_dirs}) + ament_add_gmock(test_logging_macros test/test_logging_macros.cpp) target_link_libraries(test_logging_macros ${PROJECT_NAME}) add_executable(test_logging_macros_c test/test_logging_macros.c) @@ -158,12 +163,15 @@ if(BUILD_TESTING) COMMAND "$" GENERATE_RESULT_FOR_RETURN_CODE_ZERO) - # This subdirectory extends both extra_test_libraries, extra_test_env, and extra_lib_dirs. - add_subdirectory(test/memory_tools) - - set(SKIP_TEST_IF_WIN32 "") - if(WIN32) # (memory tools doesn't do anything on Windows) - set(SKIP_TEST_IF_WIN32 "SKIP_TEST") + set(SKIP_TEST_IF_WIN32_OR_AARCH64 "") + if(WIN32) + # (memory tools doesn't do anything on Windows) + set(SKIP_TEST_IF_WIN32_OR_AARCH64 "SKIP_TEST") + endif() + # TODO(wjwwood): reenable for ARM (aarch64) when fixed in osrf_testing_tools_cpp + # see: https://github.com/osrf/osrf_testing_tools_cpp/issues/3 + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") + set(SKIP_TEST_IF_WIN32_OR_AARCH64 "SKIP_TEST") endif() macro(rcutils_custom_add_gtest target) @@ -176,12 +184,11 @@ if(BUILD_TESTING) # Gtests rcutils_custom_add_gtest(test_allocator test/test_allocator.cpp - ENV ${extra_test_env} - APPEND_LIBRARY_DIRS ${extra_lib_dirs} - ${SKIP_TEST_IF_WIN32} + ENV ${memory_tools_test_env_vars} + ${SKIP_TEST_IF_WIN32_OR_AARCH64} ) if(TARGET test_allocator) - target_link_libraries(test_allocator ${PROJECT_NAME} ${extra_test_libraries}) + target_link_libraries(test_allocator ${PROJECT_NAME} osrf_testing_tools_cpp::memory_tools) endif() rcutils_custom_add_gmock(test_error_handling test/test_error_handling.cpp @@ -274,10 +281,9 @@ if(BUILD_TESTING) rcutils_custom_add_gtest(test_time test/test_time.cpp - ENV ${extra_test_env} - APPEND_LIBRARY_DIRS ${extra_lib_dirs}) + ENV ${memory_tools_test_env_vars}) if(TARGET test_time) - target_link_libraries(test_time ${PROJECT_NAME} ${extra_test_libraries}) + target_link_libraries(test_time ${PROJECT_NAME} osrf_testing_tools_cpp::memory_tools) endif() endif() diff --git a/package.xml b/package.xml index cb4f2213..f3889b74 100644 --- a/package.xml +++ b/package.xml @@ -16,6 +16,7 @@ ament_lint_common ament_lint_auto launch_testing + osrf_testing_tools_cpp ament_cmake diff --git a/test/memory_tools/CMakeLists.txt b/test/memory_tools/CMakeLists.txt deleted file mode 100644 index 416b92b9..00000000 --- a/test/memory_tools/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -# Create the memory_tools library which is used by the tests. -add_library(${PROJECT_NAME}_memory_tools memory_tools.cpp) -if(NOT WIN32) - # otherwise the compiler will error since the allocator functions have - # different exception specifiers - set_target_properties(${PROJECT_NAME}_memory_tools - PROPERTIES COMPILE_FLAGS "-Wno-pedantic") -endif() -if(APPLE) - # Create an OS X specific version of the memory tools that does interposing. - # See: http://toves.freeshell.org/interpose/ - add_library(${PROJECT_NAME}_memory_tools_interpose memory_tools_osx_interpose.cpp) - list(APPEND extra_test_libraries ${PROJECT_NAME}_memory_tools_interpose) - list(APPEND extra_test_env - DYLD_INSERT_LIBRARIES=$) -elseif(UNIX) - # On Linux like systems, add dl and use the normal library and DL_PRELOAD. - list(APPEND extra_test_libraries dl) - list(APPEND extra_test_env DL_PRELOAD=$) -endif() -list(APPEND extra_lib_dirs $) -target_link_libraries(${PROJECT_NAME}_memory_tools ${extra_test_libraries}) -target_compile_definitions(${PROJECT_NAME}_memory_tools - PRIVATE "RCUTILS_MEMORY_TOOLS_BUILDING_DLL") -list(APPEND extra_test_libraries ${PROJECT_NAME}_memory_tools) - -# Create tests for the memory tools library. -set(SKIP_TEST "") -if(WIN32) # (memory tools doesn't do anything on Windows) - set(SKIP_TEST "SKIP_TEST") -endif() - -ament_add_gtest(test_memory_tools test_memory_tools.cpp - ENV ${extra_test_env} - ${SKIP_TEST} -) -if(TARGET test_memory_tools) - target_link_libraries(test_memory_tools ${extra_test_libraries}) -endif() - -set(extra_test_libraries ${extra_test_libraries} PARENT_SCOPE) -set(extra_test_env ${extra_test_env} PARENT_SCOPE) -set(extra_lib_dirs ${extra_lib_dirs} PARENT_SCOPE) diff --git a/test/memory_tools/memory_tools.cpp b/test/memory_tools/memory_tools.cpp deleted file mode 100644 index 5468d381..00000000 --- a/test/memory_tools/memory_tools.cpp +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright 2015 Open Source Robotics Foundation, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#if defined(__linux__) -/****************************************************************************** - * Begin 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() -{ - if (!enabled.exchange(true)) { - printf("starting memory checking...\n"); - } -} - -void stop_memory_checking() -{ - if (enabled.exchange(false)) { - printf("stopping memory checking...\n"); - } -} - -/****************************************************************************** - * End Linux - *****************************************************************************/ -#elif defined(__APPLE__) -/****************************************************************************** - * Begin Apple - *****************************************************************************/ - -// The apple implementation is in a separate shared library, loaded with DYLD_INSERT_LIBRARIES. -// Therefore we do not include the common cpp file here. - -void osx_start_memory_checking(); -void osx_stop_memory_checking(); - -void start_memory_checking() -{ - return osx_start_memory_checking(); -} - -void stop_memory_checking() -{ - return osx_stop_memory_checking(); -} - -/****************************************************************************** - * End Apple - *****************************************************************************/ -// #elif defined(_WIN32) -/****************************************************************************** - * Begin Windows - *****************************************************************************/ - -// TODO(wjwwood): install custom malloc (and others) for Windows. - -/****************************************************************************** - * End Windows - *****************************************************************************/ -#else -// Default case: do nothing. - -#include "./memory_tools.hpp" - -#include - -void start_memory_checking() -{ - printf("starting memory checking... not available\n"); -} -void stop_memory_checking() -{ - printf("stopping memory checking... not available\n"); -} - -void assert_no_malloc_begin() {} - -void assert_no_malloc_end() {} - -void set_on_unexpected_malloc_callback(UnexpectedCallbackType callback) {} - -void assert_no_realloc_begin() {} - -void assert_no_realloc_end() {} - -void set_on_unexpected_realloc_callback(UnexpectedCallbackType callback) {} - -void assert_no_free_begin() {} - -void assert_no_free_end() {} - -void set_on_unexpected_free_callback(UnexpectedCallbackType callback) {} - -void memory_checking_thread_init() {} - -#endif // if defined(__linux__) elif defined(__APPLE__) elif defined(_WIN32) else ... diff --git a/test/memory_tools/memory_tools.hpp b/test/memory_tools/memory_tools.hpp deleted file mode 100644 index bbf6f122..00000000 --- a/test/memory_tools/memory_tools.hpp +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2015 Open Source Robotics Foundation, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code to do replacing of malloc/free/etc... inspired by: -// https://dxr.mozilla.org/mozilla-central/rev/ -// cc9c6cd756cb744596ba039dcc5ad3065a7cc3ea/memory/build/replace_malloc.c - -#ifndef MEMORY_TOOLS__MEMORY_TOOLS_HPP_ -#define MEMORY_TOOLS__MEMORY_TOOLS_HPP_ - -#include - -#include - -// This logic was borrowed (then namespaced) from the examples on the gcc wiki: -// https://gcc.gnu.org/wiki/Visibility - -#if defined _WIN32 || defined __CYGWIN__ - #ifdef __GNUC__ - #define RCUTILS_MEMORY_TOOLS_EXPORT __attribute__ ((dllexport)) - #define RCUTILS_MEMORY_TOOLS_IMPORT __attribute__ ((dllimport)) - #else - #define RCUTILS_MEMORY_TOOLS_EXPORT __declspec(dllexport) - #define RCUTILS_MEMORY_TOOLS_IMPORT __declspec(dllimport) - #endif - #ifdef RCUTILS_MEMORY_TOOLS_BUILDING_DLL - #define RCUTILS_MEMORY_TOOLS_PUBLIC RCUTILS_MEMORY_TOOLS_EXPORT - #else - #define RCUTILS_MEMORY_TOOLS_PUBLIC RCUTILS_MEMORY_TOOLS_IMPORT - #endif - #define RCUTILS_MEMORY_TOOLS_PUBLIC_TYPE RCUTILS_MEMORY_TOOLS_PUBLIC - #define RCUTILS_MEMORY_TOOLS_LOCAL -#else - #define RCUTILS_MEMORY_TOOLS_EXPORT __attribute__ ((visibility("default"))) - #define RCUTILS_MEMORY_TOOLS_IMPORT - #if __GNUC__ >= 4 - #define RCUTILS_MEMORY_TOOLS_PUBLIC __attribute__ ((visibility("default"))) - #define RCUTILS_MEMORY_TOOLS_LOCAL __attribute__ ((visibility("hidden"))) - #else - #define RCUTILS_MEMORY_TOOLS_PUBLIC - #define RCUTILS_MEMORY_TOOLS_LOCAL - #endif - #define RCUTILS_MEMORY_TOOLS_PUBLIC_TYPE -#endif - -typedef std::function UnexpectedCallbackType; - -RCUTILS_MEMORY_TOOLS_PUBLIC -void -start_memory_checking(); - -#define ASSERT_NO_MALLOC(statements) \ - assert_no_malloc_begin(); statements; assert_no_malloc_end(); -RCUTILS_MEMORY_TOOLS_PUBLIC -void -assert_no_malloc_begin(); -RCUTILS_MEMORY_TOOLS_PUBLIC -void -assert_no_malloc_end(); -RCUTILS_MEMORY_TOOLS_PUBLIC -void -set_on_unexpected_malloc_callback(UnexpectedCallbackType callback); - -#define ASSERT_NO_REALLOC(statements) \ - assert_no_realloc_begin(); statements; assert_no_realloc_end(); -RCUTILS_MEMORY_TOOLS_PUBLIC -void -assert_no_realloc_begin(); -RCUTILS_MEMORY_TOOLS_PUBLIC -void -assert_no_realloc_end(); -RCUTILS_MEMORY_TOOLS_PUBLIC -void -set_on_unexpected_realloc_callback(UnexpectedCallbackType callback); - -#define ASSERT_NO_FREE(statements) \ - assert_no_free_begin(); statements; assert_no_free_end(); -RCUTILS_MEMORY_TOOLS_PUBLIC -void -assert_no_free_begin(); -RCUTILS_MEMORY_TOOLS_PUBLIC -void -assert_no_free_end(); -RCUTILS_MEMORY_TOOLS_PUBLIC -void -set_on_unexpected_free_callback(UnexpectedCallbackType callback); - -RCUTILS_MEMORY_TOOLS_PUBLIC -void -stop_memory_checking(); - -RCUTILS_MEMORY_TOOLS_PUBLIC -void -memory_checking_thread_init(); - -#endif // MEMORY_TOOLS__MEMORY_TOOLS_HPP_ diff --git a/test/memory_tools/memory_tools_common.cpp b/test/memory_tools/memory_tools_common.cpp deleted file mode 100644 index 302bca0c..00000000 --- a/test/memory_tools/memory_tools_common.cpp +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2015 Open Source Robotics Foundation, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include - -#include -#include - -#if defined(__APPLE__) -#include -#define MALLOC_PRINTF malloc_printf -#else // defined(__APPLE__) -#define MALLOC_PRINTF printf -#endif // defined(__APPLE__) - -#include "./memory_tools.hpp" -#include "./scope_exit.hpp" - -static std::atomic enabled(false); - -static __thread bool malloc_expected = true; -static __thread UnexpectedCallbackType * unexpected_malloc_callback = nullptr; -void set_on_unexpected_malloc_callback(UnexpectedCallbackType callback) -{ - if (unexpected_malloc_callback) { - unexpected_malloc_callback->~UnexpectedCallbackType(); - free(unexpected_malloc_callback); - unexpected_malloc_callback = nullptr; - } - if (nullptr == callback) { - return; - } - if (nullptr == unexpected_malloc_callback) { - unexpected_malloc_callback = - reinterpret_cast(malloc(sizeof(UnexpectedCallbackType))); - if (NULL == unexpected_malloc_callback) { - throw std::bad_alloc(); - } - new (unexpected_malloc_callback) UnexpectedCallbackType(); - } - *unexpected_malloc_callback = callback; -} - -void * -custom_malloc(size_t size) -{ - if (!enabled.load()) {return malloc(size);} - auto foo = SCOPE_EXIT(enabled.store(true);); - enabled.store(false); - if (!malloc_expected) { - if (unexpected_malloc_callback) { - (*unexpected_malloc_callback)(); - } - } - void * memory = malloc(size); - uint64_t fw_size = size; - if (!malloc_expected) { - MALLOC_PRINTF( - " malloc (%s) %p %" PRIu64 "\n", - malloc_expected ? " expected" : "not expected", memory, fw_size); - } - return memory; -} - -static __thread bool realloc_expected = true; -static __thread UnexpectedCallbackType * unexpected_realloc_callback = nullptr; -void set_on_unexpected_realloc_callback(UnexpectedCallbackType callback) -{ - if (unexpected_realloc_callback) { - unexpected_realloc_callback->~UnexpectedCallbackType(); - free(unexpected_realloc_callback); - unexpected_realloc_callback = nullptr; - } - if (nullptr == callback) { - return; - } - if (nullptr == unexpected_realloc_callback) { - unexpected_realloc_callback = - reinterpret_cast(malloc(sizeof(UnexpectedCallbackType))); - if (nullptr == unexpected_realloc_callback) { - throw std::bad_alloc(); - } - new (unexpected_realloc_callback) UnexpectedCallbackType(); - } - *unexpected_realloc_callback = callback; -} - -void * -custom_realloc(void * memory_in, size_t size) -{ - if (!enabled.load()) {return realloc(memory_in, size);} - auto foo = SCOPE_EXIT(enabled.store(true);); - enabled.store(false); - if (!realloc_expected) { - if (unexpected_realloc_callback) { - (*unexpected_realloc_callback)(); - } - } - void * memory = realloc(memory_in, size); - uint64_t fw_size = size; - if (!realloc_expected) { - MALLOC_PRINTF( - "realloc (%s) %p %p %" PRIu64 "\n", - realloc_expected ? " expected" : "not expected", memory_in, memory, fw_size); - } - return memory; -} - -static __thread bool free_expected = true; -static __thread UnexpectedCallbackType * unexpected_free_callback = nullptr; -void set_on_unexpected_free_callback(UnexpectedCallbackType callback) -{ - if (unexpected_free_callback) { - unexpected_free_callback->~UnexpectedCallbackType(); - free(unexpected_free_callback); - unexpected_free_callback = nullptr; - } - if (nullptr == callback) { - return; - } - if (!unexpected_free_callback) { - unexpected_free_callback = - reinterpret_cast(malloc(sizeof(UnexpectedCallbackType))); - if (!unexpected_free_callback) { - throw std::bad_alloc(); - } - new (unexpected_free_callback) UnexpectedCallbackType(); - } - *unexpected_free_callback = callback; -} - -void -custom_free(void * memory) -{ - if (!enabled.load()) {return free(memory);} - auto foo = SCOPE_EXIT(enabled.store(true);); - enabled.store(false); - if (!free_expected) { - if (unexpected_free_callback) { - (*unexpected_free_callback)(); - } - } - if (!free_expected) { - MALLOC_PRINTF( - " free (%s) %p\n", free_expected ? " expected" : "not expected", memory); - } - free(memory); -} - -void assert_no_malloc_begin() {malloc_expected = false;} -void assert_no_malloc_end() {malloc_expected = true;} -void assert_no_realloc_begin() {realloc_expected = false;} -void assert_no_realloc_end() {realloc_expected = true;} -void assert_no_free_begin() {free_expected = false;} -void assert_no_free_end() {free_expected = true;} diff --git a/test/memory_tools/memory_tools_osx_interpose.cpp b/test/memory_tools/memory_tools_osx_interpose.cpp deleted file mode 100644 index d9397dfd..00000000 --- a/test/memory_tools/memory_tools_osx_interpose.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2015 Open Source Robotics Foundation, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Pulled from: -// https://github.com/emeryberger/Heap-Layers/blob/ -// 076e9e7ef53b66380b159e40473b930f25cc353b/wrappers/macinterpose.h - -// The interposition data structure (just pairs of function pointers), -// used an interposition table like the following: -// - -typedef struct interpose_s -{ - void * new_func; - void * orig_func; -} interpose_t; - -#define OSX_INTERPOSE(newf, oldf) \ - __attribute__((used)) static const interpose_t \ - macinterpose ## newf ## oldf __attribute__ ((section("__DATA, __interpose"))) = { \ - reinterpret_cast(newf), \ - reinterpret_cast(oldf), \ - } - -// End Interpose. - -#include "./memory_tools_common.cpp" - -void osx_start_memory_checking() -{ - // No loading required, it is handled by DYLD_INSERT_LIBRARIES and dynamic library interposing. - if (!enabled.exchange(true)) { - MALLOC_PRINTF("starting memory checking...\n"); - } -} - -void osx_stop_memory_checking() -{ - if (enabled.exchange(false)) { - MALLOC_PRINTF("stopping memory checking...\n"); - } -} - -OSX_INTERPOSE(custom_malloc, malloc); -OSX_INTERPOSE(custom_realloc, realloc); -OSX_INTERPOSE(custom_free, free); diff --git a/test/memory_tools/scope_exit.hpp b/test/memory_tools/scope_exit.hpp deleted file mode 100644 index 59f03955..00000000 --- a/test/memory_tools/scope_exit.hpp +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2015 Open Source Robotics Foundation, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef MEMORY_TOOLS__SCOPE_EXIT_HPP_ -#define MEMORY_TOOLS__SCOPE_EXIT_HPP_ - -#include - -template -struct ScopeExit -{ - explicit ScopeExit(Callable callable) - : callable_(callable) {} - ~ScopeExit() {callable_();} - -private: - Callable callable_; -}; - -template -ScopeExit -make_scope_exit(Callable callable) -{ - return ScopeExit(callable); -} - -#define SCOPE_EXIT(code) make_scope_exit([&]() {code;}) - -#endif // MEMORY_TOOLS__SCOPE_EXIT_HPP_ diff --git a/test/memory_tools/test_memory_tools.cpp b/test/memory_tools/test_memory_tools.cpp deleted file mode 100644 index a2377df5..00000000 --- a/test/memory_tools/test_memory_tools.cpp +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright 2015 Open Source Robotics Foundation, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include - -#include "./memory_tools.hpp" - -/* Tests the allocation checking tools. - */ -TEST(TestMemoryTools, test_allocation_checking_tools) { - size_t unexpected_mallocs = 0; - auto on_unexpected_malloc = - [&unexpected_mallocs]() { - unexpected_mallocs++; - }; - set_on_unexpected_malloc_callback(on_unexpected_malloc); - size_t unexpected_reallocs = 0; - auto on_unexpected_realloc = - [&unexpected_reallocs]() { - unexpected_reallocs++; - }; - set_on_unexpected_realloc_callback(on_unexpected_realloc); - size_t unexpected_frees = 0; - auto on_unexpected_free = - [&unexpected_frees]() { - unexpected_frees++; - }; - set_on_unexpected_free_callback(on_unexpected_free); - void * mem = nullptr; - void * remem = nullptr; - // First try before enabling, should have no effect. - mem = malloc(1024); - ASSERT_NE(nullptr, mem); - remem = realloc(mem, 2048); - ASSERT_NE(nullptr, remem); - free(remem); - EXPECT_EQ(0u, unexpected_mallocs); - EXPECT_EQ(0u, unexpected_reallocs); - EXPECT_EQ(0u, unexpected_frees); - // Enable checking, but no assert, should have no effect. - start_memory_checking(); - mem = malloc(1024); - ASSERT_NE(nullptr, mem); - remem = realloc(mem, 2048); - ASSERT_NE(nullptr, remem); - free(remem); - EXPECT_EQ(0u, unexpected_mallocs); - EXPECT_EQ(0u, unexpected_reallocs); - EXPECT_EQ(0u, unexpected_frees); - // Enable no_* asserts, should increment all once. - assert_no_malloc_begin(); - assert_no_realloc_begin(); - assert_no_free_begin(); - mem = malloc(1024); - assert_no_malloc_end(); - ASSERT_NE(nullptr, mem); - remem = realloc(mem, 2048); - assert_no_realloc_end(); - ASSERT_NE(nullptr, remem); - free(remem); - assert_no_free_end(); - EXPECT_EQ(1u, unexpected_mallocs); - EXPECT_EQ(1u, unexpected_reallocs); - EXPECT_EQ(1u, unexpected_frees); - // Enable on malloc assert, only malloc should increment. - assert_no_malloc_begin(); - mem = malloc(1024); - assert_no_malloc_end(); - ASSERT_NE(nullptr, mem); - remem = realloc(mem, 2048); - ASSERT_NE(nullptr, remem); - free(remem); - EXPECT_EQ(2u, unexpected_mallocs); - EXPECT_EQ(1u, unexpected_reallocs); - EXPECT_EQ(1u, unexpected_frees); - // Enable on realloc assert, only realloc should increment. - assert_no_realloc_begin(); - mem = malloc(1024); - ASSERT_NE(nullptr, mem); - remem = realloc(mem, 2048); - assert_no_realloc_end(); - ASSERT_NE(nullptr, remem); - free(remem); - EXPECT_EQ(2u, unexpected_mallocs); - EXPECT_EQ(2u, unexpected_reallocs); - EXPECT_EQ(1u, unexpected_frees); - // Enable on free assert, only free should increment. - assert_no_free_begin(); - mem = malloc(1024); - ASSERT_NE(nullptr, mem); - remem = realloc(mem, 2048); - ASSERT_NE(nullptr, remem); - free(remem); - assert_no_free_end(); - EXPECT_EQ(2u, unexpected_mallocs); - EXPECT_EQ(2u, unexpected_reallocs); - EXPECT_EQ(2u, unexpected_frees); - // Go again, after disabling asserts, should have no effect. - mem = malloc(1024); - ASSERT_NE(nullptr, mem); - remem = realloc(mem, 2048); - ASSERT_NE(nullptr, remem); - free(remem); - EXPECT_EQ(2u, unexpected_mallocs); - EXPECT_EQ(2u, unexpected_reallocs); - EXPECT_EQ(2u, unexpected_frees); - // Go once more after disabling everything, should have no effect. - stop_memory_checking(); - mem = malloc(1024); - ASSERT_NE(nullptr, mem); - remem = realloc(mem, 2048); - ASSERT_NE(nullptr, remem); - free(remem); - EXPECT_EQ(2u, unexpected_mallocs); - EXPECT_EQ(2u, unexpected_reallocs); - EXPECT_EQ(2u, unexpected_frees); -} diff --git a/test/test_allocator.cpp b/test/test_allocator.cpp index 7b57b3e6..fa029b88 100644 --- a/test/test_allocator.cpp +++ b/test/test_allocator.cpp @@ -16,7 +16,7 @@ #include "rcutils/allocator.h" -#include "./memory_tools/memory_tools.hpp" +#include "osrf_testing_tools_cpp/memory_tools/memory_tools.hpp" #ifdef RMW_IMPLEMENTATION # define CLASSNAME_(NAME, SUFFIX) NAME ## __ ## SUFFIX @@ -25,65 +25,74 @@ # define CLASSNAME(NAME, SUFFIX) NAME #endif +using osrf_testing_tools_cpp::memory_tools::disable_monitoring_in_all_threads; +using osrf_testing_tools_cpp::memory_tools::enable_monitoring_in_all_threads; +using osrf_testing_tools_cpp::memory_tools::on_unexpected_calloc; +using osrf_testing_tools_cpp::memory_tools::on_unexpected_free; +using osrf_testing_tools_cpp::memory_tools::on_unexpected_malloc; +using osrf_testing_tools_cpp::memory_tools::on_unexpected_realloc; + class CLASSNAME (TestAllocatorFixture, RMW_IMPLEMENTATION) : public ::testing::Test { public: - CLASSNAME(TestAllocatorFixture, RMW_IMPLEMENTATION)() { - start_memory_checking(); - stop_memory_checking(); - } + CLASSNAME(TestAllocatorFixture, RMW_IMPLEMENTATION)() {} + void SetUp() { - set_on_unexpected_malloc_callback([]() {EXPECT_FALSE(true) << "UNEXPECTED MALLOC";}); - set_on_unexpected_realloc_callback([]() {EXPECT_FALSE(true) << "UNEXPECTED REALLOC";}); - set_on_unexpected_free_callback([]() {EXPECT_FALSE(true) << "UNEXPECTED FREE";}); - start_memory_checking(); + osrf_testing_tools_cpp::memory_tools::initialize(); + enable_monitoring_in_all_threads(); } void TearDown() { - assert_no_malloc_end(); - assert_no_realloc_end(); - assert_no_free_end(); - stop_memory_checking(); - set_on_unexpected_malloc_callback(nullptr); - set_on_unexpected_realloc_callback(nullptr); - set_on_unexpected_free_callback(nullptr); + disable_monitoring_in_all_threads(); + osrf_testing_tools_cpp::memory_tools::uninitialize(); } }; /* Tests the default allocator. */ TEST_F(CLASSNAME(TestAllocatorFixture, RMW_IMPLEMENTATION), test_default_allocator_normal) { - ASSERT_NO_MALLOC( - rcutils_allocator_t allocator = rcutils_get_default_allocator(); - ) size_t mallocs = 0; size_t reallocs = 0; + size_t callocs = 0; size_t frees = 0; - set_on_unexpected_malloc_callback( - [&mallocs]() { - mallocs++; - }); - set_on_unexpected_realloc_callback( - [&reallocs]() { - reallocs++; - }); - set_on_unexpected_free_callback( - [&frees]() { - frees++; - }); - assert_no_malloc_begin(); - assert_no_realloc_begin(); - assert_no_free_begin(); - void * allocated_memory = allocator.allocate(1024, allocator.state); + on_unexpected_malloc([&mallocs]() {mallocs++;}); + on_unexpected_realloc([&reallocs]() {reallocs++;}); + on_unexpected_calloc([&callocs]() {callocs++;}); + on_unexpected_free([&frees]() {frees++;}); + + rcutils_allocator_t allocator; + EXPECT_NO_MEMORY_OPERATIONS({ + allocator = rcutils_get_default_allocator(); + }); + EXPECT_EQ(0u, mallocs); + EXPECT_EQ(0u, reallocs); + EXPECT_EQ(0u, callocs); + EXPECT_EQ(0u, frees); + + void * allocated_memory = nullptr; + EXPECT_NO_MEMORY_OPERATIONS({ + allocated_memory = allocator.allocate(1024, allocator.state); + }); EXPECT_EQ(1u, mallocs); EXPECT_NE(nullptr, allocated_memory); - allocated_memory = allocator.reallocate(allocated_memory, 2048, allocator.state); + EXPECT_NO_MEMORY_OPERATIONS({ + allocated_memory = allocator.reallocate(allocated_memory, 2048, allocator.state); + }); EXPECT_EQ(1u, reallocs); EXPECT_NE(nullptr, allocated_memory); - allocator.deallocate(allocated_memory, allocator.state); + EXPECT_NO_MEMORY_OPERATIONS({ + allocator.deallocate(allocated_memory, allocator.state); + allocated_memory = allocator.zero_allocate(1024, sizeof(void *), allocator.state); + }); + EXPECT_EQ(1u, callocs); + EXPECT_NE(nullptr, allocated_memory); + EXPECT_NO_MEMORY_OPERATIONS({ + allocator.deallocate(allocated_memory, allocator.state); + }); EXPECT_EQ(1u, mallocs); EXPECT_EQ(1u, reallocs); - EXPECT_EQ(1u, frees); + EXPECT_EQ(1u, callocs); + EXPECT_EQ(2u, frees); } diff --git a/test/test_logging_macros.c b/test/test_logging_macros.c index cd691fdc..3ae6079d 100644 --- a/test/test_logging_macros.c +++ b/test/test_logging_macros.c @@ -62,7 +62,7 @@ int main(int argc, char ** argv) rcutils_logging_get_output_handler(); rcutils_logging_set_output_handler(custom_handler); - RCUTILS_LOG_INFO("empty message"); + size_t line_number = __LINE__; RCUTILS_LOG_INFO("empty message"); if (g_log_calls != 1u) { return 3; } @@ -72,7 +72,7 @@ int main(int argc, char ** argv) if (strcmp(g_last_log_event.location->function_name, "main")) { return 5; } - if (g_last_log_event.location->line_number != 65u) { + if (g_last_log_event.location->line_number != line_number) { return 6; } if (g_last_log_event.severity != RCUTILS_LOG_SEVERITY_INFO) { @@ -85,7 +85,7 @@ int main(int argc, char ** argv) return 9; } - RCUTILS_LOG_INFO("message %s", "foo"); + line_number = __LINE__; RCUTILS_LOG_INFO("message %s", "foo"); if (g_log_calls != 2u) { return 10; } @@ -95,7 +95,7 @@ int main(int argc, char ** argv) if (strcmp(g_last_log_event.location->function_name, "main")) { return 12; } - if (g_last_log_event.location->line_number != 88u) { + if (g_last_log_event.location->line_number != line_number) { return 13; } if (g_last_log_event.severity != RCUTILS_LOG_SEVERITY_INFO) { diff --git a/test/test_time.cpp b/test/test_time.cpp index ad7485ef..dd006453 100644 --- a/test/test_time.cpp +++ b/test/test_time.cpp @@ -14,56 +14,54 @@ #include -#include - #include +#include #include +#include "osrf_testing_tools_cpp/memory_tools/memory_tools.hpp" + #include "rcutils/error_handling.h" #include "rcutils/time.h" -#include "./memory_tools/memory_tools.hpp" +using osrf_testing_tools_cpp::memory_tools::disable_monitoring_in_all_threads; +using osrf_testing_tools_cpp::memory_tools::enable_monitoring_in_all_threads; +using osrf_testing_tools_cpp::memory_tools::on_unexpected_calloc; +using osrf_testing_tools_cpp::memory_tools::on_unexpected_free; +using osrf_testing_tools_cpp::memory_tools::on_unexpected_malloc; +using osrf_testing_tools_cpp::memory_tools::on_unexpected_realloc; class TestTimeFixture : public ::testing::Test { public: void SetUp() { - set_on_unexpected_malloc_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED MALLOC";}); - set_on_unexpected_realloc_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED REALLOC";}); - set_on_unexpected_free_callback([]() {ASSERT_FALSE(true) << "UNEXPECTED FREE";}); - start_memory_checking(); + osrf_testing_tools_cpp::memory_tools::initialize(); + on_unexpected_malloc([]() {FAIL() << "UNEXPECTED MALLOC";}); + on_unexpected_realloc([]() {FAIL() << "UNEXPECTED REALLOC";}); + on_unexpected_calloc([]() {FAIL() << "UNEXPECTED CALLOC";}); + on_unexpected_free([]() {FAIL() << "UNEXPECTED FREE";}); + enable_monitoring_in_all_threads(); } void TearDown() { - assert_no_malloc_end(); - assert_no_realloc_end(); - assert_no_free_end(); - stop_memory_checking(); - set_on_unexpected_malloc_callback(nullptr); - set_on_unexpected_realloc_callback(nullptr); - set_on_unexpected_free_callback(nullptr); + disable_monitoring_in_all_threads(); + osrf_testing_tools_cpp::memory_tools::uninitialize(); } }; // Tests the rcutils_system_time_now() function. TEST_F(TestTimeFixture, test_rcutils_system_time_now) { - assert_no_realloc_begin(); rcutils_ret_t ret; // Check for invalid argument error condition (allowed to alloc). ret = rcutils_system_time_now(nullptr); EXPECT_EQ(ret, RCUTILS_RET_INVALID_ARGUMENT) << rcutils_get_error_string_safe(); rcutils_reset_error(); - assert_no_malloc_begin(); - assert_no_free_begin(); // Check for normal operation (not allowed to alloc). rcutils_time_point_value_t now = 0; - ret = rcutils_system_time_now(&now); - assert_no_malloc_end(); - assert_no_realloc_end(); - assert_no_free_end(); - stop_memory_checking(); + EXPECT_NO_MEMORY_OPERATIONS({ + ret = rcutils_system_time_now(&now); + }); EXPECT_EQ(ret, RCUTILS_RET_OK) << rcutils_get_error_string_safe(); EXPECT_NE(0u, now); // Compare to std::chrono::system_clock time (within a second). @@ -81,33 +79,32 @@ TEST_F(TestTimeFixture, test_rcutils_system_time_now) { // Tests the rcutils_steady_time_now() function. TEST_F(TestTimeFixture, test_rcutils_steady_time_now) { - assert_no_realloc_begin(); rcutils_ret_t ret; // Check for invalid argument error condition (allowed to alloc). ret = rcutils_steady_time_now(nullptr); EXPECT_EQ(ret, RCUTILS_RET_INVALID_ARGUMENT) << rcutils_get_error_string_safe(); rcutils_reset_error(); - assert_no_malloc_begin(); - assert_no_free_begin(); // Check for normal operation (not allowed to alloc). rcutils_time_point_value_t now = 0; - ret = rcutils_steady_time_now(&now); - assert_no_malloc_end(); - assert_no_realloc_end(); - assert_no_free_end(); - stop_memory_checking(); + EXPECT_NO_MEMORY_OPERATIONS({ + ret = rcutils_steady_time_now(&now); + }); EXPECT_EQ(ret, RCUTILS_RET_OK) << rcutils_get_error_string_safe(); EXPECT_NE(0u, now); // Compare to std::chrono::steady_clock difference of two times (within a second). now = 0; - ret = rcutils_steady_time_now(&now); + EXPECT_NO_MEMORY_OPERATIONS({ + ret = rcutils_steady_time_now(&now); + }); std::chrono::steady_clock::time_point now_sc = std::chrono::steady_clock::now(); EXPECT_EQ(ret, RCUTILS_RET_OK) << rcutils_get_error_string_safe(); // Wait for a little while. std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Then take a new timestamp with each and compare. rcutils_time_point_value_t later; - ret = rcutils_steady_time_now(&later); + EXPECT_NO_MEMORY_OPERATIONS({ + ret = rcutils_steady_time_now(&later); + }); std::chrono::steady_clock::time_point later_sc = std::chrono::steady_clock::now(); EXPECT_EQ(ret, RCUTILS_RET_OK) << rcutils_get_error_string_safe(); int64_t steady_diff = later - now;