ElfApp error handling improved

This commit is contained in:
Ken Van Hoeylandt 2025-08-23 21:33:32 +02:00
parent 2b7aa545c9
commit e250c7ea3f

View File

@ -12,6 +12,7 @@
#include <string> #include <string>
#include <utility> #include <utility>
#include <Tactility/app/alertdialog/AlertDialog.h>
namespace tt::app { namespace tt::app {
@ -39,10 +40,18 @@ class ElfApp : public App {
const std::string filePath; const std::string filePath;
std::unique_ptr<uint8_t[]> elfFileData; std::unique_ptr<uint8_t[]> elfFileData;
esp_elf_t elf; esp_elf_t elf {
.psegment = nullptr,
.svaddr = 0,
.ptext = nullptr,
.pdata = nullptr,
.sec = { },
.entry = nullptr
};
bool shouldCleanupElf = false; // Whether we have to clean up the above "elf" object bool shouldCleanupElf = false; // Whether we have to clean up the above "elf" object
std::unique_ptr<ElfManifest> manifest; std::unique_ptr<ElfManifest> manifest;
void* data = nullptr; void* data = nullptr;
std::string lastError = "";
bool startElf() { bool startElf() {
TT_LOG_I(TAG, "Starting ELF %s", filePath.c_str()); TT_LOG_I(TAG, "Starting ELF %s", filePath.c_str());
@ -58,14 +67,17 @@ class ElfApp : public App {
} }
if (esp_elf_init(&elf) != ESP_OK) { if (esp_elf_init(&elf) != ESP_OK) {
TT_LOG_E(TAG, "Failed to initialize"); lastError = "Failed to initialize";
TT_LOG_E(TAG, "%s", lastError.c_str());
elfFileData = nullptr; elfFileData = nullptr;
return false; return false;
} }
if (esp_elf_relocate(&elf, elfFileData.get()) != ESP_OK) { auto relocate_result = esp_elf_relocate(&elf, elfFileData.get());
TT_LOG_E(TAG, "Failed to load executable"); if (relocate_result != 0) {
esp_elf_deinit(&elf); // Note: the result code mapes to values from cstdlib's errno.h
lastError = std::format("Failed to load executable (error code {})", -relocate_result);
TT_LOG_E(TAG, "%s", lastError.c_str());
elfFileData = nullptr; elfFileData = nullptr;
return false; return false;
} }
@ -74,7 +86,8 @@ class ElfApp : public App {
char* argv[] = {}; char* argv[] = {};
if (esp_elf_request(&elf, 0, argc, argv) != ESP_OK) { if (esp_elf_request(&elf, 0, argc, argv) != ESP_OK) {
TT_LOG_W(TAG, "Executable returned error code"); lastError = "Executable returned error code";
TT_LOG_E(TAG, "%s", lastError.c_str());
esp_elf_deinit(&elf); esp_elf_deinit(&elf);
elfFileData = nullptr; elfFileData = nullptr;
return false; return false;
@ -106,9 +119,20 @@ public:
auto lock = elfManifestLock->asScopedLock(); auto lock = elfManifestLock->asScopedLock();
lock.lock(); lock.lock();
auto initial_count = elfManifestSetCount; elfManifestSetCount = 0;
if (startElf()) { if (!startElf()) {
if (elfManifestSetCount > initial_count) { service::loader::stopApp();
auto message = lastError.empty() ? "Application failed to start." : std::format("Application failed to start: {}", lastError);
alertdialog::start("Error", message);
return;
}
if (elfManifestSetCount == 0) {
service::loader::stopApp();
alertdialog::start("Error", "Application failed to start: application failed to register itself");
return;
}
manifest = std::make_unique<ElfManifest>(elfManifest); manifest = std::make_unique<ElfManifest>(elfManifest);
lock.unlock(); lock.unlock();
@ -120,10 +144,6 @@ public:
manifest->onCreate(&appContext, data); manifest->onCreate(&appContext, data);
} }
} }
} else {
service::loader::stopApp();
}
}
void onDestroy(AppContext& appContext) override { void onDestroy(AppContext& appContext) override {
TT_LOG_I(TAG, "Cleaning up app"); TT_LOG_I(TAG, "Cleaning up app");