diff --git a/components/esp_system/include/esp_debug_helpers.h b/components/esp_system/include/esp_debug_helpers.h index 0ba91b99a9..c64df641e1 100644 --- a/components/esp_system/include/esp_debug_helpers.h +++ b/components/esp_system/include/esp_debug_helpers.h @@ -41,6 +41,7 @@ typedef struct { uint32_t pc; /* PC of the current frame */ uint32_t sp; /* SP of the current frame */ uint32_t next_pc; /* PC of the current frame's caller */ + const void *exc_frame; /* Pointer to the full frame data structure, if applicable */ } esp_backtrace_frame_t; /** diff --git a/components/esp_system/port/arch/xtensa/debug_helpers.c b/components/esp_system/port/arch/xtensa/debug_helpers.c index 4d9aeb5936..0a819d5d73 100644 --- a/components/esp_system/port/arch/xtensa/debug_helpers.c +++ b/components/esp_system/port/arch/xtensa/debug_helpers.c @@ -23,6 +23,8 @@ #include "soc/cpu.h" #include "esp_private/panic_internal.h" +#include "xtensa/xtensa_context.h" + #include "sdkconfig.h" #include "esp_rom_sys.h" @@ -75,9 +77,10 @@ esp_err_t IRAM_ATTR esp_backtrace_print_from_frame(int depth, const esp_backtrac print_entry(esp_cpu_process_stack_pc(stk_frame.pc), stk_frame.sp, panic); //Check if first frame is valid - bool corrupted = (esp_stack_ptr_is_sane(stk_frame.sp) && - esp_ptr_executable((void*)esp_cpu_process_stack_pc(stk_frame.pc))) ? - false : true; + bool corrupted = !(esp_stack_ptr_is_sane(stk_frame.sp) && + (esp_ptr_executable((void *)esp_cpu_process_stack_pc(stk_frame.pc)) || + /* Ignore the first corrupted PC in case of InstrFetchProhibited */ + (stk_frame.exc_frame && ((XtExcFrame *)stk_frame.exc_frame)->exccause == EXCCAUSE_INSTR_PROHIBITED))); uint32_t i = (depth <= 0) ? INT32_MAX : depth; while (i-- > 0 && stk_frame.next_pc != 0 && !corrupted) { @@ -103,7 +106,7 @@ esp_err_t IRAM_ATTR esp_backtrace_print_from_frame(int depth, const esp_backtrac esp_err_t IRAM_ATTR esp_backtrace_print(int depth) { //Initialize stk_frame with first frame of stack - esp_backtrace_frame_t start; + esp_backtrace_frame_t start = { 0 }; esp_backtrace_get_start(&(start.pc), &(start.sp), &(start.next_pc)); return esp_backtrace_print_from_frame(depth, &start, false); } diff --git a/components/esp_system/port/arch/xtensa/panic_arch.c b/components/esp_system/port/arch/xtensa/panic_arch.c index b63f68572f..fb1e021df0 100644 --- a/components/esp_system/port/arch/xtensa/panic_arch.c +++ b/components/esp_system/port/arch/xtensa/panic_arch.c @@ -460,6 +460,6 @@ void panic_set_address(void *f, uint32_t addr) void panic_print_backtrace(const void *f, int core) { XtExcFrame *xt_frame = (XtExcFrame *) f; - esp_backtrace_frame_t frame = {.pc = xt_frame->pc, .sp = xt_frame->a1, .next_pc = xt_frame->a0}; + esp_backtrace_frame_t frame = {.pc = xt_frame->pc, .sp = xt_frame->a1, .next_pc = xt_frame->a0, .exc_frame = xt_frame}; esp_backtrace_print_from_frame(100, &frame, true); }