From b35faf13b53ce25e0f3f92977a75c4cb154a050b Mon Sep 17 00:00:00 2001 From: goaaats Date: Sun, 7 Dec 2025 13:04:11 +0100 Subject: [PATCH] Show unhandled exceptions through VEH --- Dalamud.Boot/veh.cpp | 6 +++++ Dalamud/EntryPoint.cs | 25 +++---------------- .../Interface/Internal/DalamudInterface.cs | 7 ++++++ Dalamud/Utility/ErrorHandling.cs | 21 ++++++++++++++++ DalamudCrashHandler/DalamudCrashHandler.cpp | 4 +-- 5 files changed, 40 insertions(+), 23 deletions(-) create mode 100644 Dalamud/Utility/ErrorHandling.cs diff --git a/Dalamud.Boot/veh.cpp b/Dalamud.Boot/veh.cpp index 50ac9b34c..194840e52 100644 --- a/Dalamud.Boot/veh.cpp +++ b/Dalamud.Boot/veh.cpp @@ -453,3 +453,9 @@ void veh::raise_external_event(const std::wstring& info) wcsncpy_s(g_external_event_info, info.c_str(), info_size); RaiseException(CUSTOM_EXCEPTION_EXTERNAL_EVENT, 0, 0, nullptr); } + +extern "C" __declspec(dllexport) void BootVehRaiseExternalEventW(LPCWSTR info) +{ + const std::wstring info_wstr(info); + veh::raise_external_event(info_wstr); +} diff --git a/Dalamud/EntryPoint.cs b/Dalamud/EntryPoint.cs index 15077f3d8..0f8cb0480 100644 --- a/Dalamud/EntryPoint.cs +++ b/Dalamud/EntryPoint.cs @@ -292,7 +292,6 @@ public sealed class EntryPoint } var pluginInfo = string.Empty; - var supportText = ", please visit us on Discord for more help"; try { var pm = Service.GetNullable(); @@ -300,9 +299,6 @@ public sealed class EntryPoint if (plugin != null) { pluginInfo = $"Plugin that caused this:\n{plugin.Name}\n\nClick \"Yes\" and remove it.\n\n"; - - if (plugin.IsThirdParty) - supportText = string.Empty; } } catch @@ -310,31 +306,18 @@ public sealed class EntryPoint // ignored } - const MESSAGEBOX_STYLE flags = MESSAGEBOX_STYLE.MB_YESNO | MESSAGEBOX_STYLE.MB_ICONERROR | MESSAGEBOX_STYLE.MB_SYSTEMMODAL; - var result = Windows.Win32.PInvoke.MessageBox( - new HWND(Process.GetCurrentProcess().MainWindowHandle), - $"An internal error in a Dalamud plugin occurred.\nThe game must close.\n\n{ex.GetType().Name}\n{info}\n\n{pluginInfo}More information has been recorded separately{supportText}.\n\nDo you want to disable all plugins the next time you start the game?", - "Dalamud", - flags); - - if (result == MESSAGEBOX_RESULT.IDYES) - { - Log.Information("User chose to disable plugins on next launch..."); - var config = Service.Get(); - config.PluginSafeMode = true; - config.ForceSave(); - } - Log.CloseAndFlush(); - Environment.Exit(-1); + + ErrorHandling.CrashWithContext($"{ex}\n\n{info}\n\n{pluginInfo}"); break; default: Log.Fatal("Unhandled SEH object on AppDomain: {Object}", args.ExceptionObject); Log.CloseAndFlush(); - Environment.Exit(-1); break; } + + Environment.Exit(-1); } private static void OnUnhandledExceptionStallDebug(object sender, UnhandledExceptionEventArgs args) diff --git a/Dalamud/Interface/Internal/DalamudInterface.cs b/Dalamud/Interface/Internal/DalamudInterface.cs index af78c5b0c..bf55a5486 100644 --- a/Dalamud/Interface/Internal/DalamudInterface.cs +++ b/Dalamud/Interface/Internal/DalamudInterface.cs @@ -667,6 +667,8 @@ internal class DalamudInterface : IInternalDisposableService { if (this.isImGuiDrawDevMenu) { + using var barColor = ImRaii.PushColor(ImGuiCol.WindowBg, new Vector4(0.060f, 0.060f, 0.060f, 0.773f)); + barColor.Push(ImGuiCol.MenuBarBg, Vector4.Zero); if (ImGui.BeginMainMenuBar()) { var pluginManager = Service.Get(); @@ -839,6 +841,11 @@ internal class DalamudInterface : IInternalDisposableService ImGui.PopStyleVar(); } + if (ImGui.MenuItem("Raise external event through boot")) + { + ErrorHandling.CrashWithContext("Tést"); + } + ImGui.EndMenu(); } diff --git a/Dalamud/Utility/ErrorHandling.cs b/Dalamud/Utility/ErrorHandling.cs new file mode 100644 index 000000000..3c025a12e --- /dev/null +++ b/Dalamud/Utility/ErrorHandling.cs @@ -0,0 +1,21 @@ +using System.Runtime.InteropServices; + +namespace Dalamud.Utility; + +/// +/// Utilities for handling errors inside Dalamud. +/// +internal static partial class ErrorHandling +{ + /// + /// Crash the game at this point, and show the crash handler with the supplied context. + /// + /// The context to show in the crash handler. + public static void CrashWithContext(string context) + { + BootVehRaiseExternalEvent(context); + } + + [LibraryImport("Dalamud.Boot.dll", EntryPoint = "BootVehRaiseExternalEventW", StringMarshalling = StringMarshalling.Utf16)] + private static partial void BootVehRaiseExternalEvent(string info); +} diff --git a/DalamudCrashHandler/DalamudCrashHandler.cpp b/DalamudCrashHandler/DalamudCrashHandler.cpp index 1feec4b2f..3955bd983 100644 --- a/DalamudCrashHandler/DalamudCrashHandler.cpp +++ b/DalamudCrashHandler/DalamudCrashHandler.cpp @@ -1014,8 +1014,8 @@ int main() { config.pButtons = buttons; config.cButtons = ARRAYSIZE(buttons); config.nDefaultButton = IdButtonRestart; - config.pszExpandedControlText = L"Hide stack trace"; - config.pszCollapsedControlText = L"Stack trace for plugin developers"; + config.pszExpandedControlText = L"Hide further information"; + config.pszCollapsedControlText = L"Further information for developers"; config.pszExpandedInformation = window_log_str.c_str(); config.pszWindowTitle = L"Dalamud Crash Handler"; config.pRadioButtons = radios;