mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-09 04:25:32 +00:00
esp32: Refactor backtrace and add esp_backtrace_print()
This commit refactors backtracing within the panic handler so that a common function esp_backtrace_get_next_frame() is used iteratively to traverse a callstack. A esp_backtrace_print() function has also be added that allows the printing of a backtrace at runtime. The esp_backtrace_print() function allows unity to print the backtrace of failed test cases and jump back to the main test menu without the need reset the chip. esp_backtrace_print() can also be used as a debugging function by users. - esp_stack_ptr_is_sane() moved to soc_memory_layout.h - removed uncessary includes of "esp_debug_helpers.h"
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
#include "soc/cpu.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_wdt.h"
|
||||
#include "soc/soc_memory_layout.h"
|
||||
|
||||
#include "esp_private/gdbstub.h"
|
||||
#include "esp_debug_helpers.h"
|
||||
@@ -446,33 +447,36 @@ static void esp_panic_dig_reset()
|
||||
|
||||
static void putEntry(uint32_t pc, uint32_t sp)
|
||||
{
|
||||
if (pc & 0x80000000) {
|
||||
pc = (pc & 0x3fffffff) | 0x40000000;
|
||||
}
|
||||
panicPutStr(" 0x");
|
||||
panicPutHex(pc);
|
||||
panicPutStr(":0x");
|
||||
panicPutHex(sp);
|
||||
}
|
||||
|
||||
static void doBacktrace(XtExcFrame *frame)
|
||||
static void doBacktrace(XtExcFrame *exc_frame, int depth)
|
||||
{
|
||||
uint32_t i = 0, pc = frame->pc, sp = frame->a1;
|
||||
//Initialize stk_frame with first frame of stack
|
||||
esp_backtrace_frame_t stk_frame = {.pc = exc_frame->pc, .sp = exc_frame->a1, .next_pc = exc_frame->a0};
|
||||
panicPutStr("\r\nBacktrace:");
|
||||
/* Do not check sanity on first entry, PC could be smashed. */
|
||||
putEntry(pc, sp);
|
||||
pc = frame->a0;
|
||||
while (i++ < 100) {
|
||||
uint32_t psp = sp;
|
||||
if (!esp_stack_ptr_is_sane(sp) || i++ > 100) {
|
||||
break;
|
||||
}
|
||||
sp = *((uint32_t *) (sp - 0x10 + 4));
|
||||
putEntry(pc - 3, sp); // stack frame addresses are return addresses, so subtract 3 to get the CALL address
|
||||
pc = *((uint32_t *) (psp - 0x10));
|
||||
if (pc < 0x40000000) {
|
||||
break;
|
||||
putEntry(esp_cpu_process_stack_pc(stk_frame.pc), stk_frame.sp);
|
||||
|
||||
//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;
|
||||
uint32_t i = ((depth <= 0) ? INT32_MAX : depth) - 1; //Account for stack frame that's already printed
|
||||
while (i-- > 0 && stk_frame.next_pc != 0 && !corrupted) {
|
||||
if (!esp_backtrace_get_next_frame(&stk_frame)) { //Get next stack frame
|
||||
corrupted = true;
|
||||
}
|
||||
putEntry(esp_cpu_process_stack_pc(stk_frame.pc), stk_frame.sp);
|
||||
}
|
||||
|
||||
//Print backtrace termination marker
|
||||
if (corrupted) {
|
||||
panicPutStr(" |<-CORRUPTED");
|
||||
} else if (stk_frame.next_pc != 0) { //Backtrace continues
|
||||
panicPutStr(" |<-CONTINUES");
|
||||
}
|
||||
panicPutStr("\r\n");
|
||||
}
|
||||
@@ -549,7 +553,7 @@ static void commonErrorHandler_dump(XtExcFrame *frame, int core_id)
|
||||
panicPutStr("\r\n");
|
||||
|
||||
/* With windowed ABI backtracing is easy, let's do it. */
|
||||
doBacktrace(frame);
|
||||
doBacktrace(frame, 100);
|
||||
|
||||
panicPutStr("\r\n");
|
||||
}
|
||||
|
Reference in New Issue
Block a user