diff --git a/src/spice2x/avs/core.cpp b/src/spice2x/avs/core.cpp index 975893c..8dc9948 100644 --- a/src/spice2x/avs/core.cpp +++ b/src/spice2x/avs/core.cpp @@ -2003,8 +2003,9 @@ namespace avs { deferredlogs::defer_error_messages({ fmt::format( "log level is set to `{}` (either in avs-config.xml or using -loglevel)", log_level_as_str), - " if you are troubleshooting crashes or failures, it is recommended that you set ", - " AVS Log Level (-loglevel) option to `all`", + " this log file may have omitted important error messages from the game", + " if you are troubleshooting crashes or failures, it is recommended that you", + " set AVS Log Level (-loglevel) option to `all`", }); } diff --git a/src/spice2x/hooks/graphics/backends/d3d9/d3d9_backend.cpp b/src/spice2x/hooks/graphics/backends/d3d9/d3d9_backend.cpp index 0002afc..70b8c31 100644 --- a/src/spice2x/hooks/graphics/backends/d3d9/d3d9_backend.cpp +++ b/src/spice2x/hooks/graphics/backends/d3d9/d3d9_backend.cpp @@ -209,11 +209,13 @@ static void log_create_device_failure(HRESULT hresult) { deferredlogs::defer_error_messages({ fmt::format("D3D9 CreateDevice/CreateDeviceEx failed with {:#x}!", (UINT)hresult), " this is a common graphics / monitor issue", - " double check any graphics options you configured in spicecfg", - " double check that your monitor supports the resolution + refresh rate that the game needs", - " enable GPU-side resolution scaling in your GPU options as needed", - " if you have three or more monitors, try unplugging them down to one or two, or enable -graphics-force-single-adapter option", - " failing all that, see if enabling windowed mode helps" + " * double check any graphics options you configured in spicecfg", + " * double check that your monitor supports the resolution + refresh rate", + " combination that the game requires", + " * enable GPU-side resolution scaling in your GPU options as needed", + " * if you have three or more monitors, try unplugging them down to one or two,", + " or enable -graphics-force-single-adapter option", + " * failing all that, see if enabling windowed mode helps" }); } diff --git a/src/spice2x/launcher/signal.cpp b/src/spice2x/launcher/signal.cpp index 5fe0046..a8facf1 100644 --- a/src/spice2x/launcher/signal.cpp +++ b/src/spice2x/launcher/signal.cpp @@ -98,31 +98,34 @@ static LONG WINAPI TopLevelExceptionFilter(struct _EXCEPTION_POINTERS *Exception // print signal log_warning("signal", "exception raised: {}", exception_code(ExceptionRecord)); - std::string err; switch (ExceptionRecord->ExceptionCode) { case EXCEPTION_ILLEGAL_INSTRUCTION: - err = "Illegal instruction: either your CPU is too old (e.g., does not support " - "SSE4.2 or AVX2 but perhaps the game requires it); or, a bad patch was applied."; + deferredlogs::defer_error_messages({ + "Illegal instruction exception:", + " either your CPU is too old (e.g., does not support SSE4.2 or AVX2 ", + " but perhaps the game requires it); or, a bad patch was applied." + }); break; default: break; } - if (!err.empty()) { - log_warning( - "signal", - "likely cause for your error based on the exception code:\n {}", - err.c_str()); - } // check ACIO init failures if (acio::IO_INIT_IN_PROGRESS) { deferredlogs::defer_error_messages({ - "exception raised during ACIO init, this usually happens when a third party application interferes with hooks", + "exception raised during ACIO init, this usually happens when ", + " a third party application interferes with hooks", " please check for the following, disable them, and try launching the game again:", - " RivaTuner Statistics Server (RTSS), MSI Afterburner, kernel mode anti-cheat" + " * RivaTuner Statistics Server (RTSS)", + " * MSI Afterburner", + " * kernel mode anti-cheat" }); } + // dump deferred logs BEFORE stack trace since some errors cause stack trace logic to hang + // (e.g., ACIO init hang due to RTSS) + deferredlogs::dump_to_logger(); + // walk the exception chain struct _EXCEPTION_RECORD *record_cause = ExceptionRecord->ExceptionRecord; while (record_cause != nullptr) { @@ -137,8 +140,6 @@ static LONG WINAPI TopLevelExceptionFilter(struct _EXCEPTION_POINTERS *Exception log_warning("signal", "failed to print callstack"); } - deferredlogs::dump_to_logger(); - if (MiniDumpWriteDump_local != nullptr) { HANDLE minidump_file = CreateFileA( "minidump.dmp", diff --git a/src/spice2x/util/deferlog.cpp b/src/spice2x/util/deferlog.cpp index 4c4f0bc..c5c8863 100644 --- a/src/spice2x/util/deferlog.cpp +++ b/src/spice2x/util/deferlog.cpp @@ -1,4 +1,5 @@ #include +#include #include "deferlog.h" #include "util/logging.h" @@ -9,14 +10,21 @@ namespace deferredlogs { "audio initialization error was previously detected during boot!", " (W:SuperstepSound: Audio device is not available!!!)", " this crash is most likely related to audio init failure", - " see if the default audio device changed, fix your audio configuration (e.g., sample rate)", - " double check your spice audio options/patches, and try again" + " * check if the default audio device has changed", + " * fix your audio device settings (e.g., sample rate)", + " * double check your spice audio options and patches" }; std::mutex deferred_errors_mutex; std::vector> deferred_errors; + std::atomic too_late; void defer_error_messages(std::initializer_list messages) { + // don't try to acquire lock if already dumping to logger + if (too_late) { + return; + } + std::lock_guard lock(deferred_errors_mutex); deferred_errors.emplace_back(messages); } @@ -24,24 +32,25 @@ namespace deferredlogs { void dump_to_logger() { static std::once_flag printed; std::call_once(printed, []() { - std::lock_guard lock(deferred_errors_mutex); - if (!deferred_errors.empty()) { - log_warning("deferred_error", - "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); - log_warning("deferred_error", ""); + too_late = true; + if (deferred_errors.empty()) { + return; } + log_warning("troubleshooter", "/------------------------ spice2x auto-troubleshooter ------------------------\\"); + log_warning("troubleshooter", ""); + for (auto messages : deferred_errors) { for (auto message : messages) { - log_warning("deferred_error", "{}", message); + log_warning("troubleshooter", " {}", message); } - log_warning("deferred_error", ""); + log_warning("troubleshooter", ""); } - if (!deferred_errors.empty()) { - log_warning("deferred_error", - "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); - } + log_warning("troubleshooter", " Still unsure? Check the FAQ:"); + log_warning("troubleshooter", " https://github.com/spice2x/spice2x.github.io/wiki/Known-issues"); + log_warning("troubleshooter", ""); + log_warning("troubleshooter", "\\------------------------ spice2x auto-troubleshooter -----------------------/"); }); } }