mirror of
https://github.com/HarbourMasters/SpaghettiKart
synced 2026-06-30 20:11:40 -04:00
Fix crash when bailing out of first-run setup before the game inits (#707)
InitModsSystem() runs before the game world is set up. Its bail-out paths (no O2R + user declines generation, missing mods.toml, cyclic/outdated mod deps, and GenAssetFile's no-ROM / unsupported-ROM cases) call exit(), which runs the global `static World sWorldInstance` destructor -> World::CleanWorld() -> dereferences Sky::Instance and other singletons that are still null this early, segfaulting. The most visible case: declining the first-run "Generate one now?" prompt pops a crash report instead of quitting cleanly. Use _Exit() on these pre-initialization bail-outs so no static destructors run. Co-authored-by: quarrel07 <paeans-toggle-2e@icloud.com> Co-authored-by: coco875 <59367621+coco875@users.noreply.github.com>
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include "port/Engine.h"
|
||||
#include "semver.hpp"
|
||||
#include "utils/StringHelper.h"
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
@@ -51,14 +52,19 @@ void UnloadMods() {
|
||||
Mods.clear();
|
||||
}
|
||||
|
||||
// These bail-outs all run during InitModsSystem(), i.e. before the game world is set up.
|
||||
// Use _Exit instead of exit so the global `static World sWorldInstance` destructor does not
|
||||
// run: its CleanWorld() dereferences Sky::Instance and other singletons that are still null
|
||||
// at this point, which segfaults — a crash report on what should be a clean quit (e.g. when
|
||||
// the user declines the first-run "Generate one now?" prompt).
|
||||
void GenerateAssetsMods() {
|
||||
if (GameEngine::ShowYesNoBox("No O2R Files", "No O2R files found. Generate one now?") == IDYES) {
|
||||
if (!GameEngine::GenAssetFile()) {
|
||||
GameEngine::ShowMessage("Error", "An error occured, no O2R file was generated.\n\nExiting...");
|
||||
exit(1);
|
||||
_Exit(1);
|
||||
}
|
||||
} else {
|
||||
exit(1);
|
||||
_Exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,7 +247,7 @@ void FindAndLoadMods() {
|
||||
" is missing a mods.toml file. The Mod are likely incompatible.\n\n"
|
||||
"Do you want to continue loading the mods?";
|
||||
if (GameEngine::ShowYesNoBox("Missing mods.toml", msg.c_str()) == IDNO) {
|
||||
exit(1);
|
||||
_Exit(1);
|
||||
}
|
||||
metadata.name = std::filesystem::path(path).stem().string();
|
||||
semver::parse("0.0.0", metadata.version);
|
||||
@@ -260,7 +266,7 @@ void DetectCyclicDependencies() {
|
||||
}
|
||||
msg += "\nPlease resolve these cyclic dependencies before continuing.\n";
|
||||
GameEngine::ShowMessage("Cyclic Dependency Issues", msg.c_str());
|
||||
exit(1);
|
||||
_Exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,7 +287,7 @@ void DetectOutdatedDependencies() {
|
||||
if (exitDueToErrors) {
|
||||
allDepIssues += "\nPlease resolve these dependency issues before continuing.\n";
|
||||
GameEngine::ShowMessage("Dependency Issues", allDepIssues.c_str());
|
||||
exit(1);
|
||||
_Exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-2
@@ -1,5 +1,6 @@
|
||||
#include "Engine.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include "ship/utils/StringHelper.h"
|
||||
#include "GameExtractor.h"
|
||||
#include "mods/ModManager.h"
|
||||
@@ -269,14 +270,16 @@ bool GameEngine::GenAssetFile() {
|
||||
|
||||
if (!extractor->SelectGameFromUI()) {
|
||||
ShowMessage("Error", "No ROM selected.\n\nExiting...");
|
||||
exit(1);
|
||||
// _Exit, not exit: this runs before the game world is initialized, so running the
|
||||
// global World destructor (CleanWorld) would dereference still-null singletons and crash.
|
||||
_Exit(1);
|
||||
}
|
||||
|
||||
auto game = extractor->ValidateChecksum();
|
||||
if (!game.has_value()) {
|
||||
ShowMessage("Unsupported ROM",
|
||||
"The provided ROM is not supported.\n\nCheck the readme for a list of supported versions.");
|
||||
exit(1);
|
||||
_Exit(1);
|
||||
}
|
||||
|
||||
ShowMessage(("Found " + game.value()).c_str(),
|
||||
|
||||
Reference in New Issue
Block a user