Bad IL format, no errors from the host

Apr 28, 2010 at 3:38 PM

Hello.

I'm getting this exception from a type (MyClass) I generated with CCI/Metadata+Code

System.Windows.Data Error: 17 : Cannot get 'Name' value (type 'String') from '' (type 'MyClass'). BindingExpression:Path=Name; DataItem='MyClass
' (HashCode=32076356); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

TargetInvocationException:'System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.BadImageFormatException: Bad IL format. 

 at MyClass.get_InstanceAsXYZ() 

  at MyClass.get_Name()

  --- End of inner exception stack trace ---   at System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeType typeOwner)   at System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeType typeOwner)   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)   at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)   at MS.Internal.Data.PropertyPathWorker.GetValue(Object item, Int32 level)   at MS.Internal.Data.PropertyPathWorker.RawValue(Int32 k)'

 

I can open the assembly in Reflector and disassemble it as both IL and C# and I don't see anything wrong.

Usually Reflector is quite picky and throws exception when it encounters malformed IL.

MyClass.get_InstanceAsXYZ() is an abstract method that is implemented in a subclass (always generated with CCI).

Apr 28, 2010 at 9:59 PM

Please, help me with this. I got stuck.

 

Why is an abstract method called with call? Shouldn't it be called with callvirt? CCI generates a call opcode. I don't know if it's related to my main problem.

 

Coordinator
Apr 28, 2010 at 10:28 PM

I'm on vacation in South Africa with very little internet access right now, so please forgive my tardy response.

CCI should not call an abstract method with call. Could you please illustrate this with a small example so that I can debug and fix this?

It will be late next week at the earliest, I'm afraid.

Apr 28, 2010 at 11:58 PM

Thanks for your answer, herman!

This is why I'm saying I think there is such a problem:

This is defined in the same class Alpha_Wrapper

An abstract InstanceAsAlpha property:


C#/Reflector:

public abstract Alpha InstanceAsAlpha { get; }

 IL/Reflector:

.property instance specialname rtspecialname class [PerPlexEd.LC]PerPlexEd.LC.Alpha InstanceAsAlpha{    .get instance class [PerPlexEd.LC]PerPlexEd.LC.Alpha Alpha_Wrapper:get_InstanceAsAlpha()}


C#/Reflector:

public abstract Alpha get_InstanceAsAlpha();

 IL/Reflector:

.method public hidebysig specialname newslot abstract virtual instance class [PerPlexEd.LC]PerPlexEd.LC.Alpha get_InstanceAsAlpha() cil managed{}

An explicit IWrapper<Alpha>.Instance implementation based on the previous property:

C#/Reflector:

Alpha IWrapper<Alpha>.Instance{    get    {        return this.InstanceAsAlpha;    }}

IL/Reflector:.property class class [PerPlexEd.LC]PerPlexEd.LC.Alpha PerPlexEd.MP.IWrapper<PerPlexEd.LC.Alpha>.Instance{    .get instance class [PerPlexEd.LC]PerPlexEd.LC.Alpha Alpha_Wrapper:PerPlexEd.MP.IWrapper<PerPlexEd.LC.Alpha>.get_Instance()}


C#/Reflector:

Alpha IWrapper<Alpha>.get_Instance(){    return this.InstanceAsAlpha;}

IL/Reflector:

.method private hidebysig virtual instance class [PerPlexEd.LC]PerPlexEd.LC.Alpha PerPlexEd.MP.IWrapper<PerPlexEd.LC.Alpha>.get_Instance() cil managed{    .override [PerPlexEd.MP]PerPlexEd.MP.IWrapper`1<class [PerPlexEd.LC]PerPlexEd.LC.Alpha>::get_Instance    .maxstack 8    L_0000: ldarg.0     L_0001: call instance class [PerPlexEd.LC]PerPlexEd.LC.Alpha Alpha_Wrapper:get_InstanceAsAlpha()    L_0006: ret }
 
 

I'll try to create a test.

Apr 30, 2010 at 3:05 PM

I discovered that MethodCall has a IsVirtualCall property to force the use of callvirt and this fixes my problem.

I checked and I'm sure that the method (a property getter) that I'm calling has IsAbstract = true and IsVirtual = true but I only get a callvirt opcode if I set IsVirtualCall explicitly.