NeighTools / UnityDoorstop

Doorstop -- run C# before Unity does!
GNU Lesser General Public License v2.1
419 stars 62 forks source link

Support MacOS Apple Silicon (arm64) #61

Open allquixotic opened 2 weeks ago

allquixotic commented 2 weeks ago

A fairly high profile game, Valheim, just released a native Mac build. It is going to be featured at WWDC 2024, so it is likely to receive a lot of attention.

The Mac build of Valheim is still based on Unity and Mono, just like the Windows version, and they provide a "Universal Binary" of the game, which ships dual-architecture executables and libraries that are compiled for both Intel x64 and Apple Silicon arm64.

We have a way of running mods using BepInEx currently by forcing the game to run in Intel x64 mode, which kicks in Apple's Rosetta binary translator. Unfortunately, because Mono emits "new" native code all the time using its JIT compiler, Rosetta frequently causes the game to stutter or reduce FPS on some hardware. The Apple Silicon (arm64) native version of the game runs much faster because this binary translation layer is not needed.

Is it just a matter of recompiling UnityDoorstop to get it working for arm64, or would it require significant new code (e.g. in arm64 assembly) to get it to work?

ManlyMarco commented 2 weeks ago

I don't think any of us have anything with apple silicon in it so this won't be worked on. Someone would have to make a PR that adds this support.

allquixotic commented 2 weeks ago

I would happily donate time on an Apple Silicon Mac Mini at one of the cloud providers for you guys to work on this. However, I've already made some headway: I managed to fix the build scripts and the GitHub Actions (the latter, untested at the moment) for Apple Silicon / universal binary support. See https://github.com/allquixotic/UnityDoorstop/commit/6734aca25f3fe35529aa1cbb023e81f093e43de1

The library builds and links just fine, and produces a universal binary, but when it's run in arm64, the code in plthook_osx.c which assumes x86-64 architecture crashes with a segmentation fault. Log at the bottom.

The original developer of plthook_osx.c has added support for Apple Silicon; you can find it here: https://github.com/kubo/plthook/blob/master/plthook_osx.c

I see your version of the header has plthook_handle_by_name that upstream doesn't. Other than that, are there any semantic differences in the behavior of the plthook functions that your code expects, that the upstream wouldn't provide?

If not, would it be possible to replace plthook_osx.c with the latest upstream, then patch in plthook_handle_by_name() and figure out how to implement it in terms of the other functions from upstream?

Just spitballing to try to determine how to get this working.


Crash on arm64:

slide=107b1c000
Image name: /Users/sean/Library/Application Support/Steam/steamapps/common/Valheim/valheim.app/Contents/Frameworks/UnityPlayer.dylib
LC_SEGMENT_64
  segname   __TEXT
  vmaddr           0  vmsize      17a0000
  fileoff          0  filesize    17a0000
  maxprot          5  initprot          5
  nsects          13  flags             0
LC_SEGMENT_64
  segname   __DATA_CONST
  vmaddr     17a0000  vmsize        98000
  fileoff    17a0000  filesize      98000
  maxprot          3  initprot          3
  nsects           8  flags            10
LC_SEGMENT_64
  segname   __DATA
  vmaddr     1838000  vmsize       164000
  fileoff    1838000  filesize      2c000
  maxprot          3  initprot          3
  nsects          13  flags             0
LC_SEGMENT_64
  segname   __LINKEDIT
  vmaddr     199c000  vmsize        d7fc0
  fileoff    1864000  filesize      b9ca0
  maxprot          1  initprot          1
  nsects           0  flags             0
LC_ID_DYLIB
LC_DYLD_INFO_ONLY
                 offset     size
  rebase        1864000     44f8
  bind          18684f8     28f8
  weak_bind     186adf0     11e0
  lazy_bind     186bfd0     4c98
  export_bind   1870c68    1d9e0
LC_SYMTAB
symbol count:     1208
symbol offset:  18a9bd8
stf offset:  18bd590
str size:    2a2b0
LC_DYSYMTAB
itable offset:  18bbc58
itable count:      64e
LC_UUID
LC_? (0x32)
LC_SOURCE_VERSION
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_FUNCTION_STARTS
LC_DATA_IN_CODE
LC_? (0x1d)
__DATA section __la_symbol_ptr
Found lazy symbol pointers
Got FAT binary
Has arch: X86_64, offset:     8000
Got base offset: 8000
zsh: segmentation fault  ./run_bepinex.sh
allquixotic commented 2 weeks ago

would it be possible to replace plthook_osx.c with the latest upstream, then patch in plthook_handle_by_name() and figure out how to implement it in terms of the other functions from upstream?

I tried this, and it seems to work (?) but there might be something wrong with the HarmonyX patcher that BepInEx uses. Not sure if this is caused by the plthook implementation or if this is something that breaks on arm64 and needs to also be adjusted for arm64.

Code is HERE: https://github.com/NeighTools/UnityDoorstop/compare/master...allquixotic:UnityDoorstop:master

Anyway, from these logs, it appears that Doorstop "does its job" and invokes the main method of the entry point DLL of BepInEx. The latter may not be coded to properly support this new arm64 world :)

Here is my Doorstop verbose output:

/Users/sean/Library/Application Support/Steam/steamapps/common/Valheim/valheim.app
/Users/sean/Library/Application Support/Steam/steamapps/common/Valheim/valheim.app/Contents/MacOS/Valheim
[Doorstop] DOORSTOP_ENABLED: 1
[Doorstop] DOORSTOP_REDIRECT_OUTPUT_LOG: 0
[Doorstop] DOORSTOP_IGNORE_DISABLED_ENV: 0
[Doorstop] DOORSTOP_MONO_DEBUG_ENABLED: 0
[Doorstop] DOORSTOP_MONO_DEBUG_SUSPEND: 0
[Doorstop] DOORSTOP_MONO_DEBUG_ADDRESS: 127.0.0.1:10000
[Doorstop] DOORSTOP_TARGET_ASSEMBLY: /Users/sean/Library/Application Support/Steam/steamapps/common/Valheim/BepInEx/core/BepInEx.Unity.Mono.Preloader.dll
[Doorstop] DOORSTOP_BOOT_CONFIG_OVERRIDE: (null)
[Doorstop] DOORSTOP_MONO_DLL_SEARCH_PATH_OVERRIDE: BepInEx/core
[Doorstop] DOORSTOP_CLR_RUNTIME_CORECLR_PATH: /Users/sean/Library/Application Support/Steam/steamapps/common/Valheim/.dylib
[Doorstop] DOORSTOP_CLR_CORLIB_DIR: (null)
mh=1042d4000 slide=1042d4000
MEMORY MAP(/Users/sean/Library/Application Support/Steam/steamapps/common/Valheim/valheim.app/Contents/Frameworks/UnityPlayer.dylib)
 start address    end address      protection    max_protection inherit     shared reserved offset   behavior         user_wired_count
 00000001008ac000-00000001008b0000 r-x(00000005) r-x(00000005)  copy        N      N        00010000 default          0
 00000001008b0000-00000001008b4000 r--(00000001) rw-(00000003)  copy        N      N        00000000 default          0
 00000001008b4000-00000001008b8000 rw-(00000003) rw-(00000003)  copy        N      N        00000000 default          0
 00000001008b8000-00000001008bc000 r--(00000001) r--(00000001)  copy        N      N        0001c000 default          0
 00000001008bc000-0000000100cbc000 rw-(00000003) rwx(00000007)  copy        N      N        00000000 default          0
 0000000100cbc000-0000000100cc0000 ---(00000000) ---(00000000)  copy        N      N        00400000 default          0
 0000000100cc0000-0000000100d00000 rw-(00000003) rwx(00000007)  copy        N      N        00000000 default          0
 0000000100d00000-0000000100d04000 ---(00000000) ---(00000000)  copy        N      N        00040000 default          0
 0000000100d04000-0000000100d0c000 rw-(00000003) rwx(00000007)  copy        N      N        00000000 default          0
 0000000100d0c000-0000000100d10000 r--(00000001) r--(00000001)  share       N      N        00000000 default          0
 0000000100d10000-0000000100d14000 r--(00000001) rwx(00000007)  copy        N      N        00000000 default          0
 0000000100d14000-0000000100d18000 rw-(00000003) rwx(00000007)  copy        N      N        00004000 default          0
 0000000100d18000-0000000100d1c000 r--(00000001) rwx(00000007)  copy        N      N        00000000 default          0
 0000000100d1c000-0000000100d20000 r--(00000001) rwx(00000007)  copy        N      N        00000000 default          0
 0000000100d20000-0000000100d24000 rw-(00000003) rwx(00000007)  copy        N      N        00004000 default          0
 0000000100d28000-0000000100d34000 r-x(00000005) rwx(00000007)  copy        N      N        00010000 default          0
 0000000100d34000-0000000100d38000 r--(00000001) rw-(00000003)  copy        N      N        0001c000 default          0
 0000000100d38000-0000000100d3c000 rw-(00000003) rwx(00000007)  copy        N      N        00000000 default          0
 0000000100d3c000-0000000100d40000 r--(00000001) rwx(00000007)  copy        N      N        00020000 default          0
 0000000100d40000-0000000100d44000 ---(00000000) rwx(00000007)  copy        N      N        00000000 default          0
 0000000100d44000-0000000100d50000 rw-(00000003) rwx(00000007)  copy        N      N        00004000 default          0
 0000000100d50000-0000000100d54000 ---(00000000) rwx(00000007)  copy        N      N        00010000 default          0
 0000000100d54000-0000000100d58000 ---(00000000) rwx(00000007)  copy        N      N        00000000 default          0
 0000000100d58000-0000000100d64000 rw-(00000003) rwx(00000007)  copy        N      N        00004000 default          0
 0000000100d64000-0000000100d68000 ---(00000000) rwx(00000007)  copy        N      N        00010000 default          0
 0000000100d68000-0000000100d6c000 ---(00000000) rwx(00000007)  copy        N      N        00000000 default          0
 0000000100d6c000-0000000100d78000 rw-(00000003) rwx(00000007)  copy        N      N        00004000 default          0
 0000000100d78000-0000000100d7c000 ---(00000000) rwx(00000007)  copy        N      N        00010000 default          0
 00000001042d4000-0000000105a74000 r-x(00000005) rwx(00000007)  copy        N      N        01c74000 default          0
 0000000105a74000-0000000105b0c000 r--(00000001) rwx(00000007)  copy        N      N        00000000 default          0
 0000000105b0c000-0000000105b38000 rw-(00000003) rwx(00000007)  copy        N      N        00000000 default          0
 0000000105b38000-0000000105c70000 rw-(00000003) rwx(00000007)  copy        N      N        01864000 default          0
 0000000105c70000-0000000105d48000 r--(00000001) rwx(00000007)  copy        N      N        034d8000 default          0
 0000000148e00000-0000000148f00000 rw-(00000003) rwx(00000007)  copy        N      N        00000000 default          0
 0000000149000000-0000000149800000 rw-(00000003) rwx(00000007)  copy        N      N        00000000 default          0
 000000016b554000-000000016ed58000 ---(00000000) rwx(00000007)  copy        N      N        00000000 default          0
 000000016ed58000-000000016f554000 rw-(00000003) rwx(00000007)  copy        N      N        00000000 default          0
 0000000180000000-0000000204000000 r--(00000001) r--(00000001)  share       N      Y        00000000 default          0
 0000000204000000-0000000204310000 r--(00000001) r--(00000001)  share       N      Y        84000000 default          0
 0000000204310000-000000020458c000 r--(00000001) rw-(00000003)  copy        N      N        00000000 default          0
 000000020458c000-0000000206000000 r--(00000001) r--(00000001)  share       N      Y        8458c000 default          0
 0000000206000000-000000020658c000 r--(00000001) r--(00000001)  share       N      Y        86000000 default          0
 000000020658c000-00000002065ac000 rw-(00000003) rw-(00000003)  copy        N      N        00000000 default          0
 00000002065ac000-0000000207650000 r--(00000001) r--(00000001)  share       N      Y        865ac000 default          0
 0000000207650000-000000020c420000 rw-(00000003) rw-(00000003)  copy        N      N        00000000 default          0
 000000020c420000-0000000211c8c000 r--(00000001) rw-(00000003)  copy        N      N        00000000 default          0
 0000000211c8c000-0000000212000000 r--(00000001) r--(00000001)  share       N      Y        91c8c000 default          0
 0000000212000000-0000000274000000 r--(00000001) r--(00000001)  share       N      Y        92000000 default          0
 0000000274000000-00000002745ac000 r--(00000001) r--(00000001)  share       N      Y        f4000000 default          0
 00000002745ac000-0000000274d14000 r--(00000001) rw-(00000003)  copy        N      N        00000000 default          0
 0000000274d14000-0000000276000000 r--(00000001) r--(00000001)  share       N      Y        f4d14000 default          0
 0000000276000000-0000000278000000 r--(00000001) r--(00000001)  share       N      Y        f6000000 default          0
 0000000278000000-00000002781e0000 r--(00000001) r--(00000001)  share       N      Y        f8000000 default          0
 00000002781e0000-000000027bf54000 rw-(00000003) rw-(00000003)  copy        N      N        00000000 default          0
 000000027bf54000-000000027e0dc000 r--(00000001) rw-(00000003)  copy        N      N        00000000 default          0
 000000027e0dc000-0000000280000000 r--(00000001) r--(00000001)  share       N      Y        fe0dc000 default          0
 0000000280000000-0000000300000000 r--(00000001) r--(00000001)  share       N      Y        100000000 default          0
 0000000fc0000000-0000001000000000 ---(00000000) ---(00000000)  copy        N      N        00000000 default          0
 0000001000000000-0000007000000000 ---(00000000) ---(00000000)  copy        N      N        00000000 default          0
 0000600000000000-0000600020000000 rw-(00000003) rwx(00000007)  copy        N      N        00000000 default          0
CMD START
LC_SEGMENT_64
  segname   __TEXT
  vmaddr           0  vmsize      17a0000
  fileoff          0  filesize    17a0000
  maxprot          5  initprot          5
  nsects          13  flags             0
LC_SEGMENT_64
  segname   __DATA_CONST
  vmaddr     17a0000  vmsize        98000
  fileoff    17a0000  filesize      98000
  maxprot          3  initprot          3
  nsects           8  flags            10
  section_64 (0)
      sectname  __got
      segname   __DATA_CONST
      addr      0x17a0000
      size      0x460
      offset    0x17a0000
      align     0x3
      reloff    0x0
      nreloc    0
      flags     0x6
      reserved1 737
      reserved2 0
      reserved3 0
(( SNIP a ton of very similar section_64 blocks. -allquixotic ))
LC_SEGMENT_64
  segname   __DATA
  vmaddr     1838000  vmsize       164000
  fileoff    1838000  filesize      2c000
  maxprot          3  initprot          3
  nsects          13  flags             0
LC_SEGMENT_64
  segname   __LINKEDIT
  vmaddr     199c000  vmsize        d7fc0
  fileoff    1864000  filesize      b9ca0
  maxprot          1  initprot          1
  nsects           0  flags             0
LC_ID_DYLIB
LC_DYLD_INFO_ONLY
                 offset     size
  rebase        1864000     44f8
  bind          18684f8     28f8
  weak_bind     186adf0     11e0
  lazy_bind     186bfd0     4c98
  export_bind   1870c68    1d9e0
LC_SYMTAB
LC_DYSYMTAB
LC_UUID
LC_BUILD_VERSION
LC_SOURCE_VERSION
LC_LOAD_DYLIB
(( SNIP a ton of repeated lines. -allquixotic ))
LC_LOAD_DYLIB
LC_FUNCTION_STARTS
LC_DATA_IN_CODE
LC_CODE_SIGNATURE
CMD END
0x72: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: seg_index = 2, seg_offset = 0x0
0x19: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: ordinal = 9
0x40: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: sym_name = _AudioComponentFindNext
0x90: BIND_OPCODE_DO_BIND
0x00: BIND_OPCODE_DONE
(( SNIP; there are thousands of lines like this. -allquixotic ))
[Doorstop] Found UnityPlayer, hooking into it instead
Failed to hook jit_init_version, ignoring it. This is probably fine unless you see other errors. Error: no such function: mono_jit_init_version
[UnityMemory] Configuration Parameters - Can be set up in boot.config
    "memorysetup-bucket-allocator-granularity=16"
    "memorysetup-bucket-allocator-bucket-count=8"
    "memorysetup-bucket-allocator-block-size=4194304"
    "memorysetup-bucket-allocator-block-count=1"
    "memorysetup-main-allocator-block-size=16777216"
    "memorysetup-thread-allocator-block-size=16777216"
    "memorysetup-gfx-main-allocator-block-size=16777216"
    "memorysetup-gfx-thread-allocator-block-size=16777216"
    "memorysetup-cache-allocator-block-size=4194304"
    "memorysetup-typetree-allocator-block-size=2097152"
    "memorysetup-profiler-bucket-allocator-granularity=16"
    "memorysetup-profiler-bucket-allocator-bucket-count=8"
    "memorysetup-profiler-bucket-allocator-block-size=4194304"
    "memorysetup-profiler-bucket-allocator-block-count=1"
    "memorysetup-profiler-allocator-block-size=16777216"
    "memorysetup-profiler-editor-allocator-block-size=1048576"
    "memorysetup-temp-allocator-size-main=4194304"
    "memorysetup-job-temp-allocator-block-size=2097152"
    "memorysetup-job-temp-allocator-block-size-background=1048576"
    "memorysetup-job-temp-allocator-reduction-small-platforms=262144"
    "memorysetup-allocator-temp-initial-block-size-main=262144"
    "memorysetup-allocator-temp-initial-block-size-worker=262144"
    "memorysetup-temp-allocator-size-background-worker=32768"
    "memorysetup-temp-allocator-size-job-worker=262144"
    "memorysetup-temp-allocator-size-preload-manager=262144"
    "memorysetup-temp-allocator-size-nav-mesh-worker=65536"
    "memorysetup-temp-allocator-size-audio-worker=65536"
    "memorysetup-temp-allocator-size-cloud-worker=32768"
    "memorysetup-temp-allocator-size-gfx=262144"
[Doorstop] Starting mono domain "Unity Root Domain"
[Doorstop] Runtime version: v4.0.30319
[Doorstop] Current root: /Users/sean/Library/Application Support/Steam/steamapps/common/Valheim/valheim.app/Contents/Resources/Data/Managed
[Doorstop] Overriding mono DLL search path
[Doorstop] Adding root path: /Users/sean/Library/Application Support/Steam/steamapps/common/Valheim/BepInEx/core
[Doorstop] Mono search path: /Users/sean/Library/Application Support/Steam/steamapps/common/Valheim/BepInEx/core:/Users/sean/Library/Application Support/Steam/steamapps/common/Valheim/valheim.app/Contents/Resources/Data/Managed
[Doorstop] Setting config paths: base dir: /Users/sean/Library/Application Support/Steam/steamapps/common/Valheim/valheim.app/Contents/MacOS; config path: /Users/sean/Library/Application Support/Steam/steamapps/common/Valheim/valheim.app/Contents/MacOS/Valheim.config

[Doorstop] Assembly dir: /Users/sean/Library/Application Support/Steam/steamapps/common/Valheim/valheim.app/Contents/Resources/Data/Managed
[Doorstop] Opening assembly: /Users/sean/Library/Application Support/Steam/steamapps/common/Valheim/BepInEx/core/BepInEx.Unity.Mono.Preloader.dll
[Doorstop] Opened Assembly DLL (33792 bytes); opening its main image
[Doorstop] Image opened; loading included assembly
[Doorstop] Assembly loaded; looking for Doorstop.Entrypoint:Start
[Doorstop] Invoking method 0x148e12f38
[Doorstop] Done

Here is my BepInEx preloader where Harmony crashes (using the latest BepInEx bleeding edge DLLs or the latest stable):

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> HarmonyLib.HarmonyException: IL Compile Error (unknown location) ---> System.NullReferenceException: Object reference not set to an instance of an object
  at MonoMod.RuntimeDetour.DetourHelper.GetIdentifiable (System.Reflection.MethodBase method) [0x00005] in <7e79d87a23084646a4f7750a6feaa4c0>:0 
  at MonoMod.RuntimeDetour.ILHook..ctor (System.Reflection.MethodBase from, MonoMod.Cil.ILContext+Manipulator manipulator, MonoMod.RuntimeDetour.ILHookConfig& config) [0x0001c] in <7e79d87a23084646a4f7750a6feaa4c0>:0 
  at MonoMod.RuntimeDetour.ILHook..ctor (System.Reflection.MethodBase from, MonoMod.Cil.ILContext+Manipulator manipulator, MonoMod.RuntimeDetour.ILHookConfig config) [0x00000] in <7e79d87a23084646a4f7750a6feaa4c0>:0 
  at HarmonyLib.Public.Patching.ManagedMethodPatcher.DetourTo (System.Reflection.MethodBase replacement) [0x0000f] in <40a82cc9705b4865b72ee4c45165e7e9>:0 
  at HarmonyLib.PatchFunctions.UpdateWrapper (System.Reflection.MethodBase original, HarmonyLib.PatchInfo patchInfo) [0x00033] in <40a82cc9705b4865b72ee4c45165e7e9>:0 
   --- End of inner exception stack trace ---
  at HarmonyLib.PatchClassProcessor.ReportException (System.Exception exception, System.Reflection.MethodBase original) [0x00045] in <40a82cc9705b4865b72ee4c45165e7e9>:0 
  at HarmonyLib.PatchClassProcessor.Patch () [0x00095] in <40a82cc9705b4865b72ee4c45165e7e9>:0 
  at HarmonyLib.Harmony.PatchAll (System.Type type) [0x00008] in <40a82cc9705b4865b72ee4c45165e7e9>:0 
  at HarmonyLib.Harmony.CreateAndPatchAll (System.Type type, System.String harmonyInstanceId) [0x0001e] in <40a82cc9705b4865b72ee4c45165e7e9>:0 
  at BepInEx.Preloader.RuntimeFixes.ConsoleSetOutFix.Apply () [0x0001f] in /home/runner/work/BepInEx/BepInEx/BepInEx.Preloader.Core/RuntimeFixes/ConsoleSetOutFix.cs:18 
  at BepInEx.Unity.Mono.Preloader.UnityPreloaderRunner.PreloaderMain () [0x00011] in /home/runner/work/BepInEx/BepInEx/Runtimes/Unity/BepInEx.Unity.Mono.Preloader/UnityPreloaderRunner.cs:64 
  at BepInEx.Unity.Mono.Preloader.UnityPreloaderRunner.PreloaderPreMain () [0x00047] in /home/runner/work/BepInEx/BepInEx/Runtimes/Unity/BepInEx.Unity.Mono.Preloader/UnityPreloaderRunner.cs:56 
  at (wrapper managed-to-native) System.Reflection.RuntimeMethodInfo.InternalInvoke(System.Reflection.RuntimeMethodInfo,object,object[],System.Exception&)
  at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0006a] in <fd2d3e9b010a4ba4b3fdc0456cd6b40b>:0 
   --- End of inner exception stack trace ---
  at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00083] in <fd2d3e9b010a4ba4b3fdc0456cd6b40b>:0 
  at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <fd2d3e9b010a4ba4b3fdc0456cd6b40b>:0 
  at Doorstop.Entrypoint.Start () [0x00034] in /home/runner/work/BepInEx/BepInEx/Runtimes/Unity/BepInEx.Unity.Mono.Preloader/DoorstopEntrypoint.cs:28