Exception Handling (Part 1 of 2)

Anybody that done any programming on .NET has probably used some EH at least once or twice.  It all seems pretty natural and straight forward.  Well, I'm glad we can fool so many of you into thinking it's easy.

What follows is a gross-over-simplification of EH, but still useful if you know nothing about EH.

The short explanation is that the OS takes care of actually unwinding the stack, but relies on something called a 'Personality Routine' to determine what stuff to do at each stack level (like execute a finally, call a C++ destructor, etc.).  For x86 the OS and personality routines rely on an exception record stack that is pointed to by FS:[0].  Well on IA64 and AMD64 (and a few other architectures), it's a little different.  They are table based.

With the stack based approach you actually have instructions in your code that push and pop the exception state (like which finallys or catches to execute).  These correlate very nicely with some of the semantics .NET has.  The down side is that the pushing and popping seems rather inefficient, when simple static analysis can dictate what the EH stack would look like at any given point.

So then we have PDATA and XDATA.  I don't know much about the exact difference (one is used more for unwinding info, the other more for exception info).  The general idea is to have a bunch of tables that state at a given instruction address, here are the EH clauses that are in effect.

I relate all this because I've recently been working on a bug where in certain cases the wrong EH clause was being called.  This was a direct result of put opcodes in the wrong protected region (or to state it differently, having the protected regions protect too much).  This gets particularly interesting when you consider asynchronous EH (like ThreadAbortException).

Hopefully tomorrow, I can finish this off.  Either way I think the real geeks will find this interesting.

--Grant