#include "platform/crash_report.h" #include #include "platform/system_info.h" #include "safe_mode.h" #include "version.h" namespace roro::crash_report { int noteBoot(KeyValueStore& store) { bool crashed = system_info::resetWasCrash(); std::string last; store.getString("run_ver", last); if (crashed) { store.putString("crash_ver", last.empty() ? versionString() : last); store.putString("crash_why", system_info::resetReason()); } if (last != versionString()) store.putString("run_ver", versionString()); int32_t before = 0; store.getInt("crash_boots", before); int now = SafeMode::countAtBoot(crashed, before); if (now != before) store.putInt("crash_boots", now); return now; } void noteStable(KeyValueStore& store) { int32_t n = 0; if (store.getInt("crash_boots", n) && n != 0) store.putInt("crash_boots", 0); } void print(Print& out, KeyValueStore& store) { std::string version, why; store.getString("crash_ver", version); store.getString("crash_why", why); if (version.empty()) out.println("crash: none recorded"); else out.printf("crash: last one in %s (%s)\n", version.c_str(), why.c_str()); esp_core_dump_summary_t sum; if (esp_core_dump_image_check() != ESP_OK || esp_core_dump_get_summary(&sum) != ESP_OK) { out.println("crash: no core dump in flash"); return; } char reason[160] = ""; esp_core_dump_get_panic_reason(reason, sizeof reason); out.printf("crash: task %s, pc 0x%08lx, cause %lu, address 0x%08lx\n", sum.exc_task, (unsigned long)sum.exc_pc, (unsigned long)sum.ex_info.exc_cause, (unsigned long)sum.ex_info.exc_vaddr); if (reason[0]) out.printf("crash: reason: %s\n", reason); out.print("crash: backtrace"); for (uint32_t i = 0; i < sum.exc_bt_info.depth && i < 16; i++) out.printf(" 0x%08lx", (unsigned long)sum.exc_bt_info.bt[i]); out.println(sum.exc_bt_info.corrupted ? " (corrupted)" : ""); out.printf("crash: elf sha256 %s\n", reinterpret_cast(sum.app_elf_sha256)); } std::string headline() { esp_core_dump_summary_t sum; std::string where = ""; if (esp_core_dump_image_check() == ESP_OK && esp_core_dump_get_summary(&sum) == ESP_OK) where = std::string(" in ") + sum.exc_task; return std::string("Restarted after a ") + system_info::resetReason() + where; } bool erase() { return esp_core_dump_image_erase() == ESP_OK; } } // namespace roro::crash_report