none
CorExceptionFlag in CorHdr.h query RRS feed

  • Question

  • I am trying to create sample code (C#, F#, VB.NET) that will produce all the different exception clause types as defined by CorExceptionFlag in CorHdr.h.

    I am using C# and VB.NET for the first 3 but I can't work out how to arrange my code such that I can get the complier to generate exception clause sections using the types COR_ILEXCEPTION_CLAUSE_FAULT and COR_ILEXCEPTION_CLAUSE_DUPLICATED.

    Are you able to provide any snippets; the latter isn't even mentioned in ECMA335 (which I assume is the latest). 

    When reading these clauses is the ClassToken/FilterOffset field being used and if how would one interpret the value?

    Thanks

    Shaun

     

     

    Tuesday, May 10, 2011 10:26 AM

Answers

  • There are 4 kinds of handlers for protected blocks. A single protected block shall have exactly one handler associated with it:

     

    finally handler

    that shall be executed whenever the block exits, regardless of whether that occurs by normal control flow or by an unhandled exception.

    fault handler

    that shall be executed if an exception occurs, but not on completion of normal control flow.

    catch handler

    that handles any exception of a specified class or any of its sub-classes.

    filter handler

    that runs a user-specified set of CIL instructions to determine if the exception should be handled by the associated handler, or passed on to the next protected block.

     

    In C# language, we can use finally, catch, and filter (in VB.NET) handlers, for fault handler, as far as I know, it is only available in MSIL, by using fault/endfault instructions; you can dump IL of an assembly to an .il file (using ILDasm.exe), replace finally (endfinally) to fault (endfault), and then reassembly the .il file to an executable using ILAsm.exe, here is a sample of modified content of an .il file:

     

    .class private auto ansi beforefieldinit ConsoleApplication1.Program

           extends [mscorlib]System.Object

    {

      .method private hidebysig static void  Main(string[] args) cil managed

      {

        .entrypoint

        // Code size       49 (0x31)

        .maxstack  1

        .locals init ([0] int32 a,

                 [1] class [mscorlib]System.Exception e)

        IL_0000:  nop

        .try

        {

          .try

          {

            IL_0001:  nop

            IL_0002:  ldc.i4.0

            IL_0003:  stloc.0

            IL_0004:  nop

            IL_0005:  leave.s    IL_0018

     

          }  // end .try

          catch [mscorlib]System.Exception

          {

            IL_0007:  stloc.1

            IL_0008:  nop

            IL_0009:  ldloc.1

            IL_000a:  callvirt   instance string [mscorlib]System.Exception::get_Message()

            IL_000f:  call       void [mscorlib]System.Console::WriteLine(string)

            IL_0014:  nop

            IL_0015:  nop

            IL_0016:  leave.s    IL_0018

     

          }  // end handler

          IL_0018:  nop

          IL_0019:  leave.s    IL_0029

     

        }  // end .try

        fault

        {

          IL_001b:  nop

          IL_001c:  ldstr      "done"

          IL_0021:  call       void [mscorlib]System.Console::WriteLine(string)

          IL_0026:  nop

          IL_0027:  nop

          IL_0028:  endfault

        }  // end handler

        IL_0029:  nop

        IL_002a:  call       string [mscorlib]System.Console::ReadLine()

        IL_002f:  pop

        IL_0030:  ret

      } // end of method Program::Main

     

      .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 Program::.ctor

     

    } // end of class ConsoleApplication1.Program

     

     

    The CorExceptionFlag is defined as:

     

    typedef enum CorExceptionFlag                       // defintitions for the Flags field below (for both big and small)

    {

        COR_ILEXCEPTION_CLAUSE_NONE,                    // This is a typed handler

        COR_ILEXCEPTION_CLAUSE_OFFSETLEN = 0x0000,      // Deprecated

        COR_ILEXCEPTION_CLAUSE_DEPRECATED = 0x0000,     // Deprecated

        COR_ILEXCEPTION_CLAUSE_FILTER  = 0x0001,        // If this bit is on, then this EH entry is for a filter

        COR_ILEXCEPTION_CLAUSE_FINALLY = 0x0002,        // This clause is a finally clause

        COR_ILEXCEPTION_CLAUSE_FAULT = 0x0004,          // Fault clause (finally that is called on exception only)

        COR_ILEXCEPTION_CLAUSE_DUPLICATED = 0x0008,     // duplicated clase..  this clause was duplicated down to a funclet which was pulled out of line

    } CorExceptionFlag;

     

    One thing we can sure is: COR_ILEXCEPTION_CLAUSE_NONE, COR_ILEXCEPTION_CLAUSE_FILTER, COR_ILEXCEPTION_CLAUSE_FINALLY and COR_ILEXCEPTION_CLAUSE_FAULT have covered all the 4 handler types, COR_ILEXCEPTION_CLAUSE_DUPLICATED is not corresponding to a real clause, although I have no idea what does it used for.

     

    See also: ECMA C# and Common Language Infrastructure Standards

               MS Partition I.pdf

    815 983

    Common Language Infrastructure, Partition I: Concepts and Architecture (Page 94 : Exception Handling)

    MS Partition II.pdf

    1 758 195

    Common Language Infrastructure, Partition II: Metadata Definition and Semantics (Page 114: Exception Handling)


    Eric Yang [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    • Marked as answer by Shaun Wilde Friday, May 13, 2011 4:07 AM
    • Unmarked as answer by Shaun Wilde Friday, May 13, 2011 4:15 AM
    • Marked as answer by Shaun Wilde Monday, May 16, 2011 9:02 AM
    Thursday, May 12, 2011 2:43 AM

All replies

  • There are 4 kinds of handlers for protected blocks. A single protected block shall have exactly one handler associated with it:

     

    finally handler

    that shall be executed whenever the block exits, regardless of whether that occurs by normal control flow or by an unhandled exception.

    fault handler

    that shall be executed if an exception occurs, but not on completion of normal control flow.

    catch handler

    that handles any exception of a specified class or any of its sub-classes.

    filter handler

    that runs a user-specified set of CIL instructions to determine if the exception should be handled by the associated handler, or passed on to the next protected block.

     

    In C# language, we can use finally, catch, and filter (in VB.NET) handlers, for fault handler, as far as I know, it is only available in MSIL, by using fault/endfault instructions; you can dump IL of an assembly to an .il file (using ILDasm.exe), replace finally (endfinally) to fault (endfault), and then reassembly the .il file to an executable using ILAsm.exe, here is a sample of modified content of an .il file:

     

    .class private auto ansi beforefieldinit ConsoleApplication1.Program

           extends [mscorlib]System.Object

    {

      .method private hidebysig static void  Main(string[] args) cil managed

      {

        .entrypoint

        // Code size       49 (0x31)

        .maxstack  1

        .locals init ([0] int32 a,

                 [1] class [mscorlib]System.Exception e)

        IL_0000:  nop

        .try

        {

          .try

          {

            IL_0001:  nop

            IL_0002:  ldc.i4.0

            IL_0003:  stloc.0

            IL_0004:  nop

            IL_0005:  leave.s    IL_0018

     

          }  // end .try

          catch [mscorlib]System.Exception

          {

            IL_0007:  stloc.1

            IL_0008:  nop

            IL_0009:  ldloc.1

            IL_000a:  callvirt   instance string [mscorlib]System.Exception::get_Message()

            IL_000f:  call       void [mscorlib]System.Console::WriteLine(string)

            IL_0014:  nop

            IL_0015:  nop

            IL_0016:  leave.s    IL_0018

     

          }  // end handler

          IL_0018:  nop

          IL_0019:  leave.s    IL_0029

     

        }  // end .try

        fault

        {

          IL_001b:  nop

          IL_001c:  ldstr      "done"

          IL_0021:  call       void [mscorlib]System.Console::WriteLine(string)

          IL_0026:  nop

          IL_0027:  nop

          IL_0028:  endfault

        }  // end handler

        IL_0029:  nop

        IL_002a:  call       string [mscorlib]System.Console::ReadLine()

        IL_002f:  pop

        IL_0030:  ret

      } // end of method Program::Main

     

      .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 Program::.ctor

     

    } // end of class ConsoleApplication1.Program

     

     

    The CorExceptionFlag is defined as:

     

    typedef enum CorExceptionFlag                       // defintitions for the Flags field below (for both big and small)

    {

        COR_ILEXCEPTION_CLAUSE_NONE,                    // This is a typed handler

        COR_ILEXCEPTION_CLAUSE_OFFSETLEN = 0x0000,      // Deprecated

        COR_ILEXCEPTION_CLAUSE_DEPRECATED = 0x0000,     // Deprecated

        COR_ILEXCEPTION_CLAUSE_FILTER  = 0x0001,        // If this bit is on, then this EH entry is for a filter

        COR_ILEXCEPTION_CLAUSE_FINALLY = 0x0002,        // This clause is a finally clause

        COR_ILEXCEPTION_CLAUSE_FAULT = 0x0004,          // Fault clause (finally that is called on exception only)

        COR_ILEXCEPTION_CLAUSE_DUPLICATED = 0x0008,     // duplicated clase..  this clause was duplicated down to a funclet which was pulled out of line

    } CorExceptionFlag;

     

    One thing we can sure is: COR_ILEXCEPTION_CLAUSE_NONE, COR_ILEXCEPTION_CLAUSE_FILTER, COR_ILEXCEPTION_CLAUSE_FINALLY and COR_ILEXCEPTION_CLAUSE_FAULT have covered all the 4 handler types, COR_ILEXCEPTION_CLAUSE_DUPLICATED is not corresponding to a real clause, although I have no idea what does it used for.

     

    See also: ECMA C# and Common Language Infrastructure Standards

               MS Partition I.pdf

    815 983

    Common Language Infrastructure, Partition I: Concepts and Architecture (Page 94 : Exception Handling)

    MS Partition II.pdf

    1 758 195

    Common Language Infrastructure, Partition II: Metadata Definition and Semantics (Page 114: Exception Handling)


    Eric Yang [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    • Marked as answer by Shaun Wilde Friday, May 13, 2011 4:07 AM
    • Unmarked as answer by Shaun Wilde Friday, May 13, 2011 4:15 AM
    • Marked as answer by Shaun Wilde Monday, May 16, 2011 9:02 AM
    Thursday, May 12, 2011 2:43 AM
  • Eric 

    thanks - I knew I could use IL I was wondering just wondering if one of the higher level languages could do it.

    I have since read that it may be possible using the C++ compiler (http://bartdesmet.net/blogs/bart/archive/2006/04/04/clr-exception-handling-from-a-to-z-everything-you-didn-t-want-to-know-about-try-catch-finally-fault-filter.aspx) but not sure how to replicate that at the moment.

    I'd be interested if anyone knows more about the COR_ILEXCEPTION_CLAUSE_DUPLICATED  F# related perhaps? Maybe one of the other IL languages e.g. IronRuby

    Friday, May 13, 2011 4:19 AM