abort handler: Fix abort stack trace when abort() called in ISR

Previously, this resulted in task stack frames turning up incorrectly in the backtrace, ie

Backtrace: 0x400d22a0:0x3ffb0fa0 0x40085a3c:0x3ffb0fc0 0x400f32c4:0x3ffb0fe0 0x40081965:0x3ffb1010
0x400d22a0: esp_vApplicationIdleHook at /home/esp/esp-idf/components/esp32/./freertos_hooks.c:
52
0x40085a3c: prvIdleTask at /home/esp/esp-idf/components/freertos/./tasks.c:4431
0x400f32c4: i2c_isr_handler_default at /home/esp/esp-idf/components/driver/./i2c.c:598
0x40081965: _xt_lowint1 at xtensa_vectors.o:?

Fix is to implement abort() via an unhandled exception rather than a breakpoint, I think
because of relative priority of exception types.

Another approach would be to assign a software-only INUM to abort()ing and defined a
PANIC_RSN_ABORTED, but this is more complex and interrupt numbers are more scarce than RAM!
This commit is contained in:
Angus Gratton
2017-06-08 15:21:03 +10:00
committed by Angus Gratton
parent 82b8b1db1f
commit 47e789f538

View File

@@ -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) {
if (esp_cpu_in_ocd_debug_mode()) {
__asm__ ("break 0,0"); __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,7 +200,6 @@ 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) {
@@ -228,9 +230,6 @@ void panicHandler(XtExcFrame *frame)
if (debugRsn&XCHAL_DEBUGCAUSE_DEBUGINT_MASK) panicPutStr("DebugIntr "); if (debugRsn&XCHAL_DEBUGCAUSE_DEBUGINT_MASK) panicPutStr("DebugIntr ");
panicPutStr("\r\n"); panicPutStr("\r\n");
} }
} else {
panicPutStr("abort)\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,9 +244,10 @@ void panicHandler(XtExcFrame *frame)
void xt_unhandled_exception(XtExcFrame *frame) void xt_unhandled_exception(XtExcFrame *frame)
{ {
haltOtherCore(); haltOtherCore();
if (!abort_called) {
panicPutStr("Guru Meditation Error of type "); panicPutStr("Guru Meditation Error of type ");
int exccause = frame->exccause; int exccause = frame->exccause;
if (exccause < 40) { if (exccause < NUM_EDESCS) {
panicPutStr(edesc[exccause]); panicPutStr(edesc[exccause]);
} else { } else {
panicPutStr("Unknown"); panicPutStr("Unknown");
@@ -267,6 +267,7 @@ void xt_unhandled_exception(XtExcFrame *frame)
return; return;
} }
panicPutStr(". Exception was unhandled.\r\n"); panicPutStr(". Exception was unhandled.\r\n");
}
commonErrorHandler(frame); commonErrorHandler(frame);
} }
@@ -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;