Heap Allocation Tracking
This guide assumes you have already completed the minimal integration of the Memfault SDK. If you have not, please complete the appropriate Getting Started guide.
This feature of the Memfault SDK provides insight into heap allocations when viewing coredumps, for example:
Usage
- Nordic nRF Connect / Zephyr RTOS
- FreeRTOS
- ESP32
- Bare Metal / Other
Add or update the appropriate options to your system's prj.conf
:
CONFIG_MEMFAULT_HEAP_STATS=y
# Setting a non-zero memory pool size is required for heap stats; otherwise
# k_malloc() will not be supported.
CONFIG_HEAP_MEM_POOL_SIZE=512
Depending on if your code calls the FreeRTOS Heap API directly or via a wrapping function, follow the respective steps:
pvPortMalloc()
/vPortFree()
Direct Calls
For systems using the Memfault FreeRTOS port and a FreeRTOS heap implementation,
enable heap tracking with the following configuration options in
memfault_platform_config.h
:
#define MEMFAULT_COREDUMP_COLLECT_HEAP_STATS 1 // Enable heap stats collection
#define MEMFAULT_FREERTOS_PORT_HEAP_STATS_ENABLE 1 // Enable FreeRTOS port implementation
#define MEMFAULT_COREDUMP_HEAP_STATS_LOCK_ENABLE 0 // Disable internal locking
Due to the locking provided by FreeRTOS within pvPortMalloc()
/vPortFree()
,
MEMFAULT_COREDUMP_HEAP_STATS_LOCK_ENABLE
must be disabled. For reference, the
Memfault SDK port implements the traceMALLOC
/traceFREE
wrappers
here.
pvPortMalloc()
/vPortFree()
Wrapped Calls
If your system wraps calls to pvPortMalloc()
/vPortFree()
with your own
functions, instead enable heap tracking with the following:
1. Enable the config flag
#define MEMFAULT_COREDUMP_COLLECT_HEAP_STATS 1
2. Instrument your malloc()
and free()
wrappers
#include "memfault/components.h"
void *my_malloc(size_t size) {
void *ptr = (size);
MEMFAULT_HEAP_STATS_MALLOC(ptr, size);
return ptr;
}
void my_free(void *ptr) {
MEMFAULT_HEAP_STATS_FREE(ptr);
my_free(ptr);
}
The MEMFAULT_HEAP_STATS_*
macros will record the malloc
/free
operations
within your functions. The heap stats component will use
memfault_lock()/memfault_unlock()
internally for thread-safety.
1. Enable the config flag
Set this in memfault_platform_config.h
:
#define MEMFAULT_COREDUMP_COLLECT_HEAP_STATS 1
2. Instrument the malloc
and free
calls
For newlib or other typical libc-provided malloc
and free
, you can add the
following wrapper functions (same would apply to other malloc implementations):
#include "memfault/components.h"
extern void __real_free(void *ptr);
extern void *__real_malloc(size_t size);
void __wrap_free(void *ptr) {
MEMFAULT_HEAP_STATS_FREE(ptr);
__real_free(ptr);
}
void *__wrap_malloc(size_t size) {
void *ptr = __real_malloc(size);
MEMFAULT_HEAP_STATS_MALLOC(ptr, size);
return ptr;
}
The MEMFAULT_HEAP_STATS_*
macros will record the malloc
/free
operations.
To enable the wrappers, add these flags to the linker command flags:
-Wl,--wrap=malloc,--wrap=free
Add or update the appropriate options to your system's sdkconfig.defaults
:
CONFIG_MEMFAULT_HEAP_STATS=y
# HEAP_TRACING instruments malloc/free calls similarly, and is incompatible
CONFIG_HEAP_TRACING=n