Public Access
Every build now records at boot which version runs and, after a crash restart, which one crashed (even across a Rollback). The core dump summary (task, PC, reason, backtrace) is printed and raised as a Notification; `crash` shows it later. After 3 crash restarts in a row the firmware starts in Safe Mode: clock, Wi-Fi, Update Service and Debug Console only (SafeMode, 2 host tests). A normal restart or a minute up resets the count. The main loop is now on the task watchdog (enableLoopWDT): Arduino only watched core 0's idle task, so a stuck loop hung the device for good. The Update Service restarts into an installed update by itself if the main loop hasn't after 90 s. Debug Builds: `coredump get` and `reset` are answered by the console's own task; rdbg.py crash decodes the backtrace and rdbg.py coredump runs esp-coredump, against ELFs archived by version and digest in .pio/elves. The StorageService mutex is now made in the constructor: Safe Mode never starts that Service, and `info` crashed on the null mutex, 29 times in a row before the fix was pushed into Safe Mode over Wi-Fi. Verified on the device: crash report and full core dump decoded over Wi-Fi; Safe Mode at exactly 3 crashes, left by `reboot`; a hung loop caught by the watchdog in 5 s; `reset` from the console task. ADR 0005. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
27 lines
977 B
C++
27 lines
977 B
C++
#pragma once
|
|
|
|
#include <Print.h>
|
|
|
|
#include <string>
|
|
|
|
#include "key_value_store.h"
|
|
|
|
namespace roro::crash_report {
|
|
|
|
// First thing at boot: remembers which version runs, and after a crash restart, which version
|
|
// crashed (the one that ran last time, even if a Rollback has switched slots since). Returns how
|
|
// many starts in a row ended in a crash, for Safe Mode.
|
|
int noteBoot(KeyValueStore& store);
|
|
// The device has been up long enough: the crash streak is over.
|
|
void noteStable(KeyValueStore& store);
|
|
|
|
// The last crash: which firmware, why, and the task, PC and backtrace from the core dump in flash.
|
|
// Decode the backtrace on the PC with scripts/decode_backtrace.sh <version> <addresses>.
|
|
void print(Print& out, KeyValueStore& store);
|
|
// One line for a Notification after a crash restart, e.g. "Restarted after a crash in loopTask".
|
|
std::string headline();
|
|
// Forgets the core dump, so the next crash's is the one kept.
|
|
bool erase();
|
|
|
|
} // namespace roro::crash_report
|