1
0
mirror of synced 2024-11-14 19:17:42 +01:00

impr: Improve uncaught exception error handling to provide actual stack trace

This commit is contained in:
WerWolv 2023-07-22 20:16:36 +02:00
parent 564ae6dd8c
commit 46ee3f0faa

View File

@ -24,7 +24,7 @@
namespace hex::crash { namespace hex::crash {
constexpr static auto CrashBackupFileName = "crash_backup.hexproj"; constexpr static auto CrashBackupFileName = "crash_backup.hexproj";
constexpr static auto Signals = {SIGSEGV, SIGILL, SIGABRT,SIGFPE}; constexpr static auto Signals = { SIGSEGV, SIGILL, SIGABRT, SIGFPE };
static std::terminate_handler originalHandler; static std::terminate_handler originalHandler;
@ -42,8 +42,8 @@ namespace hex::crash {
log::fatal(message); log::fatal(message);
nlohmann::json crashData{ nlohmann::json crashData{
{"logFile", wolv::util::toUTF8String(hex::log::impl::getFile().getPath())}, { "logFile", wolv::util::toUTF8String(hex::log::impl::getFile().getPath()) },
{"project", wolv::util::toUTF8String(ProjectFile::getPath())}, { "project", wolv::util::toUTF8String(ProjectFile::getPath()) },
}; };
for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Config)) { for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Config)) {
@ -79,7 +79,7 @@ namespace hex::crash {
// Custom signal handler to print various information and a stacktrace when the application crashes // Custom signal handler to print various information and a stacktrace when the application crashes
static void signalHandler(int signalNumber, const std::string &signalName) { static void signalHandler(int signalNumber, const std::string &signalName) {
// reset crash handlers so we can't have a recursion if this code crashes // Reset crash handlers, so we can't have a recursion if this code crashes
resetCrashHandlers(); resetCrashHandlers();
// Actually handle the crash // Actually handle the crash
@ -115,21 +115,20 @@ namespace hex::crash {
#undef HANDLE_SIGNAL #undef HANDLE_SIGNAL
} }
// reset uncaught C++ exception handler // Reset uncaught C++ exception handler
{ {
originalHandler = std::set_terminate([]{ originalHandler = std::set_terminate([]{
// reset crash handlers so we can't have a recursion if this code crashes // Reset crash handlers, so we can't have a recursion if this code crashes
resetCrashHandlers(); resetCrashHandlers();
handleCrash("Uncaught exception!", 0);
try { try {
std::rethrow_exception(std::current_exception()); std::rethrow_exception(std::current_exception());
} catch (std::exception &ex) { } catch (std::exception &ex) {
std::string exceptionStr = hex::format("{}()::what() -> {}", llvm::itaniumDemangle(typeid(ex).name(), nullptr, nullptr, nullptr), ex.what()); std::string exceptionStr = hex::format("{}()::what() -> {}", llvm::itaniumDemangle(typeid(ex).name(), nullptr, nullptr, nullptr), ex.what());
log::fatal("Program terminated with uncaught exception: {}", exceptionStr); log::fatal("Program terminated with uncaught exception: {}", exceptionStr);
// Actually handle the crash
handleCrash(hex::format("Uncaught exception: {}", exceptionStr), 0);
// Reset signal handlers prior to calling the original handler, because it may raise a signal // Reset signal handlers prior to calling the original handler, because it may raise a signal
for (auto signal : Signals) std::signal(signal, SIG_DFL); for (auto signal : Signals) std::signal(signal, SIG_DFL);