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).
pull/8062/head
deepikabhavnani 2018-09-10 10:36:43 -05:00
parent 6646323867
commit 0e758796f6
1 changed files with 27 additions and 13 deletions

View File

@ -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<PlatformMutex> 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;
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);
}
}
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;
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);
}
}
malloc_stats_mutex->unlock();
#else // #ifdef MBED_HEAP_STATS_ENABLED