From ea46f7a1b31c23c4299a681c3a18c752a5454523 Mon Sep 17 00:00:00 2001 From: David Kerr Date: Thu, 2 Jan 2025 20:01:30 -0500 Subject: [PATCH] Add support to display crash log and function call traceback addresses, fixes issue #2 --- CHANGELOG.md | 1 + README.md | 7 +-- lib/ratgdo/log.h | 39 +++--------- platformio.ini | 9 +-- src/log.cpp | 151 +++++++++++++++++++++++++++++++++------------- src/ratgdo.cpp | 36 +++++------ src/utilities.cpp | 11 +--- src/utilities.h | 2 - src/web.cpp | 30 ++------- src/web.h | 2 - src/www/logs.js | 2 +- 11 files changed, 152 insertions(+), 138 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60490ac..fc17587 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to `homekit-ratgdo32` will be documented in this file. This ### What's Changed * Feature: Add user setting to enable/disable parking assist laser, and set duration of assist laser. +* Feature: Added support to save log on crash (Issue #2) * Bugfix: Remove multiple copies of web page content from the firmware binary. * Bugfix: Use 64-bit integer to handle milliseconds since last boot. * Bugfix: Handle more possible return codes from vehicle distance sensor. diff --git a/README.md b/README.md index b85a2c9..73505ba 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,6 @@ > Firmware for the new DISCO device is under development. The following features, documented in this README, are not currently available in this version > and may never be implemented > -> * Crashlog display and download. > * Locking WiFi to specific WiFi access point. > * Setting WiFi protocol version. > * Setting WiFi transmit power. @@ -278,7 +277,7 @@ If the OTA firmware update fails the following message will be displayed and you ### Esptool -[Espressif](https://www.espressif.com) publishes [esptool](https://docs.espressif.com/projects/esptool/en/latest/esp8266/index.html), a command line utility built with python. Esptool requires that you connect a USB serial cable to the ratgdo device. +[Espressif](https://www.espressif.com) publishes [esptool](https://docs.espressif.com/projects/esptool/en/latest/esp32/index.html), a command line utility built with python. Esptool requires that you connect a USB serial cable to the ratgdo device. > [!NOTE] > The ratgdo32 firmware comprises multiple files. It is strongly recommended to use the [online browser-based flash tool](https://ratgdo.github.io/homekit-ratgdo32/flash.html) described above rather than use this command directly @@ -315,7 +314,7 @@ Resets and reboots the device. This will delete HomeKit pairing. ``` curl -s http:///crashlog ``` -Returns details of the last crash including stack trace and the message log leading up to the crash. __Not currently implemented on ratgdo32 boards.__ +Returns details of the last crash including stack trace and the message log leading up to the crash. ### Clear crash log @@ -412,7 +411,7 @@ has already found a fix. Great reliability improvements have been made in recent versions of the firmware, but it is possible that things can still go wrong. As noted above you should check that the door protocol is correctly set and if WiFi connection stability is suspected then you select a specific WiFi version. -The footer of the webpage displays useful information that can help project contributors assist with diagnosing a problem. The ESP8266 is a low-memory device so monitoring actual memory usage is first place to start. Whenever you connect to the webpage, the firmware reports memory utilization every second... current available free heap, the lowest value that free heap has reached since last reboot, and the minimum available stack reached since last reboot. +The footer of the webpage displays useful information that can help project contributors assist with diagnosing a problem. The ratgdo is a low-memory device so monitoring actual memory usage is first place to start. Whenever you connect to the webpage, the firmware reports memory utilization every second... current available free heap, the lowest value that free heap has reached since last reboot, and the minimum available stack reached since last reboot. In addition the last reboot date and time is reported (calculated by subtracting up-time from current time). diff --git a/lib/ratgdo/log.h b/lib/ratgdo/log.h index 798eb07..72761f4 100644 --- a/lib/ratgdo/log.h +++ b/lib/ratgdo/log.h @@ -25,10 +25,6 @@ void print_packet(uint8_t *pkt); -// #define LOG_MSG_BUFFER - -#ifdef LOG_MSG_BUFFER - #define CRASH_LOG_MSG_FILE "/crash_log" #define REBOOT_LOG_MSG_FILE "/reboot_log" @@ -36,21 +32,21 @@ void print_packet(uint8_t *pkt); // This can be large, but not too large. IRAM heap is approx 18KB, we also need // space for other data in here, so during development monitor logs and adjust // this smaller if necessary. IRAM malloc's are all done during startup. -#define LOG_BUFFER_SIZE 2048 +#define LOG_BUFFER_SIZE (1024 * 3) #else #define LOG_BUFFER_SIZE 1024 #endif #define LINE_BUFFER_SIZE 256 -#ifdef ENABLE_CRASH_LOG -void crashCallback(); -#endif - extern bool syslogEn; extern uint16_t syslogPort; extern char syslogIP[16]; extern bool suppressSerialLog; +extern time_t rebootTime; +extern time_t crashTime; +extern int16_t crashCount; + typedef struct logBuffer { uint16_t wrapped; // two bytes @@ -74,30 +70,15 @@ class LOG static LOG *getInstance() { return instancePtr; } void logToBuffer(const char *fmt, ...); - void printSavedLog(Print &outDevice = Serial); + void printSavedLog(Print &outDevice = Serial, bool fromNVram = false); void printMessageLog(Print &outDevice = Serial); - void saveMessageLog(); + void printCrashLog(Print &outDevice = Serial); + void saveMessageLog(bool toNVram = false); }; extern LOG *ratgdoLogger; #define RATGDO_PRINTF(message, ...) ratgdoLogger->logToBuffer(PSTR(message), ##__VA_ARGS__) -#define RINFO(tag, message, ...) RATGDO_PRINTF(">>> [%7llu] %s: " message "\n", millis64(), tag, ##__VA_ARGS__) -#define RERROR(tag, message, ...) RATGDO_PRINTF("!!! [%7llu] %s: " message "\n", millis64(), tag, ##__VA_ARGS__) -#else // LOG_MSG_BUFFER - -#ifndef UNIT_TEST - -#define RINFO(tag, message, ...) LOG0(">>> [%7llu] %s: " message "\n", millis64(), tag, ##__VA_ARGS__) -#define RERROR(tag, message, ...) LOG0("!!! [%7llu] %s: " message "\n", millis64(), tag, ##__VA_ARGS__) - -#else // UNIT_TEST - -#include -#define RINFO(tag, message, ...) printf(">>> %s: " message "\n", tag, ##__VA_ARGS__) -#define RERROR(tag, message, ...) printf("!!! %s: " message "\n", tag, ##__VA_ARGS__) - -#endif // UNIT_TEST - -#endif // LOG_MSG_BUFFER +#define RINFO(tag, message, ...) RATGDO_PRINTF(">>> [%7lu.%03u] %s: " message "\n", (uint32_t)(millis64() / 1000LL), (uint16_t)(millis64() % 1000LL), tag, ##__VA_ARGS__) +#define RERROR(tag, message, ...) RATGDO_PRINTF("!!! [%7lu.%03u] %s: " message "\n", (uint32_t)(millis64() / 1000LL), (uint16_t)(millis64() % 1000LL), tag, ##__VA_ARGS__) diff --git a/platformio.ini b/platformio.ini index 0592137..5db08b0 100644 --- a/platformio.ini +++ b/platformio.ini @@ -27,17 +27,14 @@ board_build.partitions = partitions.csv framework = arduino build_flags = ${env.build_flags} - -Wno-unused-variable + -Wall + -Wl,--wrap=esp_panic_handler -I./src -I./lib/ratgdo -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_ERROR -D SOC_WIFI_SUPPORTED=1 - -D LOG_MSG_BUFFER - ; -D ENABLE_CRASH_LOG - -D NTP_CLIENT -D USE_NTP_TIMESTAMP - ; -D GW_PING_CHECK -; -D CRASH_DEBUG + ;-D CRASH_DEBUG monitor_filters = esp32_exception_decoder lib_deps = https://github.com/ratgdo/espsoftwareserial.git#autobaud diff --git a/src/log.cpp b/src/log.cpp index 9c74e50..9a9d3d3 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -18,6 +18,8 @@ // Arduino includes #include +#include +#include // RATGDO project includes #include "ratgdo.h" @@ -42,7 +44,6 @@ void print_packet(uint8_t *pkt) void print_packet(uint8_t pkt[SECPLUS2_CODE_LEN]) {} #endif // UNIT_TEST -#ifdef LOG_MSG_BUFFER // Construct the singleton object for logger access LOG *LOG::instancePtr = new LOG(); LOG *ratgdoLogger = LOG::getInstance(); @@ -54,17 +55,41 @@ char syslogIP[16] = ""; WiFiUDP syslog; bool suppressSerialLog = false; +// There is 8KB of RTC memory that can be set to not initialize on restart. +// Data saved here will survive a crash and restart, but will not survive a power interruption. +RTC_NOINIT_ATTR logBuffer rtcRebootLog; +RTC_NOINIT_ATTR logBuffer rtcCrashLog; +RTC_NOINIT_ATTR time_t rebootTime; +RTC_NOINIT_ATTR time_t crashTime; +RTC_NOINIT_ATTR int16_t crashCount; +RTC_NOINIT_ATTR char reasonString[64]; +RTC_NOINIT_ATTR char crashVersion[16]; + +void panic_handler(arduino_panic_info_t *info, void *arg) +{ + // crashCount could be negative... indicating that there is a core dump image, but no saved crash log. + // But now we are saving a crash log, so need to make sure it is positive. + crashCount = (crashCount < 0) ? 1 : crashCount + 1; + crashTime = (clockSet) ? time(NULL) : 0; + esp_rom_printf("Panic Handler, crash count %d\n", crashCount); + memcpy(&rtcCrashLog, ratgdoLogger->msgBuffer, sizeof(rtcCrashLog)); + strlcpy(reasonString, info->reason, sizeof(reasonString)); + strlcpy(crashVersion, AUTO_VERSION, sizeof(crashVersion)); +} + // Constructor for LOG class LOG::LOG() { logMutex = xSemaphoreCreateRecursiveMutex(); msgBuffer = (logBuffer *)malloc(sizeof(logBuffer)); - // Fill the buffer with space chars... because if we crash and dump buffer before it fills + // Zero out the buffer... because if we crash and dump buffer before it fills // up, we want blank space not garbage! - memset(msgBuffer->buffer, 0x20, sizeof(msgBuffer->buffer)); + memset(msgBuffer->buffer, 0, sizeof(msgBuffer->buffer)); msgBuffer->wrapped = 0; msgBuffer->head = 0; lineBuffer = (char *)malloc(LINE_BUFFER_SIZE); + + set_arduino_panic_handler(panic_handler, NULL); } void LOG::logToBuffer(const char *fmt, ...) @@ -116,9 +141,9 @@ void LOG::logToBuffer(const char *fmt, ...) return; } -void LOG::saveMessageLog() +void LOG::saveMessageLog(bool toNVram) { - RINFO(TAG, "Save message log buffer to NVRAM"); + RINFO(TAG, "Save message log buffer%s", toNVram ? "to NVRAM" : ""); xSemaphoreTakeRecursive(logMutex, portMAX_DELAY); // We start by rotating the circular buffer so it is all in order. uint16_t first = 0; @@ -136,19 +161,33 @@ void LOG::saveMessageLog() // reset the index msgBuffer->head = 0; msgBuffer->wrapped = 0; - nvRam->writeBlob(nvram_messageLog, msgBuffer->buffer, sizeof(msgBuffer->buffer)); + memcpy(&rtcRebootLog, ratgdoLogger->msgBuffer, sizeof(rtcRebootLog)); + rebootTime = (clockSet) ? time(NULL) : 0; + if (toNVram) + nvRam->writeBlob(nvram_messageLog, msgBuffer->buffer, sizeof(msgBuffer->buffer)); xSemaphoreGiveRecursive(logMutex); } -void LOG::printSavedLog(Print &outputDev) +void LOG::printSavedLog(Print &outputDev, bool fromNVram) { - RINFO(TAG, "Print saved log from NVRAM"); - char *buf = (char *)malloc(sizeof(msgBuffer->buffer)); - if (buf) + RINFO(TAG, "Print saved log%s", fromNVram ? " from NVRAM" : ""); + if (fromNVram) { - nvRam->readBlob(nvram_messageLog, buf, sizeof(msgBuffer->buffer)); - outputDev.print(buf); - free(buf); + char *buf = (char *)malloc(sizeof(msgBuffer->buffer)); + if (buf) + { + nvRam->readBlob(nvram_messageLog, buf, sizeof(msgBuffer->buffer)); + outputDev.print(buf); + free(buf); + } + } + else if (rebootTime != 0) + { + outputDev.print(rtcRebootLog.buffer); + } + else + { + outputDev.print("\nNo saved log available\n"); } } @@ -161,20 +200,12 @@ extern "C" uint32_t __crc_val; void LOG::printMessageLog(Print &outputDev) { xSemaphoreTakeRecursive(logMutex, portMAX_DELAY); -#ifdef NTP_CLIENT if (enableNTP && clockSet) { outputDev.printf("Server time: %s\n", timeString()); } -#endif - outputDev.printf("Server uptime (ms): %llu\n", millis64()); + outputDev.printf("Server uptime (secs): %lu.%03u\n", (uint32_t)(millis64() / 1000LL), (uint16_t)(millis64() % 1000LL)); outputDev.printf("Firmware version: %s\n", AUTO_VERSION); -#ifdef ESP8266 - outputDev.write("Flash CRC: 0x"); - outputDev.println(__crc_val, 16); - outputDev.write("Flash length: "); - outputDev.println(__crc_len); -#endif outputDev.printf("Free heap: %lu\n", free_heap); outputDev.printf("Minimum heap: %lu\n\n", min_heap); if (msgBuffer) @@ -186,7 +217,60 @@ void LOG::printMessageLog(Print &outputDev) outputDev.write(&msgBuffer->buffer[start], sizeof(msgBuffer->buffer) - start); } outputDev.print(msgBuffer->buffer); // assumes null terminated - // outputDev.write(msgBuffer->buffer, start); + } + xSemaphoreGiveRecursive(logMutex); +} + +void LOG::printCrashLog(Print &outputDev) +{ + xSemaphoreTakeRecursive(logMutex, portMAX_DELAY); + if (crashCount > 0) + { + outputDev.printf("Time of crash: %s\n", timeString(crashTime)); + outputDev.printf("Crash reason: %s\n", reasonString); + outputDev.printf("Firmware version: %s\n\n", crashVersion); + // head points to a zero (null terminator of previous log line) which we need to skip. + size_t start = (rtcCrashLog.head + 1) % sizeof(rtcCrashLog.buffer); + if (rtcCrashLog.wrapped != 0) + { + outputDev.write(&rtcCrashLog.buffer[start], sizeof(rtcCrashLog.buffer) - start); + } + outputDev.print(rtcCrashLog.buffer); // assumes null terminated + } + + if (esp_core_dump_image_check() == ESP_OK) + { + esp_core_dump_summary_t *summary = (esp_core_dump_summary_t *)malloc(sizeof(esp_core_dump_summary_t)); + if (summary) + { + if (esp_core_dump_get_summary(summary) == ESP_OK) + { + if (crashCount <= 0) + outputDev.print("No saved crash log available for core dump."); + + outputDev.print("\n\n"); + outputDev.printf("Crash in task: %s, at address: 0x%08lX\n", summary->exc_task, summary->exc_pc); + outputDev.print("Decode backtrace with this Linux command:\n\n"); + if (crashCount > 0) + outputDev.printf("addr2line -p -f -C -e homekit-ratgdo32-v%s.elf \\\n", crashVersion); + else + outputDev.print("addr2line -p -f -C -e firmware.elf \\\n"); + outputDev.print(" -a "); + for (int i = 0; i < summary->exc_bt_info.depth; i++) + { + outputDev.printf("0x%08lX ", summary->exc_bt_info.bt[i]); + if (((i + 1) % 6) == 0 && ((i + 1) < summary->exc_bt_info.depth)) + outputDev.print("\\\n "); + } + outputDev.print("\n\n"); + outputDev.print("Make sure that the ELF file matches the binary that crashed.\n"); + } + } + free(summary); + } + else + { + outputDev.print("\n\nNo core dump image available.\n"); } xSemaphoreGiveRecursive(logMutex); } @@ -233,7 +317,7 @@ void logToSyslog(char *message) syslog.beginPacket(syslogIP, syslogPort); // Use RFC5424 Format syslog.printf("<%u>1 ", PRI); // PRI code -#if defined(NTP_CLIENT) && defined(USE_NTP_TIMESTAMP) +#if defined(USE_NTP_TIMESTAMP) syslog.print((enableNTP && clockSet) ? timeString(0, true) : SYSLOG_NIL); #else syslog.print(SYSLOG_NIL); // Time - let the syslog server insert time @@ -253,22 +337,3 @@ void logToSyslog(char *message) syslog.print(msg); // message syslog.endPacket(); } - -#ifdef ENABLE_CRASH_LOG -// TODO handle crashdump log -void crashCallback() -{ - if (ratgdoLogger->msgBuffer && ratgdoLogger->logMessageFile) - { - // ratgdoLogger->logMessageFile.truncate(0); - ratgdoLogger->logMessageFile.seek(0, fs::SeekSet); - ratgdoLogger->logMessageFile.println(); - ratgdoLogger->printMessageLog(ratgdoLogger->logMessageFile); - ratgdoLogger->logMessageFile.close(); - } - // We may not have enough memory to open the file and save the code - // save_rolling_code(); -} -#endif - -#endif // LOG_MSG_BUFFER diff --git a/src/ratgdo.cpp b/src/ratgdo.cpp index 0bb3364..8d132e8 100644 --- a/src/ratgdo.cpp +++ b/src/ratgdo.cpp @@ -67,25 +67,29 @@ void setup() ; // Wait for serial port to open Serial.printf("\n\n\n=== R A T G D O ===\n"); + // Beep on boot... + tone(BEEPER_PIN, 1300, 500); + led.on(); - if (esp_core_dump_image_check() == ESP_OK) + esp_reset_reason_t r = esp_reset_reason(); + switch (r) { - crashCount = 1; - Serial.printf("CORE DUMP FOUND\n"); - esp_core_dump_summary_t *summary = (esp_core_dump_summary_t *)malloc(sizeof(esp_core_dump_summary_t)); - if (summary) - { - if (esp_core_dump_get_summary(summary) == ESP_OK) - { - Serial.printf("Crash in task: %s\n", summary->exc_task); - } - } - free(summary); + case ESP_RST_POWERON: + case ESP_RST_PWR_GLITCH: + RINFO(TAG, "System restart after power-on or power glitch: %d", r); + // RTC memory does not survive power interruption. Initialize values. + rebootTime = 0; + crashTime = 0; + crashCount = 0; + break; + default: + RINFO(TAG, "System restart reason: %d", r); + break; } - // Beep on boot... - tone(BEEPER_PIN, 1300, 500); - led.on(); + // If there is a core dump image but no saved crash log, then set count to -1. + if ((crashCount == 0) && (esp_core_dump_image_check() == ESP_OK)) + crashCount = -1; load_all_config_settings(); @@ -196,14 +200,12 @@ void service_timer_loop() return; } -#ifdef NTP_CLIENT if (enableNTP && clockSet && lastRebootAt == 0) { lastRebootAt = time(NULL) - (current_millis / 1000); RINFO(TAG, "Current System time: %s", timeString()); RINFO(TAG, "System boot time: %s", timeString(lastRebootAt)); } -#endif // Check heap if (current_millis > next_heap_check) diff --git a/src/utilities.cpp b/src/utilities.cpp index 7c568d7..8c54965 100644 --- a/src/utilities.cpp +++ b/src/utilities.cpp @@ -47,11 +47,9 @@ uint64_t ARDUINO_ISR_ATTR millis64() return (uint64_t)(esp_timer_get_time() / 1000ULL); } -#ifdef NTP_CLIENT bool clockSet = false; bool enableNTP = false; uint64_t lastRebootAt = 0; -// int32_t savedDoorUpdateAt = 0; bool get_auto_timezone() { @@ -95,10 +93,10 @@ char *timeString(time_t reqTime, bool syslog) localtime_r(&tTime, &tmTime); if (syslog) { - // syslog compatibe + // syslog compatible strftime(tBuffer, sizeof(tBuffer), "%Y-%m-%dT%H:%M:%S.000%z", &tmTime); // %z returns e.g. "-400" or "+1000", we need it to be "-4:00" or "+10:00" - // thie format is REQUIRED by syslog + // this format is REQUIRED by syslog int i = strlen(tBuffer); if (tBuffer[i - 5] == '-' || tBuffer[i - 5] == '+' || tBuffer[i - 6] == '-' || tBuffer[i - 6] == '+') @@ -117,7 +115,6 @@ char *timeString(time_t reqTime, bool syslog) } return tBuffer; } -#endif char *make_rfc952(char *dest, const char *src, int size) { @@ -173,11 +170,9 @@ void load_all_config_settings() RINFO(TAG, " rebootSeconds: %d", userConfig->getRebootSeconds()); RINFO(TAG, " LEDidle: %d", userConfig->getLEDidle()); RINFO(TAG, " motionTriggers: %d", userConfig->getMotionTriggers()); -#ifdef NTP_CLIENT RINFO(TAG, " enableNTP: %s", userConfig->getEnableNTP() ? "true" : "false"); RINFO(TAG, " doorUpdateAt: %d", userConfig->getDoorUpdateAt()); RINFO(TAG, " timeZone: %s", userConfig->getTimeZone().c_str()); -#endif RINFO(TAG, " softAPmode: %s", userConfig->getSoftAPmode() ? "true" : "false"); RINFO(TAG, " syslogEn: %s", userConfig->getSyslogEn() ? "true" : "false"); RINFO(TAG, " syslogIP: %s", userConfig->getSyslogIP().c_str()); @@ -188,7 +183,6 @@ void load_all_config_settings() RINFO(TAG, " assistDuration: %d", userConfig->getAssistDuration()); RINFO(TAG, "RFC952 device hostname: %s", device_name_rfc952); -#ifdef NTP_CLIENT // Only enable NTP client if not in soft AP mode. enableNTP = !softAPmode && userConfig->getEnableNTP(); if (enableNTP) @@ -210,7 +204,6 @@ void load_all_config_settings() configTzTime("UTC0", NTP_SERVER); } } -#endif } void sync_and_restart() diff --git a/src/utilities.h b/src/utilities.h index b53d48e..c5562af 100644 --- a/src/utilities.h +++ b/src/utilities.h @@ -24,14 +24,12 @@ // #include "homekit_decl.h" // #include "ratgdo.h" -#ifdef NTP_CLIENT extern bool clockSet; extern uint64_t lastRebootAt; extern char *timeString(time_t reqTime = 0, bool syslog = false); extern bool enableNTP; extern bool get_auto_timezone(); #define NTP_SERVER "pool.ntp.org" -#endif #if defined(MMU_IRAM_HEAP) // IRAM heap is used only for allocating globals, to leave as much regular heap diff --git a/src/web.cpp b/src/web.cpp index 7cda901..00ce849 100644 --- a/src/web.cpp +++ b/src/web.cpp @@ -49,15 +49,6 @@ static const char *TAG = "ratgdo-http"; // This is used for CSS, JS and IMAGE file types. Set to 30 days !! #define CACHE_CONTROL (60 * 60 * 24 * 30) -#ifdef ENABLE_CRASH_LOG -#include "EspSaveCrash.h" -#ifdef LOG_MSG_BUFFER -EspSaveCrash saveCrash(1408, 1024, true, &crashCallback); -#else -EspSaveCrash saveCrash(1408, 1024, true); -#endif -#endif - // Forward declare the internal URI handling functions... void handle_reset(); void handle_status(); @@ -112,8 +103,6 @@ bool last_reported_assist_laser = false; uint32_t lastDoorUpdateAt = 0; GarageDoorCurrentState lastDoorState = (GarageDoorCurrentState)0xff; -// number of times the device has crashed -int crashCount = 0; static bool web_setup_done = false; // Implement our own firmware update so can enforce MD5 check. @@ -334,7 +323,8 @@ void handle_reset() void handle_reboot() { - RINFO(TAG, "... reboot requested"); + RINFO(TAG, "System boot time: %s", timeString(lastRebootAt)); + RINFO(TAG, "Reboot requested at: %s", timeString()); const char *resp = "Rebooting...\n"; server.client().setNoDelay(true); server.send(200, type_txt, resp); @@ -923,13 +913,7 @@ void handle_crashlog() RINFO(TAG, "Request to display crash log..."); WiFiClient client = server.client(); client.print(response200); - /* TODO show crashdump - saveCrash.print(client); - #ifdef LOG_MSG_BUFFER - if (crashCount > 0) - printSavedLog(client); - #endif - */ + ratgdoLogger->printCrashLog(client); client.stop(); } @@ -937,10 +921,7 @@ void handle_showlog() { WiFiClient client = server.client(); client.print(response200); -#ifdef LOG_MSG_BUFFER ratgdoLogger->printMessageLog(client); - // ratgdoLogger->saveMessageLog(); -#endif client.stop(); } @@ -948,9 +929,7 @@ void handle_showrebootlog() { WiFiClient client = server.client(); client.print(response200); -#ifdef LOG_MSG_BUFFER ratgdoLogger->printSavedLog(client); -#endif client.stop(); } @@ -971,6 +950,7 @@ void handle_crash_oom() delay(1000); for (int i = 0; i < 30; i++) { + RINFO(TAG, "malloc(1024)"); crashptr = malloc(1024); } } @@ -982,7 +962,7 @@ void handle_forcecrash() delay(1000); RINFO(TAG, "Result: %s", test_str); } -#endif +#endif // CRASH_DEBUG void SSEBroadcastState(const char *data, BroadcastType type) { diff --git a/src/web.h b/src/web.h index 6a0cbc9..6eb48fa 100644 --- a/src/web.h +++ b/src/web.h @@ -40,5 +40,3 @@ enum BroadcastType : uint8_t LOG_MESSAGE = 2, }; void SSEBroadcastState(const char *data, BroadcastType type = RATGDO_STATUS); - -extern "C" int crashCount; // pull in number of times crashed. diff --git a/src/www/logs.js b/src/www/logs.js index 1840d0e..8d655ef 100644 --- a/src/www/logs.js +++ b/src/www/logs.js @@ -84,7 +84,7 @@ function openTab(evt, tabName) { document.getElementById(tabName).style.display = "block"; evt.currentTarget.className += " active"; if (tabName === "crashTab") { - if (msgJson?.crashCount > 0) { + if (msgJson?.crashCount != 0) { document.getElementById("clearBtn").style.display = "inline-block"; } } else if (tabName === "statusTab") {