Newlib internal allocations (from newlib ROM code) were not being included in the heap trace.
Ref https://github.com/espressif/esp-idf/issues/1652
ifdef CONFIG_HEAP_TRACING
-WRAP_FUNCTIONS = calloc malloc free realloc heap_caps_malloc heap_caps_free heap_caps_realloc
+WRAP_FUNCTIONS = calloc malloc free realloc heap_caps_malloc heap_caps_free heap_caps_realloc heap_caps_malloc_default heap_caps_realloc_default
WRAP_ARGUMENT := -Wl,--wrap=
COMPONENT_ADD_LDFLAGS = -l$(COMPONENT_NAME) $(addprefix $(WRAP_ARGUMENT),$(WRAP_FUNCTIONS))
void *__real_heap_caps_malloc(size_t size, uint32_t caps);
+void *__real_heap_caps_malloc_default( size_t size );
+void *__real_heap_caps_realloc_default( void *ptr, size_t size );
/* trace any 'malloc' event */
static IRAM_ATTR __attribute__((noinline)) void *trace_malloc(size_t size, uint32_t caps, trace_malloc_mode_t mode)
if ( mode == TRACE_MALLOC_CAPS ) {
p = __real_heap_caps_malloc(size, caps);
} else { //TRACE_MALLOC_DEFAULT
- p = heap_caps_malloc_default(size);
+ p = __real_heap_caps_malloc_default(size);
}
if (tracing && p != NULL) {
if (mode == TRACE_MALLOC_CAPS ) {
r = __real_heap_caps_realloc(p, size, caps);
} else { //TRACE_MALLOC_DEFAULT
- r = heap_caps_realloc_default(p, size);
+ r = __real_heap_caps_realloc_default(p, size);
}
if (tracing && r != NULL) {
get_call_stack(callers);
{
return trace_realloc(p, size, caps, TRACE_MALLOC_CAPS);
}
+
+IRAM_ATTR void *__wrap_heap_caps_malloc_default( size_t size )
+{
+ return trace_malloc(size, 0, TRACE_MALLOC_DEFAULT);
+}
+
+IRAM_ATTR void *__wrap_heap_caps_realloc_default( void *ptr, size_t size )
+{
+ return trace_realloc(ptr, size, 0, TRACE_MALLOC_DEFAULT);
+}
#include "sdkconfig.h"
#include "unity.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+
#ifdef CONFIG_HEAP_TRACING
// only compile in heap tracing tests if tracing is enabled
heap_trace_stop();
}
+static void print_floats_task(void *ignore)
+{
+ heap_trace_start(HEAP_TRACE_ALL);
+ char buf[16] = { };
+ volatile float f = 12.3456;
+ sprintf(buf, "%.4f", f);
+ TEST_ASSERT_EQUAL_STRING("12.3456", buf);
+ heap_trace_stop();
+
+ vTaskDelete(NULL);
+}
+
+TEST_CASE("can trace allocations made by newlib", "[heap]")
+{
+ const size_t N = 8;
+ heap_trace_record_t recs[N];
+ heap_trace_init_standalone(recs, N);
+
+ /* Verifying that newlib code performs an allocation is very fiddly:
+
+ - Printing a float allocates data associated with the task, but only the
+ first time a task prints a float of this length. So we do it in a one-shot task
+ to avoid possibility it already happened.
+
+ - If newlib is updated this test may start failing if the printf() implementation
+ changes. (This version passes for both nano & regular formatting in newlib 2.2.0)
+
+ - We also do the tracing in the task so we only capture things directly related to it.
+ */
+
+ xTaskCreate(print_floats_task, "print_float", 4096, NULL, 5, NULL);
+ vTaskDelay(10);
+
+ /* has to be at least a few as newlib allocates via multiple different function calls */
+ TEST_ASSERT(heap_trace_get_count() > 3);
+}
#endif