mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-27 23:37:05 -05:00
fix: Make sure crash handling operations happen in the right order
This commit is contained in:
@@ -48,12 +48,13 @@ namespace hex::crash {
|
||||
using CrashCallback = void (*) (const std::string&);
|
||||
static CrashCallback crashCallback = sendNativeMessage;
|
||||
|
||||
static std::fs::path s_crashBackupPath;
|
||||
static void saveCrashFile(const std::string& message) {
|
||||
log::fatal("{}", message);
|
||||
|
||||
const nlohmann::json crashData {
|
||||
{ "logFile", wolv::io::fs::toNormalizedPathString(hex::log::impl::getFile().getPath()) },
|
||||
{ "project", wolv::io::fs::toNormalizedPathString(ProjectFile::getPath()) },
|
||||
{ "project", wolv::io::fs::toNormalizedPathString(s_crashBackupPath) },
|
||||
};
|
||||
|
||||
for (const auto &path : paths::Config.write()) {
|
||||
@@ -81,11 +82,27 @@ namespace hex::crash {
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" [[noreturn]] void triggerSafeShutdown(int signalNumber = 0) {
|
||||
static void callCrashHandlers(const std::string &msg) {
|
||||
// Call the crash callback
|
||||
crashCallback(msg);
|
||||
|
||||
// Print the stacktrace to the console or log file
|
||||
printStackTrace();
|
||||
|
||||
// Flush all streams
|
||||
std::fflush(stdout);
|
||||
std::fflush(stderr);
|
||||
|
||||
#if defined(IMGUI_TEST_ENGINE)
|
||||
ImGuiTestEngine_CrashHandler();
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" [[noreturn]] void triggerSafeShutdown(std::string crashMessage, int signalNumber = 0) {
|
||||
if (!TaskManager::isMainThread()) {
|
||||
log::error("Terminating from non-main thread, scheduling termination on main thread");
|
||||
TaskManager::doLater([signalNumber] {
|
||||
triggerSafeShutdown(signalNumber);
|
||||
TaskManager::doLater([=] {
|
||||
triggerSafeShutdown(crashMessage, signalNumber);
|
||||
});
|
||||
|
||||
// Terminate this thread
|
||||
@@ -102,6 +119,7 @@ namespace hex::crash {
|
||||
|
||||
// Trigger an event so that plugins can handle crashes
|
||||
EventAbnormalTermination::post(signalNumber);
|
||||
callCrashHandlers(crashMessage);
|
||||
|
||||
// Run exit tasks
|
||||
init::runExitTasks();
|
||||
@@ -134,22 +152,6 @@ namespace hex::crash {
|
||||
#endif
|
||||
}
|
||||
|
||||
void handleCrash(const std::string &msg) {
|
||||
// Call the crash callback
|
||||
crashCallback(msg);
|
||||
|
||||
// Print the stacktrace to the console or log file
|
||||
printStackTrace();
|
||||
|
||||
// Flush all streams
|
||||
std::fflush(stdout);
|
||||
std::fflush(stderr);
|
||||
|
||||
#if defined(IMGUI_TEST_ENGINE)
|
||||
ImGuiTestEngine_CrashHandler();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Custom signal handler to print various information and a stacktrace when the application crashes
|
||||
static void signalHandler(int signalNumber, const std::string &signalName) {
|
||||
#if !defined (DEBUG)
|
||||
@@ -159,18 +161,12 @@ namespace hex::crash {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Reset crash handlers, so we can't have a recursion if this code crashes
|
||||
resetCrashHandlers();
|
||||
|
||||
// Actually handle the crash
|
||||
handleCrash(fmt::format("Received signal '{}' ({})", signalName, signalNumber));
|
||||
|
||||
// Detect if the crash was due to an uncaught exception
|
||||
if (std::uncaught_exceptions() > 0) {
|
||||
log::fatal("Uncaught exception thrown!");
|
||||
}
|
||||
|
||||
triggerSafeShutdown(signalNumber);
|
||||
triggerSafeShutdown(fmt::format("Received signal '{}' ({})", signalName, signalNumber), signalNumber);
|
||||
}
|
||||
|
||||
static void uncaughtExceptionHandler() {
|
||||
@@ -184,12 +180,8 @@ namespace hex::crash {
|
||||
else
|
||||
log::fatal("Program terminated due to unknown reason!");
|
||||
} catch (std::exception &ex) {
|
||||
std::string exceptionStr = fmt::format("{}()::what() -> {}", trace::demangle(typeid(ex).name()), ex.what());
|
||||
|
||||
handleCrash(exceptionStr);
|
||||
log::fatal("Program terminated with uncaught exception: {}", exceptionStr);
|
||||
|
||||
triggerSafeShutdown();
|
||||
const auto exceptionStr = fmt::format("Program terminated with uncaught exception: {}()::what() -> {}", trace::demangle(typeid(ex).name()), ex.what());
|
||||
triggerSafeShutdown(exceptionStr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,8 +247,11 @@ namespace hex::crash {
|
||||
// Create crash backup if any providers are open
|
||||
if (ImHexApi::Provider::isValid()) {
|
||||
for (const auto &path : paths::Config.write()) {
|
||||
if (ProjectFile::store(path / CrashBackupFileName, false))
|
||||
if (ProjectFile::store(path / CrashBackupFileName, false)) {
|
||||
s_crashBackupPath = path / CrashBackupFileName;
|
||||
log::fatal("Saved crash backup to '{}'", wolv::util::toUTF8String(s_crashBackupPath));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user