fix(heap): avoid stack smash when heap tracing stack depth is 0

On RISC-V without frame pointers, STACK_DEPTH defaults to 0, so
alloced_by[] is empty. Writing callers[0] still ran and overwrote the
caller's cm.push saved ra, causing an illegal-instruction fault after
the first traced malloc (e.g. with HEAP_TRACING on ESP32-S31).
This commit is contained in:
Alexey Lapshin
2026-08-03 16:07:54 +07:00
parent ee2ef95cfe
commit aecc6eab60
3 changed files with 9 additions and 10 deletions
+7 -8
View File
@@ -85,24 +85,23 @@ static HEAP_IRAM_ATTR __attribute__((noinline)) void get_call_stack(void **calle
#else // !CONFIG_IDF_TARGET_ARCH_XTENSA
extern uint32_t esp_fp_get_callers(uint32_t frame, void** callers, void** stacks, uint32_t depth);
static HEAP_IRAM_ATTR __attribute__((noinline)) void get_call_stack(void **callers)
{
#if STACK_DEPTH == 0
/* alloced_by[] / freed_by[] are empty — nothing to capture;
* writing callers[0] would smash the caller's stack. */
(void)callers;
#else
uint32_t fp = (uint32_t) __builtin_frame_address(0);
memset(callers, 0, sizeof(void *) * STACK_DEPTH);
#if CONFIG_ESP_SYSTEM_USE_FRAME_POINTER
/* We can skip the current return address since this function won't be inlined */
uint32_t esp_fp_get_callers(uint32_t, void **, void **, uint32_t);
esp_fp_get_callers(fp, callers, NULL, STACK_DEPTH);
#else
/* RISC-V compiler doesn't support `__builtin_frame_address` with a parameter bigger than 0 */
callers[0] = (void*) fp;
#endif
}
#endif
#endif /* CONFIG_IDF_TARGET_ARCH_XTENSA */
ESP_STATIC_ASSERT(STACK_DEPTH >= 0 && STACK_DEPTH <= 32, "CONFIG_HEAP_TRACING_STACK_DEPTH must be in range 0-32");