[Mono-dev] Re: Abort with Non-Typical Exception Handler Layout on Mono 1.1.13.6

Almann T. Goo almann.goo at gmail.com
Sun Jun 11 20:29:49 EDT 2006


On 6/12/06, Robert Jordan <robertj at gmx.net> wrote:
>
> Maybe the code doesn't pass verification. Test the assembly with pedump
> or MS.NET's PEVerify.
>

I ran this with PEVerify and got a couple of errors (I had changed the name
of the assembly so I wouldn't get confused with my other example cases):

Microsoft (R) .NET Framework PE Verifier  Version 1.1.4322.573
Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.

[IL]: Error: [d:\tmp\cs\middle.exe : Middle::Main] [exception #0x00000000]
Lexical nesting.
[IL]: Error: [d:\tmp\cs\middle.exe : Middle::Main] [offset 0x00000000]
fallthru the end of an exception block
2 Errors Verifying middle.exe

On closer inspection of ECMA-335, the reason for the first error was that my
previous code violates 12.4.2.7 of Partition I.  Specifically, the paragraph
regarding lexical nesting of protected blocks.  The reason for the second
error is a control fall through violation by the nop (that is unreachable in
my example), this violates 12.4.2.8.1 of Partition I which states that "exit
from a protected block cannot be accomplished via fall through."  Even
though the nop is unreachable, this is incorrect IL--easy to fix with a
leave that is still unreachable.

Based on that, I have re-formulated my examples and managed to get PEVerify
passable examples that still abort in Mono 1.1.13.6.

D:\tmp\cs>peverify sample.exe

Microsoft (R) .NET Framework PE Verifier  Version 1.1.4322.573
Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.

All Classes and Methods in sample.exe Verified

D:\tmp\cs>peverify sample2.exe

Microsoft (R) .NET Framework PE Verifier  Version 1.1.4322.573
Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.

All Classes and Methods in sample2.exe Verified

D:\tmp\cs>sample.exe
Start
Finally1
Finally2

D:\tmp\cs>sample2.exe
Start
Finally1

In Mono the following happens (same as with the original example):

$ mono sample2.exe

** ERROR **: file mini.c: line 9517 (mini_method_compile): assertion failed:
(tblock->native_offset)
aborting...
Aborted

$ mono sample.exe

** ERROR **: file mini.c: line 9517 (mini_method_compile): assertion failed:
(tblock->native_offset)
aborting...
Aborted

I have attached two CIL assembly source files that compile to the examples
used above.  They pass PEVerify and abort in Mono--I believe these two
examples are compliant to the ECMA-335 specification.

Best regards,
Almann

-- 
Almann T. Goo
almann.goo at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-devel-list/attachments/20060612/8bb5df1a/attachment.html 
-------------- next part --------------
.assembly extern mscorlib {
    .ver 1:0:5000:0
}
.assembly sample2
{
    .ver  0:0:0:0
}
.module sample2.exe

.class public auto ansi beforefieldinit Sample
{
  .method public hidebysig static void Main(string[] args) cil managed
  {
    .entrypoint
    .maxstack  8

    T_START:
        ldstr   "Start"
        call    void [mscorlib]System.Console::WriteLine(string)
        leave.s COMPLETE
    T1_END:

    COMPLETE:
        ret

    F1_START:
        ldstr   "Finally1"
        call    void [mscorlib]System.Console::WriteLine(string)
        endfinally
    F1_END:

    .try T_START to T1_END finally handler F1_START to F1_END

  }
}
-------------- next part --------------
.assembly extern mscorlib {
    .ver 1:0:5000:0
}
.assembly sample
{
    .ver  0:0:0:0
}
.module sample.exe

.class public auto ansi beforefieldinit Sample
{
  .method public hidebysig static void Main(string[] args) cil managed
  {
    .entrypoint
    .maxstack  8

    T_START:
        ldstr   "Start"
        call    void [mscorlib]System.Console::WriteLine(string)
        leave.s COMPLETE
    T1_END:
    F1_START:
        ldstr   "Finally1"
        call    void [mscorlib]System.Console::WriteLine(string)
        endfinally
    F1_END:
        leave.s COMPLETE
    T2_END:

    COMPLETE:
        ret

    F2_START:
        ldstr   "Finally2"
        call    void [mscorlib]System.Console::WriteLine(string)
        endfinally
    F2_END:

    .try T_START to T1_END finally handler F1_START to F1_END
    .try T_START to T2_END finally handler F2_START to F2_END

  }
}


More information about the Mono-devel-list mailing list