diff --git a/main/devices/Device.hpp b/main/devices/Device.hpp index 957552e8..f6fe6f03 100644 --- a/main/devices/Device.hpp +++ b/main/devices/Device.hpp @@ -5,10 +5,11 @@ #include -#include "esp_netif.h" -#include "esp_wifi.h" +#include +#include #include #include +#include #include @@ -495,6 +496,8 @@ class Device { json["state"] = static_cast(initState); json["peripherals"].to().set(peripheralsInitJson); json["sleepWhenIdle"] = kernel.powerManager.sleepWhenIdle; + + reportPreviousCrashIfAny(json); }, Retention::NoRetain, QoS::AtLeastOnce, 5s); @@ -542,6 +545,65 @@ class Device { } } + void reportPreviousCrashIfAny(JsonObject& json) { + esp_err_t errCheck = esp_core_dump_image_check(); + if (errCheck == ESP_ERR_NOT_FOUND) { + LOGV("No core dump found"); + return; + } + if (errCheck != ESP_OK) { + LOGE("Failed to check for core dump: %s", esp_err_to_name(errCheck)); + return; + } + + esp_core_dump_summary_t summary; + esp_err_t err = esp_core_dump_get_summary(&summary); + if (err != ESP_OK) { + LOGE("Failed to get core dump summary: %s", esp_err_to_name(err)); + } else { + auto crashJson = json["crash"].to(); + reportPreviousCrash(crashJson, summary); + } + + ESP_ERROR_CHECK_WITHOUT_ABORT(esp_core_dump_image_erase()); + } + + void reportPreviousCrash(JsonObject& json, const esp_core_dump_summary_t& summary) { + auto excCause = +#if __XTENSA__ + summary.ex_info.exc_cause; +#else + summary.ex_info.mcause; +#endif + + LOGW("Core dump found: task: %s, cause: %ld", + summary.exc_task, excCause); + + json["version"] = summary.core_dump_version; + json["sha256"] = String((const char*) summary.app_elf_sha256, CONFIG_APP_RETRIEVE_LEN_ELF_SHA); + json["task"] = summary.exc_task; + json["cause"] = excCause; + + static constexpr size_t PANIC_REASON_SIZE = 256; + char panicReason[PANIC_REASON_SIZE]; + if (esp_core_dump_get_panic_reason(panicReason, PANIC_REASON_SIZE) == ESP_OK) { + LOGW("Panic reason: %s", panicReason); + json["panicReason"] = panicReason; + } + + auto backtraceJson = json["backtrace"].to(); + if (summary.exc_bt_info.corrupted) { + LOGE("Backtrace corrupted, depth %lu", summary.exc_bt_info.depth); + backtraceJson["corrupted"] = true; + } else { + auto framesJson = backtraceJson["frames"].to(); + for (int i = 0; i < summary.exc_bt_info.depth; i++) { + auto& frame = summary.exc_bt_info.bt[i]; + framesJson.add("0x" + String(frame, HEX)); + } + } + } + Queue logRecords { "logs", 32 }; ConfiguredKernel configuredKernel { logRecords }; Kernel& kernel = configuredKernel.kernel; diff --git a/partitions.csv b/partitions.csv index 03a2a5c6..adce8e2c 100644 --- a/partitions.csv +++ b/partitions.csv @@ -3,5 +3,5 @@ nvs, data, nvs, 0x9000, 0x5000, otadata, data, ota, 0xe000, 0x2000, app0, app, ota_0, 0x10000, 0x1E0000, app1, app, ota_1, 0x1F0000,0x1E0000, -data, data, spiffs, 0x3D0000,0x20000, -coredump, data, coredump,0x3F0000,0x10000, +data, data, spiffs, 0x3D0000,0x18000, +coredump, data, coredump,0x3E8000,0x18000, diff --git a/sdkconfig.debug.defaults b/sdkconfig.debug.defaults index 3509855e..8343ecf4 100644 --- a/sdkconfig.debug.defaults +++ b/sdkconfig.debug.defaults @@ -1,6 +1,7 @@ CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE=y -CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=n -CONFIG_ESP_COREDUMP_ENABLE_TO_UART=y -CONFIG_ESP_COREDUMP_DECODE=y -CONFIG_ESP_COREDUMP_LOGS=y +CONFIG_ESP_SYSTEM_PANIC_GDBSTUB=y +CONFIG_ESP_DEBUG_OCDAWARE=y + +CONFIG_COMPILER_OPTIMIZATION_SIZE=n +CONFIG_COMPILER_OPTIMIZATION_DEBUG=y diff --git a/sdkconfig.defaults b/sdkconfig.defaults index e259a7b4..81329f4e 100644 --- a/sdkconfig.defaults +++ b/sdkconfig.defaults @@ -88,4 +88,5 @@ CONFIG_PM_LIGHT_SLEEP_CALLBACKS=y CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=y CONFIG_ESP_COREDUMP_CHECKSUM_SHA256=y +CONFIG_ESP_COREDUMP_DECODE_INFO=y CONFIG_ESP_COREDUMP_LOGS=n