Merge branch 'bugfix/abort_in_interrupt_context' into 'master'

Panic handler backtrace fixes

See merge request !835
pull/622/merge
Angus Gratton 2017-06-14 13:45:36 +08:00
commit 8e0ec6a9ab
1 zmienionych plików z 54 dodań i 53 usunięć

Wyświetl plik

@ -119,7 +119,9 @@ static __attribute__((noreturn)) inline void invoke_abort()
esp_apptrace_flush_nolock(ESP_APPTRACE_DEST_TRAX, ESP_APPTRACE_TRAX_BLOCK_SIZE*CONFIG_ESP32_APPTRACE_ONPANIC_HOST_FLUSH_TRAX_THRESH/100, CONFIG_ESP32_APPTRACE_ONPANIC_HOST_FLUSH_TMO); esp_apptrace_flush_nolock(ESP_APPTRACE_DEST_TRAX, ESP_APPTRACE_TRAX_BLOCK_SIZE*CONFIG_ESP32_APPTRACE_ONPANIC_HOST_FLUSH_TRAX_THRESH/100, CONFIG_ESP32_APPTRACE_ONPANIC_HOST_FLUSH_TMO);
#endif #endif
while(1) { while(1) {
__asm__ ("break 0,0"); if (esp_cpu_in_ocd_debug_mode()) {
__asm__ ("break 0,0");
}
*((int*) 0) = 0; *((int*) 0) = 0;
} }
} }
@ -127,7 +129,7 @@ static __attribute__((noreturn)) inline void invoke_abort()
void abort() void abort()
{ {
#if !CONFIG_ESP32_PANIC_SILENT_REBOOT #if !CONFIG_ESP32_PANIC_SILENT_REBOOT
ets_printf("abort() was called at PC 0x%08x on core %d\n", (intptr_t)__builtin_return_address(0) - 3, xPortGetCoreID()); ets_printf("abort() was called at PC 0x%08x on core %d\r\n", (intptr_t)__builtin_return_address(0) - 3, xPortGetCoreID());
#endif #endif
invoke_abort(); invoke_abort();
} }
@ -146,6 +148,7 @@ static const char *edesc[] = {
"Cp4Dis", "Cp5Dis", "Cp6Dis", "Cp7Dis" "Cp4Dis", "Cp5Dis", "Cp6Dis", "Cp7Dis"
}; };
#define NUM_EDESCS (sizeof(edesc) / sizeof(char *))
static void commonErrorHandler(XtExcFrame *frame); static void commonErrorHandler(XtExcFrame *frame);
@ -197,40 +200,36 @@ void panicHandler(XtExcFrame *frame)
panicPutStr("Guru Meditation Error: Core "); panicPutStr("Guru Meditation Error: Core ");
panicPutDec(core_id); panicPutDec(core_id);
panicPutStr(" panic'ed ("); panicPutStr(" panic'ed (");
if (!abort_called) { panicPutStr(reason);
panicPutStr(reason); panicPutStr(")\r\n");
panicPutStr(")\r\n"); if (frame->exccause == PANIC_RSN_DEBUGEXCEPTION) {
if (frame->exccause == PANIC_RSN_DEBUGEXCEPTION) { int debugRsn;
int debugRsn; asm("rsr.debugcause %0":"=r"(debugRsn));
asm("rsr.debugcause %0":"=r"(debugRsn)); panicPutStr("Debug exception reason: ");
panicPutStr("Debug exception reason: "); if (debugRsn&XCHAL_DEBUGCAUSE_ICOUNT_MASK) panicPutStr("SingleStep ");
if (debugRsn&XCHAL_DEBUGCAUSE_ICOUNT_MASK) panicPutStr("SingleStep "); if (debugRsn&XCHAL_DEBUGCAUSE_IBREAK_MASK) panicPutStr("HwBreakpoint ");
if (debugRsn&XCHAL_DEBUGCAUSE_IBREAK_MASK) panicPutStr("HwBreakpoint "); if (debugRsn&XCHAL_DEBUGCAUSE_DBREAK_MASK) {
if (debugRsn&XCHAL_DEBUGCAUSE_DBREAK_MASK) { //Unlike what the ISA manual says, this core seemingly distinguishes from a DBREAK
//Unlike what the ISA manual says, this core seemingly distinguishes from a DBREAK //reason caused by watchdog 0 and one caused by watchdog 1 by setting bit 8 of the
//reason caused by watchdog 0 and one caused by watchdog 1 by setting bit 8 of the //debugcause if the cause is watchdog 1 and clearing it if it's watchdog 0.
//debugcause if the cause is watchdog 1 and clearing it if it's watchdog 0. if (debugRsn&(1<<8)) {
if (debugRsn&(1<<8)) {
#if CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK #if CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK
const char *name = pcTaskGetTaskName(xTaskGetCurrentTaskHandleForCPU(core_id)); const char *name = pcTaskGetTaskName(xTaskGetCurrentTaskHandleForCPU(core_id));
panicPutStr("Stack canary watchpoint triggered ("); panicPutStr("Stack canary watchpoint triggered (");
panicPutStr(name); panicPutStr(name);
panicPutStr(") "); panicPutStr(") ");
#else #else
panicPutStr("Watchpoint 1 triggered "); panicPutStr("Watchpoint 1 triggered ");
#endif #endif
} else { } else {
panicPutStr("Watchpoint 0 triggered "); panicPutStr("Watchpoint 0 triggered ");
}
}
if (debugRsn&XCHAL_DEBUGCAUSE_BREAK_MASK) panicPutStr("BREAK instr ");
if (debugRsn&XCHAL_DEBUGCAUSE_BREAKN_MASK) panicPutStr("BREAKN instr ");
if (debugRsn&XCHAL_DEBUGCAUSE_DEBUGINT_MASK) panicPutStr("DebugIntr ");
panicPutStr("\r\n");
} }
} else { }
panicPutStr("abort)\r\n"); if (debugRsn&XCHAL_DEBUGCAUSE_BREAK_MASK) panicPutStr("BREAK instr ");
} if (debugRsn&XCHAL_DEBUGCAUSE_BREAKN_MASK) panicPutStr("BREAKN instr ");
if (debugRsn&XCHAL_DEBUGCAUSE_DEBUGINT_MASK) panicPutStr("DebugIntr ");
panicPutStr("\r\n");
}
if (esp_cpu_in_ocd_debug_mode()) { if (esp_cpu_in_ocd_debug_mode()) {
#if CONFIG_ESP32_APPTRACE_ENABLE #if CONFIG_ESP32_APPTRACE_ENABLE
@ -245,28 +244,30 @@ void panicHandler(XtExcFrame *frame)
void xt_unhandled_exception(XtExcFrame *frame) void xt_unhandled_exception(XtExcFrame *frame)
{ {
haltOtherCore(); haltOtherCore();
panicPutStr("Guru Meditation Error of type "); if (!abort_called) {
int exccause = frame->exccause; panicPutStr("Guru Meditation Error of type ");
if (exccause < 40) { int exccause = frame->exccause;
panicPutStr(edesc[exccause]); if (exccause < NUM_EDESCS) {
} else { panicPutStr(edesc[exccause]);
panicPutStr("Unknown"); } else {
} panicPutStr("Unknown");
panicPutStr(" occurred on core "); }
panicPutDec(xPortGetCoreID()); panicPutStr(" occurred on core ");
if (esp_cpu_in_ocd_debug_mode()) { panicPutDec(xPortGetCoreID());
panicPutStr(" at pc="); if (esp_cpu_in_ocd_debug_mode()) {
panicPutHex(frame->pc); panicPutStr(" at pc=");
panicPutStr(". Setting bp and returning..\r\n"); panicPutHex(frame->pc);
panicPutStr(". Setting bp and returning..\r\n");
#if CONFIG_ESP32_APPTRACE_ENABLE #if CONFIG_ESP32_APPTRACE_ENABLE
esp_apptrace_flush_nolock(ESP_APPTRACE_DEST_TRAX, ESP_APPTRACE_TRAX_BLOCK_SIZE*CONFIG_ESP32_APPTRACE_ONPANIC_HOST_FLUSH_TRAX_THRESH/100, CONFIG_ESP32_APPTRACE_ONPANIC_HOST_FLUSH_TMO); esp_apptrace_flush_nolock(ESP_APPTRACE_DEST_TRAX, ESP_APPTRACE_TRAX_BLOCK_SIZE*CONFIG_ESP32_APPTRACE_ONPANIC_HOST_FLUSH_TRAX_THRESH/100, CONFIG_ESP32_APPTRACE_ONPANIC_HOST_FLUSH_TMO);
#endif #endif
//Stick a hardware breakpoint on the address the handler returns to. This way, the OCD debugger //Stick a hardware breakpoint on the address the handler returns to. This way, the OCD debugger
//will kick in exactly at the context the error happened. //will kick in exactly at the context the error happened.
setFirstBreakpoint(frame->pc); setFirstBreakpoint(frame->pc);
return; return;
}
panicPutStr(". Exception was unhandled.\r\n");
} }
panicPutStr(". Exception was unhandled.\r\n");
commonErrorHandler(frame); commonErrorHandler(frame);
} }
@ -374,7 +375,7 @@ static void doBacktrace(XtExcFrame *frame)
break; break;
} }
sp = *((uint32_t *) (sp - 0x10 + 4)); sp = *((uint32_t *) (sp - 0x10 + 4));
putEntry(pc, sp); putEntry(pc - 3, sp); // stack frame addresses are return addresses, so subtract 3 to get the CALL address
pc = *((uint32_t *) (psp - 0x10)); pc = *((uint32_t *) (psp - 0x10));
if (pc < 0x40000000) { if (pc < 0x40000000) {
break; break;
@ -389,7 +390,7 @@ void esp_restart_noos() __attribute__ ((noreturn));
We arrive here after a panic or unhandled exception, when no OCD is detected. Dump the registers to the We arrive here after a panic or unhandled exception, when no OCD is detected. Dump the registers to the
serial port and either jump to the gdb stub, halt the CPU or reboot. serial port and either jump to the gdb stub, halt the CPU or reboot.
*/ */
static void commonErrorHandler(XtExcFrame *frame) static __attribute__((noreturn)) void commonErrorHandler(XtExcFrame *frame)
{ {
int *regs = (int *)frame; int *regs = (int *)frame;
int x, y; int x, y;