From 3cc64f7877c740df8f0c8915bc16c2655c6310e7 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Tue, 16 Jul 2019 00:34:45 +0200 Subject: [PATCH] Fix raise_exception() (#6288) * workaround when an exceptin occurs while in an ISR * tuning for gdb * remove dead code and rename defines/variables * per reviews: naming, handle "unhandled return" case * fix reset message --- cores/esp8266/core_esp8266_postmortem.cpp | 42 +++++++++++++++-------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/cores/esp8266/core_esp8266_postmortem.cpp b/cores/esp8266/core_esp8266_postmortem.cpp index f18dcfe53..bbe67f1d4 100644 --- a/cores/esp8266/core_esp8266_postmortem.cpp +++ b/cores/esp8266/core_esp8266_postmortem.cpp @@ -52,6 +52,13 @@ static void uart0_write_char_d(char c); static void uart1_write_char_d(char c); static void print_stack(uint32_t start, uint32_t end); +// using numbers different from "REASON_" in user_interface.h (=0..6) +enum rst_reason_sw +{ + REASON_USER_SWEXCEPTION_RST = 254 +}; +static int s_user_reset_reason = REASON_DEFAULT_RST; + // From UMM, the last caller of a malloc/realloc/calloc which failed: extern void *umm_last_fail_alloc_addr; extern int umm_last_fail_alloc_size; @@ -86,24 +93,20 @@ void __wrap_system_restart_local() { register uint32_t sp asm("a1"); uint32_t sp_dump = sp; - if (gdb_present()) { - /* When GDBStub is present, exceptions are handled by GDBStub, - but Soft WDT will still call this function. - Trigger an exception to break into GDB. - TODO: check why gdb_do_break() or asm("break.n 0") do not - break into GDB here. */ - raise_exception(); - } - struct rst_info rst_info; memset(&rst_info, 0, sizeof(rst_info)); - system_rtc_mem_read(0, &rst_info, sizeof(rst_info)); - if (rst_info.reason != REASON_SOFT_WDT_RST && - rst_info.reason != REASON_EXCEPTION_RST && - rst_info.reason != REASON_WDT_RST) + if (s_user_reset_reason == REASON_DEFAULT_RST) { - return; + system_rtc_mem_read(0, &rst_info, sizeof(rst_info)); + if (rst_info.reason != REASON_SOFT_WDT_RST && + rst_info.reason != REASON_EXCEPTION_RST && + rst_info.reason != REASON_WDT_RST) + { + rst_info.reason = REASON_DEFAULT_RST; + } } + else + rst_info.reason = s_user_reset_reason; // TODO: ets_install_putc1 definition is wrong in ets_sys.h, need cast ets_install_putc1((void *)&uart_write_char_d); @@ -128,6 +131,9 @@ void __wrap_system_restart_local() { else if (rst_info.reason == REASON_SOFT_WDT_RST) { ets_printf_P(PSTR("\nSoft WDT reset\n")); } + else { + ets_printf_P(PSTR("\nGeneric Reset\n")); + } uint32_t cont_stack_start = (uint32_t) &(g_pcont->stack); uint32_t cont_stack_end = (uint32_t) g_pcont->stack_end; @@ -222,7 +228,13 @@ static void uart1_write_char_d(char c) { } static void raise_exception() { - __asm__ __volatile__ ("syscall"); + if (gdb_present()) + __asm__ __volatile__ ("syscall"); // triggers GDB when enabled + + s_user_reset_reason = REASON_USER_SWEXCEPTION_RST; + ets_printf_P(PSTR("\nUser exception (panic/abort/assert)")); + __wrap_system_restart_local(); + while (1); // never reached, needed to satisfy "noreturn" attribute }