diff --git a/components/heap/include/heap_trace.inc b/components/heap/include/heap_trace.inc index b4dd1a5b2c7..0b382c30b6f 100644 --- a/components/heap/include/heap_trace.inc +++ b/components/heap/include/heap_trace.inc @@ -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"); diff --git a/docs/en/api-reference/system/heap_debug.rst b/docs/en/api-reference/system/heap_debug.rst index 31d9c9f985c..b0c2fea417b 100644 --- a/docs/en/api-reference/system/heap_debug.rst +++ b/docs/en/api-reference/system/heap_debug.rst @@ -568,7 +568,7 @@ In ``HEAP_TRACE_ALL``: .. only:: CONFIG_IDF_TARGET_ARCH_RISCV - By default, the depth of the call stack recorded for each trace entry is 0, which means that only the direct caller of the memory allocation function can be retrieve. However, when the ``CONFIG_ESP_SYSTEM_USE_FRAME_POINTER`` option is enabled, this call stack depth can be configured in the project configuration menu, under ``Heap Memory Debugging`` > ``Enable heap tracing`` > :ref:`CONFIG_HEAP_TRACING_STACK_DEPTH`. Up to 32 stack frames can be recorded for each allocation (the default is 2). Each additional stack frame increases the memory usage of each ``heap_trace_record_t`` record by eight bytes. + By default, the call stack depth for each trace entry is 0: no caller PCs are recorded (allocation address, size, and related fields are still traced). Enable ``CONFIG_ESP_SYSTEM_USE_FRAME_POINTER`` to walk the stack, then configure the depth under ``Heap Memory Debugging`` > ``Enable heap tracing`` > :ref:`CONFIG_HEAP_TRACING_STACK_DEPTH`. Up to 32 stack frames can be recorded for each allocation (the default is 2). Each additional stack frame increases the memory usage of each ``heap_trace_record_t`` record by eight bytes. Finally, the total number of the 'leaked' bytes (bytes allocated but not freed while the trace is running) is printed together with the total number of allocations it represents. diff --git a/docs/zh_CN/api-reference/system/heap_debug.rst b/docs/zh_CN/api-reference/system/heap_debug.rst index e6811e9ff1d..6dadaf2aa8c 100644 --- a/docs/zh_CN/api-reference/system/heap_debug.rst +++ b/docs/zh_CN/api-reference/system/heap_debug.rst @@ -568,7 +568,7 @@ KASAN 使用自己的堆内存钩子和红区方案。请勿同时启用堆内 .. only:: CONFIG_IDF_TARGET_ARCH_RISCV - 默认情况下,每个跟踪条目记录的调用栈深度为 0,所以只能检索到内存分配函数的直接调用者。但是,启用 ``CONFIG_ESP_SYSTEM_USE_FRAME_POINTER`` 选项后,可以在项目配置菜单下配置此调用栈深度,选择 ``Heap Memory Debugging`` > ``Enable heap tracing`` > :ref:`CONFIG_HEAP_TRACING_STACK_DEPTH`。每个内存分配最多可以记录 32 个栈帧(默认为 2),每增加一个栈帧,每个 ``heap_trace_record_t`` 记录的内存使用量将增加 8 个字节。 + 默认情况下,每个跟踪条目的调用栈深度为 0:不记录调用者 PC(仍会跟踪分配地址、大小等相关字段)。启用 ``CONFIG_ESP_SYSTEM_USE_FRAME_POINTER`` 后才能遍历调用栈,然后可在项目配置菜单下配置深度,选择 ``Heap Memory Debugging`` > ``Enable heap tracing`` > :ref:`CONFIG_HEAP_TRACING_STACK_DEPTH`。每个内存分配最多可以记录 32 个栈帧(默认为 2),每增加一个栈帧,每个 ``heap_trace_record_t`` 记录的内存使用量将增加 8 个字节。 最后,将打印“泄漏”的总字节数(即在跟踪期间分配但未释放的总字节数),以及它所代表的总分配次数。