From 8fb34d42dcae6662d59edb2107f2b60397838011 Mon Sep 17 00:00:00 2001 From: ITotalJustice <47043333+ITotalJustice@users.noreply.github.com> Date: Thu, 5 Jun 2025 02:56:13 +0100 Subject: [PATCH] fix very rare crash when closing sphaira from the appstore when saves/games menu has also been opened. i've been trying to track down this bug for a while. i still don't understand why it happens, however i have managed to reproduce it an narrow down the crash, and thus fix it. the bug was caused calling nvgDeleteImage() inside ~LazyImage() on image 43. this would only trigger once games/saves menu had been opened at least once also. i can only assume that the image fd was still refrenced in deko3d when drawing, as it would only ever crash on the visible images. destroying fb resources before the calls to nvg delete seems to fix the issue. maybe the explicit call to waitIdle is what fixes it? or clearing the cmd buf? who knows... --- sphaira/source/app.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/sphaira/source/app.cpp b/sphaira/source/app.cpp index f8d27b8..53a1b39 100644 --- a/sphaira/source/app.cpp +++ b/sphaira/source/app.cpp @@ -1857,18 +1857,23 @@ App::~App() { log_write("starting to exit\n"); TimeStamp ts; - i18n::exit(); - curl::Exit(); + appletUnhook(&m_appletHookCookie); + + // destroy this first as it seems to prevent a crash when exiting the appstore + // when an image that was being drawn is displayed + // replicate: saves -> homebrew -> misc -> appstore -> sphaira -> changelog -> exit + // it will crash when deleting image 43. + this->destroyFramebufferResources(); // this has to be called before any cleanup to ensure the lifetime of // nvg is still active as some widgets may need to free images. m_widgets.clear(); nvgDeleteImage(vg, m_default_image); - appletUnhook(&m_appletHookCookie); + i18n::exit(); + curl::Exit(); ini_puts("config", "theme", m_theme.meta.ini_path, CONFIG_PATH); - CloseTheme(); // Free any loaded sound from memory @@ -1881,7 +1886,6 @@ App::~App() { // De-initialize our player plsrPlayerExit(); - this->destroyFramebufferResources(); nvgDeleteDk(this->vg); this->renderer.reset();