Il2Cpp: Redirect stderr on Windows to log CoreCLR crash messages

On Windows, emit BepInEx/ErrorLog.log that will contain the latest stderr
This allows to catch any errors CoreCLR writes before closing on a fatal crash

On Unix, same is already possible via normal piping
This commit is contained in:
ghorsington committed 2022-08-14 17:19:09 +03:00
1 parent c5ca4a8ee5
commit ae18f16803
2 files changed
+52

No files matched your search

+3
View File
@@ -1,6 +1,7 @@
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using BepInEx.IL2CPP.RuntimeFixes;
using BepInEx.Logging;
using BepInEx.Preloader.Core;
using BepInEx.Preloader.Core.Logging;
@@ -38,6 +39,8 @@ public static class Preloader
Logger.Listeners.Add(new ConsoleLogListener());
}
RedirectStdErrFix.Apply();
ChainloaderLogHelper.PrintLogInfo(Log);
Logger.Log(LogLevel.Info, $"Running under Unity {UnityInfo.Version}");
@@ -0,0 +1,49 @@
using System.IO;
using System.Runtime.InteropServices;
using BepInEx.Logging;
using MonoMod.Utils;
namespace BepInEx.IL2CPP.RuntimeFixes;
internal static class RedirectStdErrFix
{
private const int STD_ERROR_HANDLE = -12;
private const int INVALID_HANDLE_VALUE = -1;
private const int FILE_SHARE_READ = 1;
private const int GENERIC_WRITE = 0x40000000;
private const int CREATE_ALWAYS = 2;
private const int FILE_ATTRIBUTE_NORMAL = 0x00000080;
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern nint CreateFile(string fileName,
uint desiredAccess,
int shareMode,
nint securityAttributes,
int creationDisposition,
int flagsAndAttributes,
nint templateFile);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SetStdHandle(int nStdHandle, nint hConsoleOutput);
public static void Apply()
{
if (PlatformHelper.Is(Platform.Windows))
{
Logger.Log(LogLevel.Info, "Redirecting stderr");
var errorFile = CreateFile(Path.Combine(Paths.BepInExRootPath, "ErrorLog.log"), GENERIC_WRITE,
FILE_SHARE_READ,
0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (errorFile == INVALID_HANDLE_VALUE)
{
Logger.Log(LogLevel.Warning, "Failed to open error log file; skipping error redirection");
return;
}
if (!SetStdHandle(STD_ERROR_HANDLE, errorFile))
Logger.Log(LogLevel.Warning, "Failed to redirect stderr; skipping error redirection");
}
// On unix, we can generally redirect stderr to a file "normally" via piping
}
}