Add some more protection

This commit is contained in:
Brendan O'Leary 2025-12-18 21:12:09 -05:00
parent 71fc35845b
commit 18527c6bc0
2 changed files with 63 additions and 13 deletions

View File

@ -107,19 +107,30 @@ void CrossPointWebServer::begin() {
void CrossPointWebServer::stop() {
if (!running || !server) {
Serial.printf("[%lu] [WEB] stop() called but already stopped (running=%d, server=%p)\n", millis(), running, server);
return;
}
Serial.printf("[%lu] [WEB] STOP INITIATED - setting running=false first\n", millis());
running = false; // Set this FIRST to prevent handleClient from using server
Serial.printf("[%lu] [WEB] [MEM] Free heap before stop: %d bytes\n", millis(), ESP.getFreeHeap());
// Add delay to allow any in-flight handleClient() calls to complete
delay(100);
Serial.printf("[%lu] [WEB] Waited 100ms for handleClient to finish\n", millis());
server->stop();
Serial.printf("[%lu] [WEB] [MEM] Free heap after server->stop(): %d bytes\n", millis(), ESP.getFreeHeap());
// Add another delay before deletion to ensure server->stop() completes
delay(50);
Serial.printf("[%lu] [WEB] Waited 50ms before deleting server\n", millis());
delete server;
server = nullptr;
running = false;
Serial.printf("[%lu] [WEB] Web server stopped\n", millis());
Serial.printf("[%lu] [WEB] Web server stopped and deleted\n", millis());
Serial.printf("[%lu] [WEB] [MEM] Free heap after delete server: %d bytes\n", millis(), ESP.getFreeHeap());
// Note: Static upload variables (uploadFileName, uploadPath, uploadError) are declared
@ -129,14 +140,25 @@ void CrossPointWebServer::stop() {
void CrossPointWebServer::handleClient() {
static unsigned long lastDebugPrint = 0;
if (running && server) {
// Print debug every 10 seconds to confirm handleClient is being called
if (millis() - lastDebugPrint > 10000) {
Serial.printf("[%lu] [WEB] handleClient active, server running on port %d\n", millis(), port);
lastDebugPrint = millis();
}
server->handleClient();
// Check running flag FIRST before accessing server
if (!running) {
return;
}
// Double-check server pointer is valid
if (!server) {
Serial.printf("[%lu] [WEB] WARNING: handleClient called with null server!\n", millis());
return;
}
// Print debug every 10 seconds to confirm handleClient is being called
if (millis() - lastDebugPrint > 10000) {
Serial.printf("[%lu] [WEB] handleClient active, server running on port %d\n", millis(), port);
lastDebugPrint = millis();
}
server->handleClient();
}
void CrossPointWebServer::handleRoot() {
@ -453,6 +475,12 @@ void CrossPointWebServer::handleUpload() {
static unsigned long uploadStartTime = 0;
static size_t lastLoggedSize = 0;
// Safety check: ensure server is still valid
if (!running || !server) {
Serial.printf("[%lu] [WEB] [UPLOAD] ERROR: handleUpload called but server not running!\n", millis());
return;
}
HTTPUpload& upload = server->upload();
if (upload.status == UPLOAD_FILE_START) {

View File

@ -48,37 +48,59 @@ void WifiScreen::onEnter() {
}
void WifiScreen::onExit() {
Serial.printf("[%lu] [WIFI] ========== onExit START ==========\n", millis());
Serial.printf("[%lu] [WIFI] [MEM] Free heap at onExit start: %d bytes\n", millis(), ESP.getFreeHeap());
// Stop any ongoing WiFi scan
Serial.printf("[%lu] [WIFI] Deleting WiFi scan...\n", millis());
WiFi.scanDelete();
Serial.printf("[%lu] [WIFI] [MEM] Free heap after scanDelete: %d bytes\n", millis(), ESP.getFreeHeap());
// Stop the web server to free memory
// CRITICAL: Stop the web server FIRST to prevent new packets from being queued
Serial.printf("[%lu] [WIFI] Stopping web server...\n", millis());
crossPointWebServer.stop();
Serial.printf("[%lu] [WIFI] [MEM] Free heap after webserver stop: %d bytes\n", millis(), ESP.getFreeHeap());
Serial.printf("[%lu] [WIFI] Web server stopped successfully\n", millis());
Serial.printf("[%lu] [WIFI] [MEM] Free heap after webserver stop: %d bytes\n", millis());
// Disconnect WiFi to free memory
WiFi.disconnect(true);
// CRITICAL: Wait for LWIP stack to flush any pending packets
// The crash occurs because WiFi.disconnect() tears down the interface while
// packets are still queued in the LWIP stack (ethernet.c, etharp.c, wlanif.c)
Serial.printf("[%lu] [WIFI] Waiting 500ms for network stack to flush pending packets...\n", millis());
delay(500);
// Disconnect WiFi gracefully - use disconnect(false) first to send disconnect frame
Serial.printf("[%lu] [WIFI] Disconnecting WiFi (graceful)...\n", millis());
WiFi.disconnect(false); // false = don't erase credentials, send disconnect frame
delay(100); // Allow disconnect frame to be sent
Serial.printf("[%lu] [WIFI] Setting WiFi mode OFF...\n", millis());
WiFi.mode(WIFI_OFF);
delay(100); // Allow WiFi hardware to fully power down
Serial.printf("[%lu] [WIFI] [MEM] Free heap after WiFi disconnect: %d bytes\n", millis(), ESP.getFreeHeap());
// Delete the display task
Serial.printf("[%lu] [WIFI] Deleting display task...\n", millis());
if (displayTaskHandle) {
vTaskDelete(displayTaskHandle);
displayTaskHandle = nullptr;
Serial.printf("[%lu] [WIFI] Display task deleted\n", millis());
}
// Small delay to ensure task is fully deleted before cleaning up mutex
Serial.printf("[%lu] [WIFI] Waiting for task cleanup...\n", millis());
vTaskDelay(10 / portTICK_PERIOD_MS);
// Now safe to delete the mutex
Serial.printf("[%lu] [WIFI] Deleting mutex...\n", millis());
if (renderingMutex) {
vSemaphoreDelete(renderingMutex);
renderingMutex = nullptr;
Serial.printf("[%lu] [WIFI] Mutex deleted\n", millis());
}
Serial.printf("[%lu] [WIFI] [MEM] Free heap at onExit end: %d bytes\n", millis(), ESP.getFreeHeap());
Serial.printf("[%lu] [WIFI] ========== onExit COMPLETE ==========\n", millis());
}
void WifiScreen::startWifiScan() {