From 66463238677e824832f3b44ff750f1593721f0cd Mon Sep 17 00:00:00 2001 From: Deepika Date: Wed, 5 Sep 2018 16:25:04 -0500 Subject: [PATCH 1/2] Alignment of 8 is not required for additional header malloc guarantees aligned memory. If we add an alignment here, we are adding additonal unused 4 bytes. Each allocator has its own 4/8 byte header (GGC / ARM have 4 bytes). So if user request for 8 bytes of memory stats will add 8 + allocator 8. However if we remove the alignment in stats header, allocator will consider add 4 bytes to 12 byte request and zero padding. It will be beneficial to leave the padding to allocator. --- platform/mbed_alloc_wrappers.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/platform/mbed_alloc_wrappers.cpp b/platform/mbed_alloc_wrappers.cpp index 3b4caf077a..66bc1f150d 100644 --- a/platform/mbed_alloc_wrappers.cpp +++ b/platform/mbed_alloc_wrappers.cpp @@ -40,10 +40,8 @@ are active, the second one (MBED_MEM_TRACING_ENABLED) will trace the first one's /* Implementation of the runtime max heap usage checker */ /******************************************************************************/ -/* Size must be a multiple of 8 to keep alignment */ typedef struct { uint32_t size; - uint32_t pad; } alloc_info_t; #ifdef MBED_HEAP_STATS_ENABLED From 0e758796f66d14f2f06dc1ceaf353c1921fd87ba Mon Sep 17 00:00:00 2001 From: deepikabhavnani Date: Mon, 10 Sep 2018 10:36:43 -0500 Subject: [PATCH 2/2] Signature to track memory allocations by wrapper functions. Compilers allocate some section of memory without using wrapper function, which is later freed when wrappers were initialized. Since the allocated memory didn;t contain wrapper header the pointer got corrupt when calling to free. This implementation of signature addition during malloc and signature check during free helps in freeing the memory allocated by wrapper functions properly and also the internal memory allocated by compilers (without malloc wrappers). --- platform/mbed_alloc_wrappers.cpp | 40 +++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/platform/mbed_alloc_wrappers.cpp b/platform/mbed_alloc_wrappers.cpp index 66bc1f150d..3777118180 100644 --- a/platform/mbed_alloc_wrappers.cpp +++ b/platform/mbed_alloc_wrappers.cpp @@ -42,9 +42,12 @@ are active, the second one (MBED_MEM_TRACING_ENABLED) will trace the first one's typedef struct { uint32_t size; + uint32_t signature; } alloc_info_t; #ifdef MBED_HEAP_STATS_ENABLED +#define MBED_HEAP_STATS_SIGNATURE (0xdeadbeef) + static SingletonPtr malloc_stats_mutex; static mbed_stats_heap_t heap_stats = {0, 0, 0, 0, 0, 0, 0}; @@ -104,6 +107,7 @@ extern "C" void *malloc_wrapper(struct _reent *r, size_t size, void *caller) alloc_info_t *alloc_info = (alloc_info_t *)__real__malloc_r(r, size + sizeof(alloc_info_t)); if (alloc_info != NULL) { alloc_info->size = size; + alloc_info->signature = MBED_HEAP_STATS_SIGNATURE; ptr = (void *)(alloc_info + 1); heap_stats.current_size += size; heap_stats.total_size += size; @@ -184,13 +188,18 @@ extern "C" void free_wrapper(struct _reent *r, void *ptr, void *caller) alloc_info_t *alloc_info = NULL; if (ptr != NULL) { alloc_info = ((alloc_info_t *)ptr) - 1; - size_t user_size = alloc_info->size; - size_t alloc_size = MALLOC_HEAP_TOTAL_SIZE(MALLOC_HEADER_PTR(alloc_info)); - heap_stats.current_size -= user_size; - heap_stats.alloc_cnt -= 1; - heap_stats.overhead_size -= (alloc_size - user_size); + if (MBED_HEAP_STATS_SIGNATURE == alloc_info->signature) { + size_t user_size = alloc_info->size; + size_t alloc_size = MALLOC_HEAP_TOTAL_SIZE(MALLOC_HEADER_PTR(alloc_info)); + alloc_info->signature = 0x0; + heap_stats.current_size -= user_size; + heap_stats.alloc_cnt -= 1; + heap_stats.overhead_size -= (alloc_size - user_size); + __real__free_r(r, (void *)alloc_info); + } else { + __real__free_r(r, ptr); + } } - __real__free_r(r, (void *)alloc_info); malloc_stats_mutex->unlock(); #else // #ifdef MBED_HEAP_STATS_ENABLED @@ -231,7 +240,6 @@ extern "C" void *__wrap__memalign_r(struct _reent *r, size_t alignment, size_t b } - /******************************************************************************/ /* ARMCC / IAR memory allocation wrappers */ /******************************************************************************/ @@ -286,6 +294,7 @@ extern "C" void *malloc_wrapper(size_t size, void *caller) alloc_info_t *alloc_info = (alloc_info_t *)SUPER_MALLOC(size + sizeof(alloc_info_t)); if (alloc_info != NULL) { alloc_info->size = size; + alloc_info->signature = MBED_HEAP_STATS_SIGNATURE; ptr = (void *)(alloc_info + 1); heap_stats.current_size += size; heap_stats.total_size += size; @@ -384,13 +393,18 @@ extern "C" void free_wrapper(void *ptr, void *caller) alloc_info_t *alloc_info = NULL; if (ptr != NULL) { alloc_info = ((alloc_info_t *)ptr) - 1; - size_t user_size = alloc_info->size; - size_t alloc_size = MALLOC_HEAP_TOTAL_SIZE(MALLOC_HEADER_PTR(alloc_info)); - heap_stats.current_size -= user_size; - heap_stats.alloc_cnt -= 1; - heap_stats.overhead_size -= (alloc_size - user_size); + if (MBED_HEAP_STATS_SIGNATURE == alloc_info->signature) { + size_t user_size = alloc_info->size; + size_t alloc_size = MALLOC_HEAP_TOTAL_SIZE(MALLOC_HEADER_PTR(alloc_info)); + alloc_info->signature = 0x0; + heap_stats.current_size -= user_size; + heap_stats.alloc_cnt -= 1; + heap_stats.overhead_size -= (alloc_size - user_size); + SUPER_FREE((void *)alloc_info); + } else { + SUPER_FREE(ptr); + } } - SUPER_FREE((void *)alloc_info); malloc_stats_mutex->unlock(); #else // #ifdef MBED_HEAP_STATS_ENABLED