mirror of
https://github.com/esphome/esphome.git
synced 2026-06-24 12:33:10 +00:00
[esp8266] Decode crash handler PC and backtrace in logs (#16911)
This commit is contained in:
@@ -492,6 +492,15 @@ def _parse_register(config, regex, line):
|
||||
STACKTRACE_ESP8266_EXCEPTION_TYPE_RE = re.compile(r"[eE]xception \((\d+)\):")
|
||||
STACKTRACE_ESP8266_PC_RE = re.compile(r"epc1=0x(4[0-9a-fA-F]{7})")
|
||||
STACKTRACE_ESP8266_EXCVADDR_RE = re.compile(r"excvaddr=0x(4[0-9a-fA-F]{7})")
|
||||
# Structured crash handler output (crash_handler.cpp) from a previous boot:
|
||||
# PC: 0x40220060
|
||||
# EXCVADDR: 0x0000008A
|
||||
# BT0: 0x40212345
|
||||
STACKTRACE_ESP8266_CRASH_PC_RE = re.compile(r".*PC\s*:\s*(?:0x)?(4[0-9a-fA-F]{7})")
|
||||
STACKTRACE_ESP8266_CRASH_EXCVADDR_RE = re.compile(
|
||||
r".*EXCVADDR\s*:\s*(?:0x)?(4[0-9a-fA-F]{7})"
|
||||
)
|
||||
STACKTRACE_ESP8266_CRASH_BT_RE = re.compile(r"BT\d+:\s*0x([0-9a-fA-F]{8})")
|
||||
STACKTRACE_BAD_ALLOC_RE = re.compile(
|
||||
r"^last failed alloc call: (4[0-9a-fA-F]{7})\((\d+)\)$"
|
||||
)
|
||||
@@ -508,10 +517,17 @@ def process_stacktrace(config, line, backtrace_state):
|
||||
"Exception type: %s", ESP8266_EXCEPTION_CODES.get(code, "unknown")
|
||||
)
|
||||
|
||||
# ESP8266 PC/EXCVADDR
|
||||
# ESP8266 PC/EXCVADDR (legacy Arduino postmortem)
|
||||
_parse_register(config, STACKTRACE_ESP8266_PC_RE, line)
|
||||
_parse_register(config, STACKTRACE_ESP8266_EXCVADDR_RE, line)
|
||||
|
||||
# ESP8266 structured crash handler (crash_handler.cpp) from previous boot
|
||||
_parse_register(config, STACKTRACE_ESP8266_CRASH_PC_RE, line)
|
||||
_parse_register(config, STACKTRACE_ESP8266_CRASH_EXCVADDR_RE, line)
|
||||
match = re.search(STACKTRACE_ESP8266_CRASH_BT_RE, line)
|
||||
if match is not None:
|
||||
_decode_pc(config, match.group(1))
|
||||
|
||||
# bad alloc
|
||||
match = re.match(STACKTRACE_BAD_ALLOC_RE, line)
|
||||
if match is not None:
|
||||
|
||||
@@ -45,6 +45,36 @@ def test_process_stacktrace_esp8266_backtrace(
|
||||
assert state is False
|
||||
|
||||
|
||||
def test_process_stacktrace_esp8266_crash_handler(
|
||||
setup_core: Path, mock_esp8266_decode_pc: Mock
|
||||
) -> None:
|
||||
"""Test process_stacktrace handles ESP8266 crash handler backtrace lines."""
|
||||
from esphome.components.esp8266 import process_stacktrace
|
||||
|
||||
config = {"name": "test"}
|
||||
|
||||
# Simulate crash handler log lines as they appear from the API/serial
|
||||
line_pc = "[E][esp8266:191]: PC: 0x40220060"
|
||||
state = process_stacktrace(config, line_pc, False)
|
||||
mock_esp8266_decode_pc.assert_called_once_with(config, "40220060")
|
||||
assert state is False
|
||||
|
||||
mock_esp8266_decode_pc.reset_mock()
|
||||
|
||||
# Near-null data address (wild pointer) is not a code address, must be ignored
|
||||
line_excvaddr = "[E][esp8266:193]: EXCVADDR: 0x0000008A"
|
||||
state = process_stacktrace(config, line_excvaddr, False)
|
||||
mock_esp8266_decode_pc.assert_not_called()
|
||||
assert state is False
|
||||
|
||||
mock_esp8266_decode_pc.reset_mock()
|
||||
|
||||
line_bt0 = "[E][esp8266:196]: BT0: 0x40212345"
|
||||
state = process_stacktrace(config, line_bt0, False)
|
||||
mock_esp8266_decode_pc.assert_called_once_with(config, "40212345")
|
||||
assert state is False
|
||||
|
||||
|
||||
def test_process_stacktrace_esp32_backtrace(
|
||||
setup_core: Path, mock_esp32_decode_pc: Mock
|
||||
) -> None:
|
||||
|
||||
Reference in New Issue
Block a user