BepInEx / HarmonyX

Harmony built on top of MonoMod.RuntimeDetours with additional features
MIT License
329 stars 42 forks source link

Assembly.GetExecutingAssembly causing game to crash #112

Closed MarshMello0 closed 4 weeks ago

MarshMello0 commented 1 month ago

I have been trying to move from Harmony2 to HarmonyX for my mod loader but sadly been hitting a lot of crashes.

Been trying to create a simple mod to load Unity Explorer, in my Awake method I have this:

private void Awake()
{
    LoaderClass.Log("Awake");
    Assembly executingAssembly = Assembly.GetExecutingAssembly();
    string location = executingAssembly.Location;
    this.LoadAssemblies(Path.GetDirectoryName(location));
}

Putting a break point on Assembly executingAssembly = Assembly.GetExecutingAssembly(); its all fine, then stepping over this line it crashes with Access violation.

Does anyone know what could be causing this?

Context

Built Game: VTOL VR Unity Engine: 2020.3.30f1 Mono Call stack in the player.logs when it crashes ``` 0x000001502852A6F3 (Mono JIT Code) UnityExplorer.LoaderClass:Awake () 0x000001502852A3B8 (Mono JIT Code) (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr) 0x00007FFFB141F1E0 (mono-2.0-bdwgc) mono_get_runtime_build_info 0x00007FFFB13A2AC2 (mono-2.0-bdwgc) mono_perfcounters_init 0x00007FFFB13ABB1F (mono-2.0-bdwgc) mono_runtime_invoke 0x00007FFFACDB4D7D (UnityPlayer) UnityMain 0x00007FFFACDB1EE2 (UnityPlayer) UnityMain 0x00007FFFACDB1FAE (UnityPlayer) UnityMain 0x00007FFFACDDE815 (UnityPlayer) UnityMain 0x00007FFFACD99AF8 (UnityPlayer) UnityMain 0x00007FFFACD98EBD (UnityPlayer) UnityMain 0x00007FFFACD93C25 (UnityPlayer) UnityMain 0x00007FFFACDDFF52 (UnityPlayer) UnityMain 0x00007FFFACC3B8B2 (UnityPlayer) UnityMain 0x00007FFFACC3754F (UnityPlayer) UnityMain 0x00007FFFACC3724F (UnityPlayer) UnityMain 0x00007FFFACD4A1AD (UnityPlayer) UnityMain 0x00007FFFACE0E084 (UnityPlayer) UnityMain 0x0000014F2ECDCB41 (Mono JIT Code) (wrapper managed-to-native) UnityEngine.GameObject:Internal_AddComponentWithType (UnityEngine.GameObject,System.Type) 0x0000014F2ECDC943 (Mono JIT Code) UnityEngine.GameObject:AddComponent (System.Type) 0x0000014F2ECDC5A3 (Mono JIT Code) UnityEngine.GameObject:.ctor (string,System.Type[]) 0x0000015028520C43 (Mono JIT Code) ModLoader.ModLoader:SpawnVtolMod (System.Type,System.Reflection.Assembly,SteamQueries.Models.SteamItem) 0x00000150284FD073 (Mono JIT Code) ModLoader.ModLoader:LoadMod (SteamQueries.Models.SteamItem,ulong) 0x00000150284FBA03 (Mono JIT Code) ModLoader.ModLoader:LoadSteamItem (SteamQueries.Models.SteamItem) 0x00000150284E0943 (Mono JIT Code) ModLoader.LoadOnStartSpawner:LoadLocalItems (System.Collections.Generic.Dictionary`2) 0x000001502733CB5B (Mono JIT Code) ModLoader.LoadOnStartSpawner:RequestForLoadOnStartSettings () 0x000001502733A84B (Mono JIT Code) ModLoader.LoadOnStartSpawner:Start () 0x0000014DE7F7F958 (Mono JIT Code) (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr) 0x00007FFFB141F1E0 (mono-2.0-bdwgc) mono_get_runtime_build_info 0x00007FFFB13A2AC2 (mono-2.0-bdwgc) mono_perfcounters_init 0x00007FFFB13ABB1F (mono-2.0-bdwgc) mono_runtime_invoke 0x00007FFFACDB4D7D (UnityPlayer) UnityMain 0x00007FFFACDB1EE2 (UnityPlayer) UnityMain 0x00007FFFACD9C940 (UnityPlayer) UnityMain 0x00007FFFACD9C9CE (UnityPlayer) UnityMain 0x00007FFFACD9A19A (UnityPlayer) UnityMain 0x00007FFFACB11F64 (UnityPlayer) UnityMain 0x00007FFFACC43C5A (UnityPlayer) UnityMain 0x00007FFFACC43D00 (UnityPlayer) UnityMain 0x00007FFFACC47A58 (UnityPlayer) UnityMain ERROR: SymGetSymFromAddr64, GetLastError: 'Attempt to access invalid address.' (Address: 00007FFFACA08CEA) 0x00007FFFACA08CEA (UnityPlayer) (function-name not available) ERROR: SymGetSymFromAddr64, GetLastError: 'Attempt to access invalid address.' (Address: 00007FFFACA071AB) 0x00007FFFACA071AB (UnityPlayer) (function-name not available) ERROR: SymGetSymFromAddr64, GetLastError: 'Attempt to access invalid address.' (Address: 00007FFFACA0C342) 0x00007FFFACA0C342 (UnityPlayer) (function-name not available) 0x00007FFFACA0D2CB (UnityPlayer) UnityMain ERROR: SymGetSymFromAddr64, GetLastError: 'Attempt to access invalid address.' (Address: 00007FF75A6311F2) 0x00007FF75A6311F2 (VTOLVR) (function-name not available) 0x00007FF89C4D7344 (KERNEL32) BaseThreadInitThunk 0x00007FF89D8826B1 (ntdll) RtlUserThreadStart ``` And `HarmonyFileLog.log` is empty

ManlyMarco commented 1 month ago

Does it work fine when loaded by BepInEx?

MarshMello0 commented 1 month ago

Yep seemed to work all fine with with BepInEx_win_x64_5.4.23.1. (I assume HarmonyX is packaged up with it by default)

I created this basic plugin

```c# using System.Reflection; using BepInEx; namespace BepInEx_Crash_Test { [BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)] public class Plugin : BaseUnityPlugin { private void Awake() { // Plugin startup logic Logger.LogInfo($"Plugin {PluginInfo.PLUGIN_GUID} is loaded!"); var assembly = Assembly.GetExecutingAssembly(); Logger.LogInfo($"This is after calling {nameof(Assembly.GetExecutingAssembly)}, the result was {assembly}"); } } } ```

and it showed up all fine in the logs without crashing the game

> [Message: BepInEx] BepInEx 5.4.23.1 - VTOLVR (22/05/2024 21:44:57) [Info : BepInEx] Running under Unity v2020.3.30.2077119 [Info : BepInEx] CLR runtime version: 4.0.30319.42000 [Info : BepInEx] Supports SRE: True [Info : BepInEx] System platform: Bits64, Windows [Message: BepInEx] Preloader started [Info : BepInEx] Loaded 1 patcher method from [BepInEx.Preloader 5.4.23.1] [Info : BepInEx] 1 patcher plugin loaded [Info : BepInEx] Patching [UnityEngine.CoreModule] with [BepInEx.Chainloader] [Message: BepInEx] Preloader finished [Message: BepInEx] Chainloader ready [Message: BepInEx] Chainloader started [Info : BepInEx] 1 plugin to load [Info : BepInEx] Loading [BepInEx_Crash_Test 1.0.0] [Info :BepInEx_Crash_Test] Plugin BepInEx_Crash_Test is loaded! [Info :BepInEx_Crash_Test] This is after calling GetExecutingAssembly, the result was BepInEx_Crash_Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null [Message: BepInEx] Chainloader startup complete

ManlyMarco commented 1 month ago

I assume HarmonyX is packaged up with it by default

Yes, it is. This means you're missing something in your launcher then.

MarshMello0 commented 1 month ago

When you say something, are you meaning maybe an assembly? Comparing with dependencies HarmonyX brings in through Nuget vs what I have installed, there isn't anything missing.

Adding this just for context of the thread, now weirdly having:

var path = Assembly.GetExecutingAssembly();
Debug.Log(path);

Throw a null error in debug.log, even though decompiled dll shows its got a null check image

NullReferenceException: Object reference not set to an instance of an object
  at UnityEngine.Logger.GetString (System.Object message) [0x00032] in <72b60a3dd8cd4f12a155b761a1af9144>:0 
  at UnityEngine.Logger.Log (UnityEngine.LogType logType, System.Object message) [0x00012] in <72b60a3dd8cd4f12a155b761a1af9144>:0 
  at UnityEngine.Debug.Log (System.Object message) [0x00006] in <72b60a3dd8cd4f12a155b761a1af9144>:0 
  at Pop.HelmetPop+<LoadAudioClip>d__2.MoveNext () [0x00030] in <62d0a4dbf2a34d38ba2e27292f55322c>:0 
  at UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) [0x00026] in <72b60a3dd8cd4f12a155b761a1af9144>:0 
Meivyn commented 1 month ago

If you use HarmonyX v2.12.0, that's most likely the same issue https://github.com/BepInEx/HarmonyX/pull/79#issuecomment-1867407564 which was introduced in reorg. I don't think BepInEx is using the reorg version currently? That was supposed to be fixed with https://github.com/BepInEx/HarmonyX/commit/6e3726f88a045a1284498b8b4899425a943b0c15 which isn't released yet though.

Using the latest version of HarmonyX produced the same behavior as you when I was using it in our mod loader. Sometimes it was crashing Unity, sometimes it threw a null ref.

You either should use v2.10.2 or wait for the next release. v2.12.0 is broken. And it was released knowing it was broken. For some reason.

ManlyMarco commented 1 month ago

I don't think BepInEx is using the reorg version currently?

It is not using it yet. This might be fixed by https://github.com/BepInEx/HarmonyX/pull/114 ?

Meivyn commented 1 month ago

It should be fixed by #97.

MarshMello0 commented 4 weeks ago

Added HarmonyX source to my project and compiled at the current latest on master. Ran it three times and it didn't crash!

Closing this as I've confirmed its fixed for me. Thank you so much @Meivyn for that insight