Interesting case you've found there. I could reproduce the crash when
opening that assembly in ILSpy.
That seems to be a bug in the Microsoft C# compiler - PEVerify doesn't
like the assembly either:
[IL]: Error: [C:\temp\AssemblyToTest\bin\Debug\AssemblyToTest.dll :
ListViewModel::<>n__FabricatedMethod1]  [HRESULT 0x8007000B] - An
attempt was made to load a program with an incorrect format.
[IL]: Error: [C:\temp\AssemblyToTest\bin\Debug\AssemblyToTest.dll :
ListViewModel::<>n__FabricatedMethod2]  [HRESULT 0x8007000B] - An
attempt was made to load a program with an incorrect format.
[IL]: Error: [C:\temp\AssemblyToTest\bin\Debug\AssemblyToTest.dll :
ListViewModel::<DoSomething>b__0]  [HRESULT 0x8007000B] - An attempt was
made to load a program with an incorrect format.

.NET can execute the DoSomething() method just fine as long as the
delegate is not being called.
Only if I add an "action();" call, I get a BadImageFormatException.

This bug report seems to describe the problem:
https://connect.microsoft.com/VisualStudio/feedback/details/626550/badimageformatexception-on-simple-program-using-generics-and-lambdas.

ILDasm can disassemble the assembly successfully and produces the
attached result. The problem seems to be that the fabricated methods
refer to a type parameter that is not in scope.
AFAIK fabricated methods are a workaround for accessing protected
members from lambdas that get compiled into a separate closure class;
and are highly redundant in this case (the property is not protected,
and the lambda does not use a closure class).

I'm not sure how this invalid assembly could be represented in the Cecil
object model - maybe create a fake GenericParameter, or introduce an
UnknownTypeReference?
In any case, such an error should not cause a crash on a task as simple
as listing the methods that are available.

Daniel

On 7/20/2011 11:47, Simon wrote:
> If I put this in an assembly
>
>
> public class BaseListViewModel<T>
> {
>     public virtual T SelectedItem { get; set; }
> }
> public class ListViewModel : BaseListViewModel<object>
> {
>     public void DoSomething()
>     {
>         Action action = () =>
>         {
>             var x = base.SelectedItem;
>         };
>     }
> }
>
> And try to iterate through all the methods it I get
>
> System.ArgumentOutOfRangeException was unhandled
>   Message=Specified argument was out of the range of valid values.
>   Source=Mono.Cecil
>   StackTrace:
>        at
> Mono.Cecil.SignatureReader.GetGenericParameter(GenericParameterType
> type, UInt32 var)
>        at Mono.Cecil.SignatureReader.ReadTypeSignature(ElementType etype)
>        at
> Mono.Cecil.SignatureReader.ReadMethodSignature(IMethodSignature method)
>        at Mono.Cecil.MetadataReader.ReadMethod(UInt32 method_rid,
> Collection`1 methods)
>        at Mono.Cecil.MetadataReader.ReadMethods(TypeDefinition type)
>        at Mono.Cecil.TypeDefinition.get_Methods()
>        at CecilTest.Program.Main(String[] args) in
> D:\Code\CecilTest\CecilTest\Class1.cs:line 16
>        at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly,
> String[] args)
>        at
> Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
>        at System.Threading.ExecutionContext.Run(ExecutionContext
> executionContext, ContextCallback callback, Object state, Boolean
> ignoreSyncCtx)
>        at System.Threading.ExecutionContext.Run(ExecutionContext
> executionContext, ContextCallback callback, Object state)
>        at System.Threading.ThreadHelper.ThreadStart()
>   InnerException:
>
>
> Am I missing something here?
>
> Attached is a repo
> -- 
> --
> mono-cecil 

//  Microsoft (R) .NET Framework IL Disassembler.  Version 4.0.30319.1
//  Copyright (c) Microsoft Corporation.  All rights reserved.



// Metadata version: v4.0.30319
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // 
.z\V.4..
  .ver 4:0:0:0
}
.assembly AssemblyToTest
{
  .custom instance void 
[mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor()
 = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx
                                                                                
                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       
// ceptionThrows.
  .custom instance void 
[mscorlib]System.Runtime.Versioning.TargetFrameworkAttribute::.ctor(string) = ( 
01 00 1A 2E 4E 45 54 46 72 61 6D 65 77 6F 72 6B   // ....NETFramework
                                                                                
                        2C 56 65 72 73 69 6F 6E 3D 76 34 2E 30 01 00 54   // 
,Version=v4.0..T
                                                                                
                        0E 14 46 72 61 6D 65 77 6F 72 6B 44 69 73 70 6C   // 
..FrameworkDispl
                                                                                
                        61 79 4E 61 6D 65 10 2E 4E 45 54 20 46 72 61 6D   // 
ayName..NET Fram
                                                                                
                        65 77 6F 72 6B 20 34 )                            // 
ework 4

  // --- The following custom attribute is added automatically, do not 
uncomment -------
  //  .custom instance void 
[mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype 
[mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 
01 00 00 00 00 ) 

  .custom instance void 
[mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32)
 = ( 01 00 08 00 00 00 00 00 ) 
  .hash algorithm 0x00008004
  .ver 0:0:0:0
}
.module AssemblyToTest.dll
// MVID: {62B038F8-EF5F-4051-9CE0-5219EE6925E8}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003       // WINDOWS_CUI
.corflags 0x00000001    //  ILONLY
// Image base: 0x00260000


// =============== CLASS MEMBERS DECLARATION ===================

.class public auto ansi beforefieldinit BaseListViewModel`1<T>
       extends [mscorlib]System.Object
{
  .field private !T '<SelectedItem>k__BackingField'
  .custom instance void 
[mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = 
( 01 00 00 00 ) 
  .method public hidebysig newslot specialname virtual 
          instance !T  get_SelectedItem() cil managed
  {
    .custom instance void 
[mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = 
( 01 00 00 00 ) 
    // Code size       11 (0xb)
    .maxstack  1
    .locals init (!T V_0)
    IL_0000:  ldarg.0
    IL_0001:  ldfld      !0 class 
BaseListViewModel`1<!T>::'<SelectedItem>k__BackingField'
    IL_0006:  stloc.0
    IL_0007:  br.s       IL_0009

    IL_0009:  ldloc.0
    IL_000a:  ret
  } // end of method BaseListViewModel`1::get_SelectedItem

  .method public hidebysig newslot specialname virtual 
          instance void  set_SelectedItem(!T 'value') cil managed
  {
    .custom instance void 
[mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = 
( 01 00 00 00 ) 
    // Code size       8 (0x8)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  ldarg.1
    IL_0002:  stfld      !0 class 
BaseListViewModel`1<!T>::'<SelectedItem>k__BackingField'
    IL_0007:  ret
  } // end of method BaseListViewModel`1::set_SelectedItem

  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    // Code size       7 (0x7)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
    IL_0006:  ret
  } // end of method BaseListViewModel`1::.ctor

  .property instance !T SelectedItem()
  {
    .get instance !T BaseListViewModel`1::get_SelectedItem()
    .set instance void BaseListViewModel`1::set_SelectedItem(!T)
  } // end of property BaseListViewModel`1::SelectedItem
} // end of class BaseListViewModel`1

.class public auto ansi beforefieldinit ListViewModel
       extends class BaseListViewModel`1<object>
{
  .method public hidebysig instance void 
          DoSomething() cil managed
  {
    // Code size       15 (0xf)
    .maxstack  3
    .locals init ([0] class [mscorlib]System.Action action)
    IL_0000:  nop
    IL_0001:  ldarg.0
    IL_0002:  ldftn      instance void ListViewModel::'<DoSomething>b__0'()
    IL_0008:  newobj     instance void [mscorlib]System.Action::.ctor(object,
                                                                      native 
int)
    IL_000d:  stloc.0
    IL_000e:  ret
  } // end of method ListViewModel::DoSomething

  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    // Code size       7 (0x7)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  call       instance void class 
BaseListViewModel`1<object>::.ctor()
    IL_0006:  ret
  } // end of method ListViewModel::.ctor

  .method private hidebysig instance !0  '<>n__FabricatedMethod1'() cil managed
  {
    .custom instance void 
[mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = 
( 01 00 00 00 ) 
    // Code size       11 (0xb)
    .maxstack  1
    .locals init (!0 V_0)
    IL_0000:  ldarg.0
    IL_0001:  call       instance !0 class 
BaseListViewModel`1<object>::get_SelectedItem()
    IL_0006:  stloc.0
    IL_0007:  br.s       IL_0009

    IL_0009:  ldloc.0
    IL_000a:  ret
  } // end of method ListViewModel::'<>n__FabricatedMethod1'

  .method private hidebysig instance void 
          '<>n__FabricatedMethod2'(!0 A_1) cil managed
  {
    .custom instance void 
[mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = 
( 01 00 00 00 ) 
    // Code size       8 (0x8)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  ldarg.1
    IL_0002:  call       instance void class 
BaseListViewModel`1<object>::set_SelectedItem(!0)
    IL_0007:  ret
  } // end of method ListViewModel::'<>n__FabricatedMethod2'

  .method private hidebysig instance void 
          '<DoSomething>b__0'() cil managed
  {
    .custom instance void 
[mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = 
( 01 00 00 00 ) 
    // Code size       9 (0x9)
    .maxstack  1
    .locals init ([0] object x)
    IL_0000:  nop
    IL_0001:  ldarg.0
    IL_0002:  call       instance !0 ListViewModel::'<>n__FabricatedMethod1'()
    IL_0007:  stloc.0
    IL_0008:  ret
  } // end of method ListViewModel::'<DoSomething>b__0'

} // end of class ListViewModel


// =============================================================

// *********** DISASSEMBLY COMPLETE ***********************
// WARNING: Created Win32 resource file out.res

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to