Howto: разбор краша по core dump¶
Если контроллер внезапно перезагрузился, и причина не очевидна — у прошивки есть core dump: снимок регистров, стеков и списка задач, сохранённый в момент сбоя. По нему восстанавливается точный backtrace.
Когда core dump создаётся¶
Дамп пишется в flash-партицию coredump (64 КБ) при аварийном
ребуте:
- panic — необработанное исключение,
abort(), разыменование нулевого указателя, stack canary и т.п. - task watchdog (TWDT) — задача зависла и не покормила watchdog.
НЕ создаётся при:
POWERON/SW_RESET(штатная перезагрузка, OTA-apply,/api/system/restart)BROWNOUT— просадка питания. Дампа не будет, но сам фактreset_reason = BROWNOUTв/api/diag/systemуже указывает на проблему с питанием, а не с прошивкой.
Категория последнего ребута всегда видна: GET /api/diag/system →
поле reset_reason.
Шаг 1. Проверить, есть ли дамп¶
Через web-UI: вкладка «Диагностика» → карточка «Core dump».
Бейдж в шапке: чисто — дампа нет, есть дамп — креш зафиксирован.
Развернув карточку, видно задачу, PC и backtrace.
Через API:
{
"available": true,
"size": 8192,
"task": "dosator_1",
"pc": "0x400e1234",
"elf_sha256": "a1b2c3d4...",
"backtrace": ["0x400e1234", "0x40098765", "0x400d4321"],
"bt_corrupted": false
}
| Поле | Что говорит |
|---|---|
task |
В какой задаче произошёл сбой |
pc |
Адрес инструкции на момент сбоя |
backtrace |
Цепочка адресов вызовов |
elf_sha256 |
SHA-256 ELF — какой именно прошивке соответствует дамп |
bt_corrupted |
Backtrace частично повреждён (стек затёрт) — доверять осторожно |
Часто task + первый-второй адрес backtrace уже подсказывают, где
копать. Для точного «файл:строка» — шаг 2.
Шаг 2. Точный разбор через espcoredump.py¶
espcoredump.py сопоставляет адреса дампа с символами в ELF и выдаёт
человекочитаемый backtrace (функции, файлы, строки).
2.1. Скачать бинарь дампа¶
UI: кнопка «Скачать .bin» в карточке. Или:
2.2. Взять ELF той же версии¶
Критично: нужен firmware.elf ровно той прошивки, что крешнулась.
Символы в ELF другой версии не совпадут с адресами дампа → разбор
будет врать.
- Сразу после сборки ELF лежит в
.pio/build/esp32dev/firmware.elf. - Сверить версию:
elf_sha256из ответа API должен совпасть с ELF. - Рекомендация: архивировать
firmware.elfпо каждому релизу (build уже пишет sha в манифест — привязывайтесь к ней).
2.3. Запустить разбор¶
espcoredump.py входит в состав ESP-IDF. Если стоит PlatformIO —
он внутри пакета framework-espidf / toolchain. Проще всего:
# через esptool/idf, путь к espcoredump.py зависит от установки
espcoredump.py info_corefile -c coredump.bin firmware.elf
Вывод покажет:
- Crashed task и причину (
Exception cause,EXCVADDR) - Backtrace с именами функций:
dosatorTask at dosator.cpp:158 - Состояние регистров и стеки всех задач
- Свободную/занятую память на момент сбоя
Этого достаточно чтобы найти строку, где упало.
Шаг 3. Стереть дамп¶
После разбора — стереть, чтобы партиция была готова поймать следующий креш (новый дамп не перезапишет старый, пока тот не стёрт).
UI: кнопка «Стереть». Или:
Партиция core dump¶
Дамп пишется в партицию coredump (тип data, subtype coredump,
64 КБ) — см. memory-map.md.
Важно: партиция появилась добавлением строки в partitions_ota.csv.
Партиционная таблица обновляется только при прошивке по кабелю —
OTA её не трогает. Если устройство прошивалось только по OTA и в логе
есть esp_core_dump_flash: No core dump partition found — нужна одна
прошивка кабелем, чтобы таблица применилась. Offset'ы app0/app1/nvs
при этом не сдвигаются — настройки и данные не теряются.
Что core dump не покрывает¶
- BROWNOUT — питание просело, MCU не успел ничего сохранить.
Лечится по железу (БП, кабели),
reset_reasonэто и показывает. - Нарратив «что устройство делало перед крешем» — core dump даёт
состояние в момент сбоя, но не историю до него. Системный лог
(
/api/diag/log) живёт в RAM и стирается ребутом. Зеркалирование хвоста лога в RTC-память (переживает SW-reset) — потенциальное расширение.
См. также: api/diagnostics.md.