Consider this code:
void Main()
{
try {
Console.Write("try ");
throw new NotImplementedException();
}
catch (NotImplementedException) {
Console.Write("catch");
}
}
Using LINQPad, I see the code compiles to:
IL_0000: nop
IL_0001: nop
IL_0002: ldstr "try"
IL_0007: call System.Console.WriteLine
IL_000C: nop
IL_000D: newobj System.NotImplementedException..ctor
IL_0012: throw
IL_0013: pop
IL_0014: nop
IL_0015: ldstr "catch"
IL_001A: call System.Console.WriteLine
IL_001F: nop
IL_0020: nop
IL_0021: leave.s
The code above prints try catch
, if I throw Exception
instead, try
is printed and the program exits due to the unhandled exception (as expected), the IL code remains the same, except this line:
IL_000D: newobj System.Exception..ctor
What is the logic behind that? I would except for logic that checks the type of the exception to make a decision if to go into the catch block or not.
I little bit of necromancy here. I've spent several hours reading specs on the subject and here are some interesting details that aren't covered in comments. The quotes are taken from Standard ECMA-335 - Common Language Infrastructure (CLI) :
Each method in an executable has associated with it a (possibly empty) array of exception handling information. Each entry in the array describes a protected block, its filter, and its handler. When an exception occurs, the CLI searches the array for the first protected block that
If a match is not found in the current method, the calling method is searched, and so on. If no match is found the CLI will dump a stack trace and abort the program
Some things to notice are:
So that "a (possibly empty) array of exception handling information" is actually a section that every method has
At the next 4-byte boundary following the method body can be extra method data sections. Currently, the method data sections are only used for exception tables.
And that section consists of clauses
which store information about where try
block starts, where it ends, where catch
starts and there is one particular field — ClassToken
which is described as Meta data token for a type-based exception handler
which should be the information about exception type that could be handled by that particular catch block.
Unfortunately, ILDASM doesn't show raw method headers and inserts information from there as .try
instructions in disassembled code view, but the IL itself has no specific instructions for exception type handling as it does not inserts specific intermediate code for the same purpose.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.