Harmony icon indicating copy to clipboard operation
Harmony copied to clipboard

FatalExecutionEngineError (0xc0000005) accessing event handler method from MarshalByRefObject

Open FailedShack opened this issue 4 years ago • 3 comments

Describe the bug The CLR crashes with an Access Violation exception whenever you try to access the event handler method from an object inheriting MarshalByRefObject after patching said method.

To Reproduce

  1. Patch the method you wish to register as an event handler.
  2. Create a class that inherits MarshalByRefObject and register the event handler.
  3. Attempt to access the Method property of the event.
using HarmonyLib;
using System;

static class Program
{
    [STAThread]
    static void Main()
    {
        var harmony = new Harmony("_");
        harmony.PatchAll();

        new TestClass().Run();
    }
}

[HarmonyPatch(typeof(TestClass), "Handler")]
class HandlerPatch
{
    static void Prefix() { }
}

class TestClass : MarshalByRefObject    // crashes
                                        //class TestClass    // works
{
    public delegate void TestEvent();
    public event TestEvent OnTestEvent;

    internal void Run()
    {
        OnTestEvent += Handler;
        var _ = OnTestEvent.Method;  // <=== "The runtime has encountered a fatal error. [...] 0xc0000005"
    }

    // patched with an empty prefix
    private void Handler() { }
}

Expected behavior The runtime doesn't crash, instead the Method property returns the MethodInfo of the registered handler.

Screenshots / Code crash

Runtime environment (please complete the following information):

  • OS: Windows 10, 64bit
  • .NET version: 4.7.2
  • Harmony version 2.0.0.9
  • Name of game or host application N/A

FailedShack avatar Apr 04 '20 22:04 FailedShack

Since there is no documentation on how the .NET runtime implements the glue code between managed methods and their jitted assembler code, special methods like certain types of generics and methods inheriting from MarshalByRefObject are not patchable.

pardeike avatar Apr 04 '20 22:04 pardeike

Should be fixed, at least the test I added recently did not crash

pardeike avatar Jan 06 '22 20:01 pardeike

Update: with more tests added, the pattern become more clear:

  • crashes only on x86
  • only for <= net48
  • only for the combination of MarshalByRefObject and adding a patched method to an event

pardeike avatar Jan 06 '22 21:01 pardeike

Probably obsolete or outdated. Closing it now

pardeike avatar Jun 17 '23 15:06 pardeike