ESP32 crash decoder
Paste a Guru Meditation, abort, assert, watchdog, or brownout log from an ESP32, S2, S3, C3, C6, or H2 and get the cause explained, the registers annotated, the backtrace resolved against your ELF, and the reset reason decoded.
Added
How to use it
How to use it
Paste the serial monitor output — ideally from the ROM rst:0x… boot:0x… lines through the
Backtrace: and ELF file SHA256: lines. Timestamps and colour codes from idf.py monitor,
PlatformIO, or the Arduino serial monitor are ignored. The chip is detected from the ROM banner
(ESP-ROM:esp32c3-…, ets Jun 8 2016), the register set (Xtensa PC/PS/EXCCAUSE or RISC-V
MEPC/MCAUSE), and the addresses; override it from the menu if needed. Pick a sample to see
each kind of failure.
What it recognises:
-
Guru Meditation panics with the full Xtensa EXCCAUSE table (LoadProhibited, StoreProhibited, InstrFetchProhibited, IllegalInstruction, IntegerDivideByZero, LoadStoreAlignment, Cp0Dis…), ESP-IDF’s pseudo-causes (interrupt watchdog, cache disabled, unhandled debug exception, double exception), and RISC-V mcause values (load/store access faults, illegal instruction, misaligned access, stack protection fault, memory protection).
-
abort(),assert failed:(new and old formats),ESP_ERROR_CHECK failedwith theesp_err_tname, FreeRTOS stack overflow, stack canary watchpoints, task watchdog reports (which tasks starved and what was running), brownouts,CORRUPT HEAPmessages, ISR context, and boot loops. -
The register dump, each register annotated: PC and EXCVADDR/MTVAL classified against the chip’s memory map (IRAM, DRAM, flash IROM/DROM, ROM, RTC, peripherals, PSRAM, unmapped), A0 turned into the caller’s return address, the PS and MSTATUS bit fields, and recognisable values — NULL and NULL-plus-offset, the 0xA5 FreeRTOS stack fill, heap-poisoning fills 0xFEFEFEFE/0xCECECECE, and ASCII text where a pointer should be.
-
The backtrace (PC:SP pairs,
|←CORRUPTED,|←CONTINUES, both cores) and, on RISC-V, likely return addresses picked out of the printed stack memory. -
Reset reasons with the ROM names for each chip and what usually causes them, and the boot strapping value (download mode, the ESP32 GPIO12 1.8 V flash trap).
Resolving addresses
Load the firmware.elf (or build/<project>.elf) from the build that crashed. Its symbol
table gives the function and offset of every address; if it was built with debug info, the
DWARF .debug_line table (DWARF 2–5) gives the source file and line, matching
addr2line -pfa — inlined call chains are not expanded. C++ names are demangled. The ELF’s
SHA-256 is compared with the ELF file SHA256: line, because decoding against a different
build gives wrong answers. The ELF is read in your browser and never uploaded.
Without an ELF the tool generates the xtensa-esp32-elf-addr2line -pfiaC -e build/app.elf …
(or riscv32-esp-elf-addr2line) command for every code address, and lists the monitor
options that decode automatically: idf.py monitor, esp-idf-monitor, and PlatformIO’s
monitor_filters = esp32_exception_decoder.
The Reference tab has each chip’s memory map, reset reason table, the EXCCAUSE or mcause
table, and common esp_err_t codes. Sources: ESP-IDF v5.4 (panic_arch.c, soc.h,
rom/rtc.h) and esptool’s memory maps. The hints are heuristics — the backtrace and your
code have the last word.
Sharing
Share link copies a URL that opens this tool with your current settings — every value it remembers between visits, packed into ?s=. Opening a link replaces your saved settings for this tool. You can also write a short link by hand with chip (the chip; the pasted crash dump travels packed in ?s=), for example /tools/esp-crash/?chip=esp32s3. The ELF file is never included — load it again after opening the link.
Feedback is a gift. Something to improve, a feature to add, or a bug? Tell me.
Runs entirely in your browser; nothing you type leaves this page.