Skip to content

Instantly share code, notes, and snippets.

@pardeike
Created March 26, 2024 22:41
Show Gist options
  • Save pardeike/b7121a986e9613c1241899fbc0fb139f to your computer and use it in GitHub Desktop.
Save pardeike/b7121a986e9613c1241899fbc0fb139f to your computer and use it in GitHub Desktop.
Multiple Finalizers seems broken
void Main()
{
var harmony = new Harmony("test");
Harmony.DEBUG = true;
harmony.PatchAll();
Class.Test();
}
[HarmonyPriority(Priority.High)]
[HarmonyPatch(typeof(Class), nameof(Class.Test))]
static class Patch1
{
static Exception Finalizer(Exception __exception)
{
Console.WriteLine("Finalizer1");
return new Exception("E2");
}
}
[HarmonyPriority(Priority.Low)]
[HarmonyPatch(typeof(Class), nameof(Class.Test))]
static class Patch2
{
static Exception Finalizer(Exception __exception)
{
Console.WriteLine("Finalizer2");
return new Exception("E3");
}
}
static class Class
{
public static void Test()
{
Console.WriteLine("Test");
throw new Exception("E1");
}
}
/* result after first patch
### Patch: static System.Void Class::Test()
### Replacement: static System.Void UserQuery+Class::UserQuery+Class.Test_Patch1()
IL_0000: Local var 0: System.Boolean
IL_0000: Local var 1: System.Exception
IL_0000: ldc.i4 0
IL_0005: stloc 0 (System.Boolean)
IL_0009: ldnull
IL_000A: stloc 1 (System.Exception)
.try
{
IL_000E: // start original
IL_000E: ldstr "Test"
IL_0013: call static System.Void System.Console::WriteLine(System.String value)
IL_0018: ldstr "E1"
IL_001D: newobj System.Void System.Exception::.ctor(System.String message)
IL_0022: throw
IL_0023: // end original (has dead code end)
IL_0023: ldloc 1 (System.Exception)
IL_0027: call static System.Exception Patch1::Finalizer(System.Exception __exception)
IL_002C: stloc 1 (System.Exception)
IL_0030: ldc.i4.1
IL_0031: stloc 0 (System.Boolean)
IL_0035: ldloc 1 (System.Exception)
IL_0039: brfalse => Label2
IL_003E: ldloc 1 (System.Exception)
IL_0042: throw
IL_0043: Label2
IL_0043: leave => (autogenerated)
} // end try
.catch System.Object
{
IL_0048: stloc 1 (System.Exception)
IL_004C: ldloc 0 (System.Boolean)
IL_0050: brtrue => Label5
.try
{
IL_0055: ldloc 1 (System.Exception)
IL_0059: call static System.Exception Patch1::Finalizer(System.Exception __exception)
IL_005E: stloc 1 (System.Exception)
IL_0062: leave => (autogenerated)
} // end try
.catch System.Object
{
IL_0067: pop
IL_0068: leave => (autogenerated)
} // end handler
IL_006D: Label5
IL_006D: ldloc 1 (System.Exception)
IL_0071: brfalse => Label10
IL_0076: ldloc 1 (System.Exception)
IL_007A: throw
IL_007B: Label10
IL_007B: leave => (autogenerated)
} // end handler
IL_0080: ret
DONE
*/
/* result after second patch
### Patch: static System.Void Class::Test()
### Replacement: static System.Void UserQuery+Class::UserQuery+Class.Test_Patch2()
IL_0000: Local var 0: System.Boolean
IL_0000: Local var 1: System.Exception
IL_0000: ldc.i4 0
IL_0005: stloc 0 (System.Boolean)
IL_0009: ldnull
IL_000A: stloc 1 (System.Exception)
.try
{
IL_000E: // start original
IL_000E: ldstr "Test"
IL_0013: call static System.Void System.Console::WriteLine(System.String value)
IL_0018: ldstr "E1"
IL_001D: newobj System.Void System.Exception::.ctor(System.String message)
IL_0022: throw
IL_0023: // end original (has dead code end)
IL_0023: ldloc 1 (System.Exception)
IL_0027: call static System.Exception Patch1::Finalizer(System.Exception __exception)
IL_002C: stloc 1 (System.Exception)
IL_0030: ldloc 1 (System.Exception)
IL_0034: call static System.Exception Patch2::Finalizer(System.Exception __exception)
IL_0039: stloc 1 (System.Exception)
IL_003D: ldc.i4.1
IL_003E: stloc 0 (System.Boolean)
IL_0042: ldloc 1 (System.Exception)
IL_0046: brfalse => Label2
IL_004B: ldloc 1 (System.Exception)
IL_004F: throw
IL_0050: Label2
IL_0050: leave => (autogenerated)
} // end try
.catch System.Object
{
IL_0055: stloc 1 (System.Exception)
IL_0059: ldloc 0 (System.Boolean)
IL_005D: brtrue => Label5
.try
{
IL_0062: ldloc 1 (System.Exception)
IL_0066: call static System.Exception Patch1::Finalizer(System.Exception __exception)
IL_006B: stloc 1 (System.Exception)
IL_006F: leave => (autogenerated)
} // end try
.catch System.Object
{
IL_0074: pop
IL_0075: leave => (autogenerated)
} // end handler
.try
{
IL_007A: ldloc 1 (System.Exception)
IL_007E: call static System.Exception Patch2::Finalizer(System.Exception __exception)
IL_0083: stloc 1 (System.Exception)
IL_0087: leave => (autogenerated)
} // end try
.catch System.Object
{
IL_008C: pop
IL_008D: leave => (autogenerated)
} // end handler
IL_0092: Label5
IL_0092: ldloc 1 (System.Exception)
IL_0096: brfalse => Label14
IL_009B: ldloc 1 (System.Exception)
IL_009F: throw
IL_00A0: Label14
IL_00A0: leave => (autogenerated)
} // end handler
IL_00A5: ret
DONE
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment