diff --git a/cores/esp8266/StackThunk.cpp b/cores/esp8266/StackThunk.cpp index 7456fcaeeb..0d2a8a3541 100644 --- a/cores/esp8266/StackThunk.cpp +++ b/cores/esp8266/StackThunk.cpp @@ -142,11 +142,12 @@ void stack_thunk_dump_stack() ets_printf("<< + #include #include -#include "ets_sys.h" -extern "C" { +#include "cont.h" +#include "debug.h" -#define CONT_STACKGUARD 0xfeefeffe +extern "C" +{ + +static constexpr unsigned int CONT_STACKGUARD { 0xfeefeffe }; void cont_init(cont_t* cont) { memset(cont, 0, sizeof(cont_t)); @@ -42,10 +46,15 @@ void cont_init(cont_t* cont) { } } -int IRAM_ATTR cont_check(cont_t* cont) { - if(cont->stack_guard1 != CONT_STACKGUARD || cont->stack_guard2 != CONT_STACKGUARD) return 1; +void IRAM_ATTR cont_check(cont_t* cont) { + if ((cont->stack_guard1 == CONT_STACKGUARD) + && (cont->stack_guard2 == CONT_STACKGUARD)) + { + return; + } - return 0; + __stack_chk_fail(); + __builtin_unreachable(); } // No need for this to be in IRAM, not expected to be IRQ called diff --git a/cores/esp8266/core_esp8266_main.cpp b/cores/esp8266/core_esp8266_main.cpp index 430808f19d..cf6dd669f6 100644 --- a/cores/esp8266/core_esp8266_main.cpp +++ b/cores/esp8266/core_esp8266_main.cpp @@ -245,21 +245,21 @@ static void loop_wrapper() { } loop(); loop_end(); + cont_check(g_pcont); if (serialEventRun) { serialEventRun(); } esp_schedule(); } +extern "C" void __stack_chk_fail(void); + static void loop_task(os_event_t *events) { (void) events; s_cycles_at_resume = ESP.getCycleCount(); ESP.resetHeap(); cont_run(g_pcont, &loop_wrapper); ESP.setDramHeap(); - if (cont_check(g_pcont) != 0) { - panic(); - } } extern "C" { diff --git a/cores/esp8266/core_esp8266_postmortem.cpp b/cores/esp8266/core_esp8266_postmortem.cpp index 2279401b54..ce2817aaf6 100644 --- a/cores/esp8266/core_esp8266_postmortem.cpp +++ b/cores/esp8266/core_esp8266_postmortem.cpp @@ -42,9 +42,12 @@ static int s_panic_line = 0; static const char* s_panic_func = 0; static const char* s_panic_what = 0; +// Our wiring for abort() and C++ exceptions static bool s_abort_called = false; static const char* s_unhandled_exception = NULL; +// Common way to notify about where the stack smashing happened +// (but, **only** if caller uses our handler function) static uint32_t s_stacksmash_addr = 0; void abort() __attribute__((noreturn)); @@ -154,7 +157,7 @@ void __wrap_system_restart_local() { ets_printf_P(PSTR("\nSoft WDT reset\n")); } else if (rst_info.reason == REASON_USER_STACK_SMASH) { - ets_printf_P(PSTR("\nStack overflow detected.\n")); + ets_printf_P(PSTR("\nStack smashing detected.\n")); ets_printf_P(PSTR("\nException (%d):\nepc1=0x%08x epc2=0x%08x epc3=0x%08x excvaddr=0x%08x depc=0x%08x\n"), 5 /* Alloca exception, closest thing to stack fault*/, s_stacksmash_addr, 0, 0, 0, 0); } @@ -310,8 +313,6 @@ void __panic_func(const char* file, int line, const char* func) { uintptr_t __stack_chk_guard = 0x08675309 ^ RANDOM_REG32; void __stack_chk_fail(void) { s_user_reset_reason = REASON_USER_STACK_SMASH; - ets_printf_P(PSTR("\nPANIC: Stack overrun")); - s_stacksmash_addr = (uint32_t)__builtin_return_address(0); if (gdb_present()) @@ -319,8 +320,7 @@ void __stack_chk_fail(void) { __wrap_system_restart_local(); - while (1); // never reached, needed to satisfy "noreturn" attribute + __builtin_unreachable(); // never reached, needed to satisfy "noreturn" attribute } - -}; +} // extern "C" diff --git a/cores/esp8266/debug.h b/cores/esp8266/debug.h index c6ea8230ef..e6dc124c57 100644 --- a/cores/esp8266/debug.h +++ b/cores/esp8266/debug.h @@ -26,7 +26,7 @@ void hexdump(const void* mem, uint32_t len, uint8_t cols); extern "C" { #endif - + void __stack_chk_fail(void) __attribute__((noreturn)); void __unhandled_exception(const char* str) __attribute__((noreturn)); void __panic_func(const char* file, int line, const char* func) __attribute__((noreturn)); #define panic() __panic_func(PSTR(__FILE__), __LINE__, __func__)