Capgemini / Cauldron

C# Toolkit

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

IConstructorInterceptor causes assembly to fail verification (and won't run)

0x15e opened this issue · comments

Using package versions:

  • Fody: 3.2.4
  • Cauldron.Interception.Fody: 3.0.34 (and latest beta)
  • Cauldron.BasicInterceptors: 3.0.33 (and latest beta)

Attempting to build a .NET Framework console app for framework 4.7.2. There's nothing in the project but the necessary nuget packages for the interceptors, an attribute class, a class where it's applied, and Program.cs.

peverify /verbose produces the error:

Microsoft (R) .NET Framework PE Verifier.  Version  4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

[IL]: Error: [C:\Users\0x15e\source\repos\CauldronExeFailReproduction\CauldronExeFailReproduction\bin\Debug\CauldronExeFailReproduction.exe : CauldronExeFailReproduction.TestSubject::.ctor][mdToken=0x6000008][offset 0x0000006C][found ref 'Cauldron.Interception.IConstructorInterceptor'][expected ref 'System.Exception'] Unexpected type on the stack.
[IL]: Error: [C:\Users\0x15e\source\repos\CauldronExeFailReproduction\CauldronExeFailReproduction\bin\Debug\CauldronExeFailReproduction.exe : CauldronExeFailReproduction.TestSubject::.ctor][mdToken=0x6000008][offset 0x0000006C] Stack underflow.
2 Error(s) Verifying CauldronExeFailReproduction.exe

Attempting to run it anyway results in a System.InvalidProgramException: "Unhandled Exception: System.InvalidProgramException: Common Language Runtime detected an invalid program."

Here's the IL of the class where the interceptor is applied:

.class public auto ansi beforefieldinit CauldronExeFailReproduction.TestSubject
	extends [mscorlib]System.Object
{
	// Methods
	.method public hidebysig specialname rtspecialname 
		instance void .ctor (
			string someParam
		) cil managed 
	{
		// Method begins at RVA 0x20d4
		// Code size 115 (0x73)
		.maxstack 5
		.locals init (
			[0] object[],
			[1] class [Cauldron.Interception]Cauldron.Interception.IConstructorInterceptor,
			[2] class [mscorlib]System.Exception
		)

		// (no C# code)
		IL_0000: ldc.i4.1
		IL_0001: newarr [mscorlib]System.Object
		IL_0006: stloc.0
		IL_0007: ldloc.0
		IL_0008: ldc.i4.0
		// 	object[] values = new object[1]
		// 	{
		// 		someParam
		// 	};
		IL_0009: ldarg.1
		// (no C# code)
		IL_000a: stelem.ref
		// IConstructorInterceptor constructorInterceptor = new TestConstructorFailureAttribute();
		IL_000b: newobj instance void CauldronExeFailReproduction.TestConstructorFailureAttribute::.ctor()
		IL_0010: stloc.1
		// constructorInterceptor.OnBeforeInitialization(typeof(TestSubject), MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/, typeof(TestSubject).TypeHandle), values);
		IL_0011: ldloc.1
		IL_0012: ldtoken CauldronExeFailReproduction.TestSubject
		IL_0017: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
		IL_001c: ldtoken method instance void CauldronExeFailReproduction.TestSubject::.ctor(string)
		IL_0021: ldtoken CauldronExeFailReproduction.TestSubject
		IL_0026: call class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [mscorlib]System.RuntimeMethodHandle, valuetype [mscorlib]System.RuntimeTypeHandle)
		IL_002b: ldloc.0
		IL_002c: callvirt instance void [Cauldron.Interception]Cauldron.Interception.IConstructorInterceptor::OnBeforeInitialization(class [mscorlib]System.Type, class [mscorlib]System.Reflection.MethodBase, object[])
		// base..ctor();
		IL_0031: ldarg.0
		IL_0032: call instance void [mscorlib]System.Object::.ctor()
		.try
		{
			.try
			{
				// constructorInterceptor.OnEnter(typeof(TestSubject), this, MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/, typeof(TestSubject).TypeHandle), values);
				IL_0037: ldloc.1
				IL_0038: ldtoken CauldronExeFailReproduction.TestSubject
				IL_003d: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
				IL_0042: ldarg.0
				IL_0043: ldtoken method instance void CauldronExeFailReproduction.TestSubject::.ctor(string)
				IL_0048: ldtoken CauldronExeFailReproduction.TestSubject
				IL_004d: call class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [mscorlib]System.RuntimeMethodHandle, valuetype [mscorlib]System.RuntimeTypeHandle)
				IL_0052: ldloc.0
				IL_0053: callvirt instance void [Cauldron.Interception]Cauldron.Interception.IConstructorInterceptor::OnEnter(class [mscorlib]System.Type, object, class [mscorlib]System.Reflection.MethodBase, object[])
				// (no C# code)
				IL_0058: leave.s IL_0072
			} // end .try
			catch [mscorlib]System.Exception
			{
				IL_005a: stloc.2
				// if (constructorInterceptor.OnException(e))
				IL_005b: ldloc.1
				IL_005c: ldloc.2
				IL_005d: callvirt instance bool [Cauldron.Interception]Cauldron.Interception.IConstructorInterceptor::OnException(class [mscorlib]System.Exception)
				// (no C# code)
				IL_0062: ldc.i4.1
				IL_0063: ceq
				IL_0065: brfalse.s IL_0069

				IL_0067: rethrow

				IL_0069: leave.s IL_0072
			} // end handler
		} // end .try
		finally
		{
			// ((IConstructorInterceptor)/*Error near IL_006c: Stack underflow*/).OnException((Exception)constructorInterceptor);
			IL_006b: ldloc.1
			IL_006c: callvirt instance bool [Cauldron.Interception]Cauldron.Interception.IConstructorInterceptor::OnException(class [mscorlib]System.Exception)
			// (no C# code)
			IL_0071: endfinally
		} // end handler

		IL_0072: ret
	} // end of method TestSubject::.ctor

} // end of class CauldronExeFailReproduction.TestSubject

Does it have the same error in Release mode with optimization turned on?

I just checked and confirmed the same thing happens in Release with optimizations on (also regardless of platform target and bitness preference).

In case it helps anything, here are my msbuild and csc versions:

  • msbuild: 15.8.169+g1ccb72aefa
  • csc: 2.9.0.63208 (958f2354)

OK thanks… I'll look into this as soon as possible.

Fixed … Next version will have the fix...

Fantastic. I just built from source and confirmed everything's working on my end as well. Thanks!

Nuget packages are coming. I am unlisting older and merged packages.