From ed7bfa3e0f455fe6fee285c91e2d95e932b365df Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 5 Apr 2026 12:51:34 -1000 Subject: [PATCH] Detect divide-by-zero from ROM ILL instruction pattern GCC's ROM divide routine triggers IllegalInstruction (exccause=0) at ROM addresses 0x4000dce5/0x4000dd3d instead of IntegerDivideByZero (exccause=6). Patch exccause to match the Arduino core's postmortem handler behavior. --- esphome/components/esp8266/crash_handler.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/esphome/components/esp8266/crash_handler.cpp b/esphome/components/esp8266/crash_handler.cpp index 02bd34d485..f9308ca75c 100644 --- a/esphome/components/esp8266/crash_handler.cpp +++ b/esphome/components/esp8266/crash_handler.cpp @@ -200,11 +200,17 @@ void crash_handler_log() { uint8_t bt_count = read_rtc_backtrace(backtrace, MAX_BACKTRACE); ESP_LOGE(TAG, "*** CRASH DETECTED ON PREVIOUS BOOT ***"); - // Show exception cause for all crash types — WDT resets also populate exccause - const LogString *cause = get_exception_cause(resetInfo.exccause); + // GCC's ROM divide routine triggers IllegalInstruction (exccause=0) at specific + // ROM addresses instead of IntegerDivideByZero (exccause=6). Patch to match + // the Arduino core's postmortem handler behavior. + uint32_t exccause = resetInfo.exccause; + if (exccause == 0 && (resetInfo.epc1 == 0x4000dce5 || resetInfo.epc1 == 0x4000dd3d)) { + exccause = 6; // IntegerDivideByZero + } + const LogString *cause = get_exception_cause(exccause); if (cause != nullptr) { ESP_LOGE(TAG, " Reason: %s - %s (exccause=%" PRIu32 ")", LOG_STR_ARG(get_reset_reason(resetInfo.reason)), - LOG_STR_ARG(cause), resetInfo.exccause); + LOG_STR_ARG(cause), exccause); } else { ESP_LOGE(TAG, " Reason: %s", LOG_STR_ARG(get_reset_reason(resetInfo.reason))); }