mirror of
https://github.com/BepInEx/BepInEx.git
synced 2026-10-20 01:46:13 +00:00
v5: Fix crash on macOS arm64: wrap XTermFix and ConsoleSetOutFix in TryDo (#1288)
On macOS arm64 (Apple Silicon), MonoMod's DetourHelper.GetIdentifiable() returns null for certain methods (e.g. Console.SetOut, TermInfoReader methods). The ILHook constructor does not guard against this null return, causing a NullReferenceException that propagates out of XTermFix.Apply() and ConsoleSetOutFix.Apply() uncaught, which terminates BepInEx initialization before Preloader.Run() is ever called. These two fixes are intentionally called before ConsoleManager.Initialize in PreloaderMain() so they cannot simply be moved into Run(). Instead, wrap each with Utility.TryDo() (the same pattern already used for UnityPatches.Apply in Run()) and store any exception for deferred logging once the BepInEx logger is available. Result: on macOS arm64, BepInEx now fully initializes — Preloader and Chainloader complete, all plugins load — with a LogWarning noting which patches could not be applied rather than a silent hard crash.
This commit is contained in:
1 parent
c69012ad1f
commit
b10beef59b
2 files changed
+20
-2
No files matched your search
@@ -10,6 +10,12 @@ namespace BepInEx.Preloader
|
||||
{
|
||||
internal static class PreloaderRunner
|
||||
{
|
||||
/// <summary>
|
||||
/// Exceptions thrown by XTermFix.Apply() and ConsoleSetOutFix.Apply() during early preloader init,
|
||||
/// stored for deferred logging in <see cref="Preloader.Run"/> once the logger is available.
|
||||
/// </summary>
|
||||
internal static Exception XTermFixException;
|
||||
internal static Exception ConsoleSetOutFixException;
|
||||
// This is a list of important assemblies in BepInEx core folder that should be force-loaded
|
||||
// Some games can ship these assemblies in Managed folder, in which case assembly resolving bypasses our LocalResolve
|
||||
// On the other hand, renaming these assemblies is not viable because 3rd party assemblies
|
||||
@@ -62,8 +68,14 @@ namespace BepInEx.Preloader
|
||||
{
|
||||
if (Preloader.ConfigApplyRuntimePatches.Value)
|
||||
{
|
||||
XTermFix.Apply();
|
||||
ConsoleSetOutFix.Apply();
|
||||
// These fixes must run before ConsoleManager.Initialize (which opens the terminal),
|
||||
// so they cannot be placed inside Preloader.Run(). Wrap them individually so that
|
||||
// a failure on one platform (e.g. macOS arm64, where MonoMod's ILHook throws a
|
||||
// NullReferenceException in DetourHelper.GetIdentifiable) does not prevent BepInEx
|
||||
// from initializing at all. Exceptions are stored for deferred logging once the
|
||||
// BepInEx logger is available in Preloader.Run().
|
||||
Utility.TryDo(() => XTermFix.Apply(), out XTermFixException);
|
||||
Utility.TryDo(() => ConsoleSetOutFix.Apply(), out ConsoleSetOutFixException);
|
||||
}
|
||||
|
||||
Preloader.Run();
|
||||
|
||||
@@ -73,6 +73,12 @@ namespace BepInEx.Preloader
|
||||
Logger.LogInfo($"Supports SRE: {Utility.CLRSupportsDynamicAssemblies}");
|
||||
Logger.LogInfo($"System platform: {PlatformHelper.Current}");
|
||||
|
||||
if (PreloaderRunner.XTermFixException != null)
|
||||
Logger.LogWarning($"Failed to apply XTermFix runtime patch. See more info in the output log. Error message: {PreloaderRunner.XTermFixException.Message}");
|
||||
|
||||
if (PreloaderRunner.ConsoleSetOutFixException != null)
|
||||
Logger.LogWarning($"Failed to apply ConsoleSetOutFix runtime patch. See more info in the output log. Error message: {PreloaderRunner.ConsoleSetOutFixException.Message}");
|
||||
|
||||
if (runtimePatchException != null)
|
||||
Logger.LogWarning($"Failed to apply runtime patches for Mono. See more info in the output log. Error message: {runtimePatchException.Message}");
|
||||
|
||||
|
||||
Reference in new issue
Block a user