18 Exception Handling


In the CLI, a method may define a range of CIL instructions that are said to be protected. This is called the "try block." It can then associate one or more handlers with that try block. If an exception occurs during execution anywhere within the try block, an exception object is created that describes the problem. The CIL then takes over, transferring control from the point at which the exception was thrown, to the block of code that is willing to handle that exception. See Partition I.

ANNOTATION

Pertinent information on exception handling can be found in Partition I, section 12.4.2 and its subsections. Take particular notice of the following sections:

12.4.2.4 Timing of Exceptions

12.4.2.5 Overview of Exception Handling

12.4.2.7 Lexical Nesting of Protected Blocks

12.4.2.8 Control Flow Restrictions on Protected Blocks


<sehBlock> ::=

 

<tryBlock> <sehClause> [<sehClause>*]

The next few sections expand upon this simple description, by describing the five kinds of code blocks that take part in exception processing: try, catch, filter, finally, and fault. (Note that there are restrictions upon how many, and what kinds of <sehClause> a given <tryBlock> may have; see Partition I, section 12.4.2 for details.)

The remaining syntax items are described in detail below; they are collected here for reference.

<tryBlock> ::=

Description

.try <label> to <label>

Protect region from first label to prior to second.

| .try <scopeBlock>

<scopeBlock> is protected.

<sehClause> ::=

Description

 

catch <typeReference> <handlerBlock>

Catch all objects of the specified type.

| fault <handlerBlock>

Handle all exceptions but not normal exit.

| filter <label> <handlerBlock>

Enter handler only if filter succeeds.

| finally <handlerBlock>

Handle all exceptions and normal exit.

<handlerBlock> ::=

Description

handler <label> to <label>

Handler range is from first label to prior to second.

| <scopeBlock>

<scopeBlock> is the handler block.

ANNOTATION

The stack trace is created at the time the exception is thrown. This is in contrast to Java, where the stack trace is created during the constructioin of the exception object, and not modified when the exception is thrown. When implementing the Java language on top of the CLI, one must therefore take care. This difference is not always apparent, because typically the exception object is created and immediately thrown, so there is no difference in the stack trace. However, when the exception object is created in one method and thrown in another, the difference will be visible to the program that prints the stack trace for that exception.


18.1 Protected Blocks

A try, or protected, or guarded, block is declared with the .try directive.

<tryBlock> ::=

Description

.try <label> to <label>

Protect region from first label to prior to second.

| .try <scopeBlock>

<scopeBlock> is protected.

In the first, the protected block is delimited by two labels. The first label is the first instruction to be protected, while the second label is the instruction just beyond the last one to be protected. Both labels shall be defined prior to this point.

The second uses a scope block (see Partition II, section 14.4.4) after the .try directive the instructions within that scope are the ones to be protected.

18.2 Handler Blocks

<handlerBlock> ::=

Description

| handler <label> to <label>

Handler range is from first label to prior to second.

| <scopeBlock>

<scopeBlock> is the handler block.

In the first syntax, the labels enclose the instructions of the handler block, the first label being the first instruction of the handler while the second is the instruction immediately after the handler. Alternatively, the handler block is just a scope block.

ANNOTATION

Implementation-Specific (Microsoft): The Microsoft ilasm requires labels used to specify any exception blocks to be defined beforehand in the source. It also supports the following additional syntax for use in round-tripping:

 
 <handlerBlock> ::= handler <int32> to <int32> 


18.3 atch [Blocks]

A catch block is declared using the catch keyword. This specifies the type of exception object the clause is designed to handle, and the handler code itself.

<sehClause> ::=

 

catch <typeReference> <handlerBlock>

 
 Example (informative): .try {      ...                           // protected instructions      leave   exitSEH               // normal exit } catch [mscorlib]System.FormatException {      ...                           // handle the exception      pop                           // pop the exception object      leave   exitSEH               // leave catch handler } exitSEH:                           // continue here 

18.4 Filter [Blocks]

A filter block is declared using the filter keyword.

<sehClause> ::= ...

| filter <label> <handlerBlock>

| filter <scope> <handlerBlock>

The filter code begins at the specified label and ends at the first instruction of the handler block. (Note that the CLI demands that the filter block shall immediately precede, within the CIL stream, its corresponding handler block.)

 
 Example (informative): .method public static void m () {     .try {       ...                          // protected instructions       leave                        exitSEH        // normal exit     }     filter {       ...                         // decide whether to handle       pop                         // pop exception object       ldc.i4.1                    // EXCEPTION_EXECUTE_HANDLER       endfilter                     // return answer to CLI     }     {       ...                           // handle the exception       pop                           // pop the exception object       leave               exitSEH   // leave filter handler     } exitSEH:     ... } 

18.5 Finally [Blocks]

A finally block is declared using the finally keyword. This specifies the handler code, with this grammar:

<sehClause> ::= ...

| finally <handlerBlock>

The last possible CIL instruction that can be executed in a finally handler shall be endfinally.

 
 Example (informative): .try {      ...                     // protected instructions      leave exitTry           // shall use leave } finally {      ...                     // finally handler      endfinally } exitTry:                     // back to normal 

18.6 Fault Handler [Blocks]

A fault block is declared using the fault keyword. This specifies the handler code, with this grammar:

<sehClause> ::= ...

| fault <handlerBlock>

The last possible CIL instruction that can be executed in a fault handler shall be endfault.

 
 Example (informative): .method public static void m() { startTry:            ...                     // protected instructions            leave     exitSEH       // shall use leave endTry: startFault:            ...                     // fault handler instructions           endfault endFault:      .try startTry to endTry fault handler startFault to endFault exitSEH:                           // back to normal } 


The Common Language Infrastructure Annotated Standard (Microsoft. NET Development Series)
The Common Language Infrastructure Annotated Standard (Microsoft. NET Development Series)
ISBN: N/A
EAN: N/A
Year: 2002
Pages: 121

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net