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...
This commit is contained in:
ITotalJustice
2025-06-05 02:56:13 +01:00
parent be831eb04a
commit 8fb34d42dc

View File

@@ -1857,18 +1857,23 @@ App::~App() {
log_write("starting to exit\n"); log_write("starting to exit\n");
TimeStamp ts; TimeStamp ts;
i18n::exit(); appletUnhook(&m_appletHookCookie);
curl::Exit();
// 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 // 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. // nvg is still active as some widgets may need to free images.
m_widgets.clear(); m_widgets.clear();
nvgDeleteImage(vg, m_default_image); nvgDeleteImage(vg, m_default_image);
appletUnhook(&m_appletHookCookie); i18n::exit();
curl::Exit();
ini_puts("config", "theme", m_theme.meta.ini_path, CONFIG_PATH); ini_puts("config", "theme", m_theme.meta.ini_path, CONFIG_PATH);
CloseTheme(); CloseTheme();
// Free any loaded sound from memory // Free any loaded sound from memory
@@ -1881,7 +1886,6 @@ App::~App() {
// De-initialize our player // De-initialize our player
plsrPlayerExit(); plsrPlayerExit();
this->destroyFramebufferResources();
nvgDeleteDk(this->vg); nvgDeleteDk(this->vg);
this->renderer.reset(); this->renderer.reset();