From 5777745ab3cc0a52ee1c7f799aae19c312513095 Mon Sep 17 00:00:00 2001 From: srkizer Date: Thu, 7 Dec 2023 14:06:39 +0900 Subject: [PATCH] Add injector option to not apply any exception handlers (#1541) * Add injector option to not apply any exception handlers * Log as warning if NoExceptionHandlers is set --- Dalamud.Boot/DalamudStartInfo.cpp | 1 + Dalamud.Boot/DalamudStartInfo.h | 1 + Dalamud.Boot/dllmain.cpp | 4 +++- Dalamud.Common/DalamudStartInfo.cs | 37 ++++-------------------------- Dalamud.Injector/EntryPoint.cs | 6 +++-- Dalamud/EntryPoint.cs | 6 +++-- 6 files changed, 18 insertions(+), 37 deletions(-) diff --git a/Dalamud.Boot/DalamudStartInfo.cpp b/Dalamud.Boot/DalamudStartInfo.cpp index 15faf82ad..e2fed1beb 100644 --- a/Dalamud.Boot/DalamudStartInfo.cpp +++ b/Dalamud.Boot/DalamudStartInfo.cpp @@ -103,6 +103,7 @@ void from_json(const nlohmann::json& json, DalamudStartInfo& config) { } config.CrashHandlerShow = json.value("CrashHandlerShow", config.CrashHandlerShow); + config.NoExceptionHandlers = json.value("NoExceptionHandlers", config.NoExceptionHandlers); } void DalamudStartInfo::from_envvars() { diff --git a/Dalamud.Boot/DalamudStartInfo.h b/Dalamud.Boot/DalamudStartInfo.h index 66109abf7..73a1a0d34 100644 --- a/Dalamud.Boot/DalamudStartInfo.h +++ b/Dalamud.Boot/DalamudStartInfo.h @@ -49,6 +49,7 @@ struct DalamudStartInfo { std::set BootUnhookDlls{}; bool CrashHandlerShow = false; + bool NoExceptionHandlers = false; friend void from_json(const nlohmann::json&, DalamudStartInfo&); void from_envvars(); diff --git a/Dalamud.Boot/dllmain.cpp b/Dalamud.Boot/dllmain.cpp index 94f1c7d0f..8ffef40b0 100644 --- a/Dalamud.Boot/dllmain.cpp +++ b/Dalamud.Boot/dllmain.cpp @@ -133,7 +133,9 @@ DWORD WINAPI InitializeImpl(LPVOID lpParam, HANDLE hMainThreadContinue) { // ============================== VEH ======================================== // logging::I("Initializing VEH..."); - if (utils::is_running_on_wine()) { + if (g_startInfo.NoExceptionHandlers) { + logging::W("=> Exception handlers are disabled from DalamudStartInfo."); + } else if (utils::is_running_on_wine()) { logging::I("=> VEH was disabled, running on wine"); } else if (g_startInfo.BootVehEnabled) { if (veh::add_handler(g_startInfo.BootVehFull, g_startInfo.WorkingDirectory)) diff --git a/Dalamud.Common/DalamudStartInfo.cs b/Dalamud.Common/DalamudStartInfo.cs index 069a0ef9f..5126fe3a4 100644 --- a/Dalamud.Common/DalamudStartInfo.cs +++ b/Dalamud.Common/DalamudStartInfo.cs @@ -17,38 +17,6 @@ public record DalamudStartInfo // ignored } - /// - /// Initializes a new instance of the class. - /// - /// Object to copy values from. - public DalamudStartInfo(DalamudStartInfo other) - { - this.WorkingDirectory = other.WorkingDirectory; - this.ConfigurationPath = other.ConfigurationPath; - this.LogPath = other.LogPath; - this.LogName = other.LogName; - this.PluginDirectory = other.PluginDirectory; - this.AssetDirectory = other.AssetDirectory; - this.Language = other.Language; - this.GameVersion = other.GameVersion; - this.DelayInitializeMs = other.DelayInitializeMs; - this.TroubleshootingPackData = other.TroubleshootingPackData; - this.NoLoadPlugins = other.NoLoadPlugins; - this.NoLoadThirdPartyPlugins = other.NoLoadThirdPartyPlugins; - this.BootLogPath = other.BootLogPath; - this.BootShowConsole = other.BootShowConsole; - this.BootDisableFallbackConsole = other.BootDisableFallbackConsole; - this.BootWaitMessageBox = other.BootWaitMessageBox; - this.BootWaitDebugger = other.BootWaitDebugger; - this.BootVehEnabled = other.BootVehEnabled; - this.BootVehFull = other.BootVehFull; - this.BootEnableEtw = other.BootEnableEtw; - this.BootDotnetOpenProcessHookMode = other.BootDotnetOpenProcessHookMode; - this.BootEnabledGameFixes = other.BootEnabledGameFixes; - this.BootUnhookDlls = other.BootUnhookDlls; - this.CrashHandlerShow = other.CrashHandlerShow; - } - /// /// Gets or sets the working directory of the XIVLauncher installations. /// @@ -169,4 +137,9 @@ public record DalamudStartInfo /// Gets or sets a value indicating whether to show crash handler console window. /// public bool CrashHandlerShow { get; set; } + + /// + /// Gets or sets a value indicating whether to disable all kinds of global exception handlers. + /// + public bool NoExceptionHandlers { get; set; } } diff --git a/Dalamud.Injector/EntryPoint.cs b/Dalamud.Injector/EntryPoint.cs index bd9fa87f8..3ffb7ba18 100644 --- a/Dalamud.Injector/EntryPoint.cs +++ b/Dalamud.Injector/EntryPoint.cs @@ -96,6 +96,7 @@ namespace Dalamud.Injector args.Remove("--no-plugin"); args.Remove("--no-3rd-plugin"); args.Remove("--crash-handler-console"); + args.Remove("--no-exception-handlers"); var mainCommand = args[1].ToLowerInvariant(); if (mainCommand.Length > 0 && mainCommand.Length <= 6 && "inject"[..mainCommand.Length] == mainCommand) @@ -393,6 +394,7 @@ namespace Dalamud.Injector startInfo.NoLoadThirdPartyPlugins = args.Contains("--no-3rd-plugin"); // startInfo.BootUnhookDlls = new List() { "kernel32.dll", "ntdll.dll", "user32.dll" }; startInfo.CrashHandlerShow = args.Contains("--crash-handler-console"); + startInfo.NoExceptionHandlers = args.Contains("--no-exception-handlers"); return startInfo; } @@ -434,7 +436,7 @@ namespace Dalamud.Injector Console.WriteLine("Verbose logging:\t[-v]"); Console.WriteLine("Show Console:\t[--console] [--crash-handler-console]"); Console.WriteLine("Enable ETW:\t[--etw]"); - Console.WriteLine("Enable VEH:\t[--veh], [--veh-full]"); + Console.WriteLine("Enable VEH:\t[--veh], [--veh-full], [--no-exception-handlers]"); Console.WriteLine("Show messagebox:\t[--msgbox1], [--msgbox2], [--msgbox3]"); Console.WriteLine("No plugins:\t[--no-plugin] [--no-3rd-plugin]"); Console.WriteLine("Logging:\t[--logname=] [--logpath=]"); @@ -889,7 +891,7 @@ namespace Dalamud.Injector var gameVerStr = File.ReadAllText(Path.Combine(ffxivDir, "ffxivgame.ver")); var gameVer = GameVersion.Parse(gameVerStr); - return new DalamudStartInfo(startInfo) + return startInfo with { GameVersion = gameVer, }; diff --git a/Dalamud/EntryPoint.cs b/Dalamud/EntryPoint.cs index c9537eda6..d0f9e8845 100644 --- a/Dalamud/EntryPoint.cs +++ b/Dalamud/EntryPoint.cs @@ -147,7 +147,8 @@ public sealed class EntryPoint LogLevelSwitch.MinimumLevel = configuration.LogLevel; // Log any unhandled exception. - AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; + if (!info.NoExceptionHandlers) + AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; TaskScheduler.UnobservedTaskException += OnUnobservedTaskException; var unloadFailed = false; @@ -196,7 +197,8 @@ public sealed class EntryPoint finally { TaskScheduler.UnobservedTaskException -= OnUnobservedTaskException; - AppDomain.CurrentDomain.UnhandledException -= OnUnhandledException; + if (!info.NoExceptionHandlers) + AppDomain.CurrentDomain.UnhandledException -= OnUnhandledException; Log.Information("Session has ended."); Log.CloseAndFlush();