From 1fa7f37d9c32ee71de66b7ad01671788bf907505 Mon Sep 17 00:00:00 2001 From: Kevin Huck Date: Mon, 22 Mar 2021 16:08:38 -0700 Subject: [PATCH] Adding support for calloc and realloc --- src/apex/memory_wrapper.cpp | 9 ++++ src/unit_tests/C++/CMakeLists.txt | 8 ++- src/unit_tests/C++/apex_malloc.cpp | 64 ++++++++++++++++++++++ src/wrappers/memory_wrapper.cpp | 68 +++++++++++++++++------- src/wrappers/memory_wrapper.h | 6 +-- src/wrappers/memory_wrapper_internal.cpp | 60 ++++++++++----------- 6 files changed, 162 insertions(+), 53 deletions(-) create mode 100644 src/unit_tests/C++/apex_malloc.cpp diff --git a/src/apex/memory_wrapper.cpp b/src/apex/memory_wrapper.cpp index 2cd5c101..683e1ca2 100644 --- a/src/apex/memory_wrapper.cpp +++ b/src/apex/memory_wrapper.cpp @@ -68,3 +68,12 @@ void disable_memory_wrapper() { } } + +extern "C" void enable_memory_wrapper(void) { + apex::enable_memory_wrapper(); +} + +extern "C" void disable_memory_wrapper(void) { + apex::disable_memory_wrapper(); +} + diff --git a/src/unit_tests/C++/CMakeLists.txt b/src/unit_tests/C++/CMakeLists.txt index 830ab1db..08b6c14f 100644 --- a/src/unit_tests/C++/CMakeLists.txt +++ b/src/unit_tests/C++/CMakeLists.txt @@ -44,6 +44,7 @@ set(example_programs apex_profiler_guids apex_non_worker_thread apex_swap_threads + apex_malloc ${APEX_OPENMP_TEST} ) #apex_set_thread_cap @@ -107,7 +108,12 @@ endif (OPENMP_FOUND) #add_dependencies (apex_fibonacci_std_async_cpp apex_pthread_wrapper) - +set_property (TEST test_apex_malloc_cpp APPEND PROPERTY ENVIRONMENT + "LD_PRELOAD=${APEX_BINARY_DIR}/src/wrappers/libapex_memory_wrapper.so") +set_property (TEST test_apex_malloc_cpp APPEND PROPERTY ENVIRONMENT + "APEX_PROC_STAT=0") +#set_property (TEST test_apex_malloc_cpp APPEND PROPERTY ENVIRONMENT +# "APEX_TRACK_MEMORY=1") # Make sure the compiler can find include files from our Apex library. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MPI_COMPILE_FLAGS}") diff --git a/src/unit_tests/C++/apex_malloc.cpp b/src/unit_tests/C++/apex_malloc.cpp new file mode 100644 index 00000000..d241af8e --- /dev/null +++ b/src/unit_tests/C++/apex_malloc.cpp @@ -0,0 +1,64 @@ +#include +#include +#include "apex_api.hpp" + +void bar(char* data) { + apex::scoped_timer(__func__); + auto s = strlen(data); + std::cout << "Size: " << s << std::endl; +} + +void test_malloc() { + apex::scoped_timer(__func__); + auto foo = (char*)(malloc(42 * sizeof(char))); + memset(foo, 'a', 41); + foo[41] = 0; + bar(foo); + free(foo); +} + +void test_calloc() { + apex::scoped_timer(__func__); + auto foo = (char*)(calloc(42, sizeof(char))); + memset(foo, 'a', 41); + bar(foo); + free(foo); +} + +void test_realloc() { + apex::scoped_timer(__func__); + auto foo = (char*)(malloc(42 * sizeof(char))); + memset(foo, 'a', 41); + foo[41] = 0; + bar(foo); + foo = (char*)(realloc(foo, 84 * sizeof(char))); + memset(foo, 'a', 83); + foo[83] = 0; + bar(foo); + free(foo); +} + +void test_all(void) { + test_malloc(); + test_calloc(); + test_realloc(); +} + +void apex_enable_memory_wrapper(void); +void apex_disable_memory_wrapper(void); + +int main (int argc, char** argv) { + APEX_UNUSED(argc); + APEX_UNUSED(argv); + apex::init("apex memory wrapper unit test", 0, 1); + apex::apex_options::use_screen_output(true); + apex::apex_options::track_memory(true); + test_all(); + apex::enable_memory_wrapper(); + test_all(); + apex::disable_memory_wrapper(); + apex::finalize(); + apex::cleanup(); + return 0; +} + diff --git a/src/wrappers/memory_wrapper.cpp b/src/wrappers/memory_wrapper.cpp index 40908e57..7a61d5c5 100644 --- a/src/wrappers/memory_wrapper.cpp +++ b/src/wrappers/memory_wrapper.cpp @@ -226,15 +226,55 @@ int puts (const char* s) { return r; } -#if 0 +extern "C" void* calloc (size_t nmemb, size_t size) { static calloc_p _calloc = NULL; - if (!_calloc) { - _calloc = (calloc_p)get_system_function_handle("calloc", (void*)calloc); + static bool initializing = false; + static bool bootstrapped = false; + if (!bootstrapped) { + if (!initializing) { + initializing = true; + _calloc = (calloc_p)get_system_function_handle("calloc", (void*)calloc); + } + if (!_calloc) { + return bootstrap_alloc(0, (nmemb*size)); + } + if (!all_clear()) { + return _calloc(nmemb, size); + } + bootstrapped = true; + } + if (all_clear()) { + return apex_calloc_wrapper(_calloc, nmemb, size); } - return apex_calloc_wrapper(_calloc, nmemb, size); + return _calloc(nmemb, size); } +extern "C" +void* realloc (void* ptr, size_t size) { + static realloc_p _realloc = NULL; + static bool initializing = false; + static bool bootstrapped = false; + if (!bootstrapped) { + if (!initializing) { + initializing = true; + _realloc = (realloc_p)get_system_function_handle("realloc", (void*)realloc); + } + if (!_realloc) { + return bootstrap_alloc(0, size); + } + if (!all_clear()) { + return _realloc(ptr, size); + } + bootstrapped = true; + } + if (all_clear()) { + return apex_realloc_wrapper(_realloc, ptr, size); + } + return _realloc(ptr, size); +} + +#if 0 #if defined(memalign) void* memalign (size_t alignment, size_t size) { static memalign_p _memalign = NULL; @@ -245,14 +285,6 @@ void* memalign (size_t alignment, size_t size) { } #endif -void* realloc (void* ptr, size_t size) { - static realloc_p _realloc = NULL; - if (!_realloc) { - _realloc = (realloc_p)get_system_function_handle("realloc", (void*)realloc); - } - return apex_realloc_wrapper(_realloc, ptr, size); -} - #if defined(reallocarray) void* reallocarray (void* ptr, size_t nmemb, size_t size) { static reallocarray_p _reallocarray = NULL; @@ -307,12 +339,17 @@ void __wrap_free(void* ptr) { return apex_free_wrapper(__real_free, ptr); } -#if 0 void* __real_calloc(size_t, size_t); void* __wrap_calloc(size_t nmemb, size_t size) { return apex_calloc_wrapper(__real_calloc, nmemb, size); } +void* __real_realloc(void*, size_t); +void* __wrap_realloc(void* ptr, size_t size) { + return apex_realloc_wrapper(__real_realloc, ptr, size); +} + +#if 0 #if defined(memalign) void* __real_memalign(size_t, size_t); void* __wrap_memalign(size_t alignment, size_t size) { @@ -320,11 +357,6 @@ void* __wrap_memalign(size_t alignment, size_t size) { } #endif -void* __real_realloc(void*, size_t); -void* __wrap_realloc(void* ptr, size_t size) { - return apex_realloc_wrapper(__real_realloc, ptr, size); -} - #if defined(reallocarray) void* __real_reallocarray(void*, size_t, size_t); void* __wrap_reallocarray(void* ptr, size_t nmemb, size_t size) { diff --git a/src/wrappers/memory_wrapper.h b/src/wrappers/memory_wrapper.h index 6faf7e3e..24753b4f 100644 --- a/src/wrappers/memory_wrapper.h +++ b/src/wrappers/memory_wrapper.h @@ -24,9 +24,9 @@ typedef void* (*malloc_p)(size_t); typedef void (*free_p)(void*); typedef int (*puts_p)(const char*); -#if 0 typedef void* (*calloc_p)(size_t, size_t); typedef void* (*realloc_p)(void*, size_t); +#if 0 #if defined(memalign) typedef void* (*memalign_p)(void*, size_t, size_t); #endif @@ -51,14 +51,14 @@ extern "C" { void* apex_malloc_wrapper(malloc_p malloc_call, size_t size); void apex_free_wrapper(free_p free_call, void* ptr); int apex_puts_wrapper(const char* s); +void* apex_calloc_wrapper(calloc_p calloc_call, size_t nmemb, size_t size); +void* apex_realloc_wrapper(realloc_p realloc_call, void* ptr, size_t size); void apex_memory_wrapper_init(void); void apex_report_leaks(void); #if 0 -void* apex_calloc_wrapper(calloc_p calloc_call, size_t nmemb, size_t size); #if defined(memalign) void* apex_memalign_wrapper(memalign_p calloc_call, size_t align, size_t size); #endif -void* apex_realloc_wrapper(realloc_p realloc_call, void* ptr, size_t size); #if defined(reallocarray) void* apex_reallocarray_wrapper(reallocarray_p reallocarray_call, void* ptr, size_t nmemb, size_t size); #endif diff --git a/src/wrappers/memory_wrapper_internal.cpp b/src/wrappers/memory_wrapper_internal.cpp index d72fb55c..05fd058d 100644 --- a/src/wrappers/memory_wrapper_internal.cpp +++ b/src/wrappers/memory_wrapper_internal.cpp @@ -124,23 +124,37 @@ void apex_report_leaks() { } } -#if 0 -extern "C" void* apex_calloc_wrapper(calloc_p calloc_call, size_t nmemb, size_t size) { - if(inWrapper()) { + if(inWrapper() || apex::in_apex::get() > 0) { // Another wrapper has already intercepted the call so just pass through return calloc_call(nmemb, size); - } else { - inWrapper() = true; - - // do the allocation - auto retval = calloc_call(nmemb, size); + } + inWrapper() = true; + // do the allocation + auto retval = calloc_call(nmemb, size); + // record the state + record_alloc(size, retval); + inWrapper() = false; + return retval; +} - inWrapper() = false; - return retval; +void* apex_realloc_wrapper(realloc_p realloc_call, void* ptr, size_t size) { + if(inWrapper() || apex::in_apex::get() > 0) { + // Another wrapper has already intercepted the call so just pass through + return realloc_call(ptr, size); } + inWrapper() = true; + // record the state + record_free(ptr); + // do the allocation + auto retval = realloc_call(ptr, size); + // record the state + record_alloc(size, retval); + inWrapper() = false; + return retval; } +#if 0 #if defined(memalign) extern "C" void* apex_memalign_wrapper(memalign_p memalign_call, size_t nmemb, size_t size) { @@ -159,22 +173,6 @@ void* apex_memalign_wrapper(memalign_p memalign_call, size_t nmemb, size_t size) } #endif -extern "C" -void* apex_realloc_wrapper(realloc_p realloc_call, void* ptr, size_t size) { - if(inWrapper()) { - // Another wrapper has already intercepted the call so just pass through - return realloc_call(ptr, size); - } else { - inWrapper() = true; - - // do the allocation - auto retval = realloc_call(ptr, size); - - inWrapper() = false; - return retval; - } -} - #if defined(reallocarray) extern "C" void* apex_reallocarray_wrapper(reallocarray_p reallocarray_call, void* ptr, size_t nmemb, size_t size) { @@ -257,21 +255,21 @@ extern "C" void apex_free(void* ptr) { return apex_free_wrapper(free, ptr); } -#if 0 extern "C" void* apex_calloc(size_t nmemb, size_t size) { return apex_calloc_wrapper(calloc, nmemb, size); } +extern "C" void* apex_realloc(void* ptr, size_t size) { + return apex_realloc_wrapper(realloc, ptr, size); +} + +#if 0 #if defined(memalign) extern "C" void* apex_memalign(size_t nmemb, size_t size) { return apex_memalign_wrapper(memalign, nmemb, size); } #endif -extern "C" void* apex_realloc(void* ptr, size_t size) { - return apex_realloc_wrapper(realloc, ptr, size); -} - #if defined(reallocarray) extern "C" void* apex_reallocarray(void* ptr, size_t nmemb, size_t size) { return apex_reallocarray_wrapper(reallocarray, ptr, nmemb, size);