From ec0f52b7c3e3efc40dfbec472a57e2465ac2568d Mon Sep 17 00:00:00 2001 From: goat Date: Mon, 20 Mar 2023 20:15:24 +0100 Subject: [PATCH] chore: don't report crashes when shutting down the game, if no devplugin is loaded --- .../Internal/DalamudConfiguration.cs | 5 +++++ Dalamud/Dalamud.cs | 11 ++++++++++ .../Interface/Internal/DalamudInterface.cs | 6 ++++++ DalamudCrashHandler/DalamudCrashHandler.cpp | 20 ++++++++++++++++++- 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/Dalamud/Configuration/Internal/DalamudConfiguration.cs b/Dalamud/Configuration/Internal/DalamudConfiguration.cs index d2f8c4aa1..f6cf88d90 100644 --- a/Dalamud/Configuration/Internal/DalamudConfiguration.cs +++ b/Dalamud/Configuration/Internal/DalamudConfiguration.cs @@ -244,6 +244,11 @@ internal sealed class DalamudConfiguration : IServiceType /// public int? PluginWaitBeforeFree { get; set; } + /// + /// Gets or sets a value indicating whether or not crashes during shutdown should be reported. + /// + public bool ReportShutdownCrashes { get; set; } + /// /// Gets or sets a list of saved styles. /// diff --git a/Dalamud/Dalamud.cs b/Dalamud/Dalamud.cs index e78776955..73914d2a7 100644 --- a/Dalamud/Dalamud.cs +++ b/Dalamud/Dalamud.cs @@ -11,6 +11,7 @@ using Dalamud.Game.Gui.Internal; using Dalamud.Interface.Internal; using Dalamud.Plugin.Internal; using Dalamud.Utility; +using PInvoke; using Serilog; #if DEBUG @@ -103,6 +104,16 @@ internal sealed class Dalamud : IServiceType public void Unload() { Log.Information("Trigger unload"); + + var reportCrashesSetting = Service.GetNullable()?.ReportShutdownCrashes ?? true; + var pmHasDevPlugins = Service.GetNullable()?.InstalledPlugins.Any(x => x.IsDev) ?? false; + if (!reportCrashesSetting && !pmHasDevPlugins) + { + // Leaking on purpose for now + var attribs = Kernel32.SECURITY_ATTRIBUTES.Create(); + Kernel32.CreateMutex(attribs, false, "DALAMUD_CRASHES_NO_MORE"); + } + this.unloadSignal.Set(); } diff --git a/Dalamud/Interface/Internal/DalamudInterface.cs b/Dalamud/Interface/Internal/DalamudInterface.cs index 3da633c86..45b31e7a8 100644 --- a/Dalamud/Interface/Internal/DalamudInterface.cs +++ b/Dalamud/Interface/Internal/DalamudInterface.cs @@ -759,6 +759,12 @@ internal class DalamudInterface : IDisposable, IServiceType } } + if (ImGui.MenuItem("Report crashes at shutdown", null, configuration.ReportShutdownCrashes)) + { + configuration.ReportShutdownCrashes = !configuration.ReportShutdownCrashes; + configuration.QueueSave(); + } + ImGui.Separator(); if (ImGui.MenuItem("Open Dalamud branch switcher")) diff --git a/DalamudCrashHandler/DalamudCrashHandler.cpp b/DalamudCrashHandler/DalamudCrashHandler.cpp index f31715c5e..18f7f0791 100644 --- a/DalamudCrashHandler/DalamudCrashHandler.cpp +++ b/DalamudCrashHandler/DalamudCrashHandler.cpp @@ -739,6 +739,11 @@ int main() { std::cout << "Crash triggered" << std::endl; + auto shutup_mutex = CreateMutex(NULL, false, L"DALAMUD_CRASHES_NO_MORE"); + bool shutup = false; + if (shutup_mutex == NULL && GetLastError() == ERROR_ALREADY_EXISTS) + shutup = true; + /* Hard won wisdom: changing symbol path with SymSetSearchPath() after modules have been loaded (invadeProcess=TRUE in SymInitialize() or SymRefreshModuleList()) @@ -795,7 +800,11 @@ int main() { std::wstring dumpError; if (dumpPath.empty()) { std::cout << "Skipping dump path, as log directory has not been specified" << std::endl; - } else { + } else if (shutup) { + std::cout << "Skipping dump, was shutdown" << std::endl; + } + else + { MINIDUMP_EXCEPTION_INFORMATION mdmp_info{}; mdmp_info.ThreadId = GetThreadId(exinfo.hThreadHandle); mdmp_info.ExceptionPointers = exinfo.pExceptionPointers; @@ -821,6 +830,10 @@ int main() { std::wostringstream log; log << std::format(L"Unhandled native exception occurred at {}", to_address_string(exinfo.ContextRecord.Rip, false)) << std::endl; log << std::format(L"Code: {:X}", exinfo.ExceptionRecord.ExceptionCode) << std::endl; + + if (shutup) + log << L"======= Crash handler was globally muted(shutdown?) =======" << std::endl; + if (dumpPath.empty()) log << L"Dump skipped" << std::endl; else if (dumpError.empty()) @@ -971,6 +984,11 @@ int main() { submitThread = {}; } + if (shutup) { + TerminateProcess(g_hProcess, exinfo.ExceptionRecord.ExceptionCode); + return 0; + } + int nButtonPressed = 0, nRadioButton = 0; if (FAILED(TaskDialogIndirect(&config, &nButtonPressed, &nRadioButton, nullptr))) { ResumeThread(exinfo.hThreadHandle);