<snip>
Suppose a statment in the try-block throws and then code in finally block
also throws? IIUC, The finally block will be executed before stack
unwinding? Tjen you suddenly have two exceptions...
There are not two exceptions, the 2nd exception replaces the 1st. Also,
finally blocks are executed after, not before, the stack unwinds.
Ignoring kernel mode transitions, 1st chance exceptions sent to the debugger
, win32 subsystems, transitions in-and-out of unmanaged code, etc, the basic
sequence when an exception is thrown is...
1. 1st pass of stack walking searches the exception frames in the stack for
a catch block to handle the exception. This is based on type filters (for
C#; for VB it may also be user-filtered).
2. If a handler is found it starts the 2nd pass. It remembers where the
catch handler is at and then starts walking the stack again, this time
executing code in finally and fault blocks, up to the frame that contains
the catch block that will handle the exception; it does not yet execute the
finally block associated with that catch block.
3. Control is given to the catch handler. Note that ALL downstream finally
blocks have already run and the stack is unwound to the point of the catch
handler.
4. When the catch handler completes control passes to the finally block (if
any) that follows the catch handler.
If a finally block throws an exception (which is legitimate and happens all
the time) a new exception is thrown and a new sequence of 2 pass stack
walking occurs.
It's also possible for a user-filter to throw its own exception; this is a
nested exception. I believe it replaces the initial exception (in win32 this
would probably be a nested exception). C# does not support user-filtered
exceptions (VB does and I wish C# did too). Also, the CLR does not support
resumable or restartable exceptions (even though the spec states it does; I
frankly think is better off without this).
An important distinction between exceptions thrown in user-filters as
opposed to exceptions thrown in finally or catch blocks is the phase that it
occurs in. Exceptions thrown in user-filters occur during the 1st phase of
the stack walk (before finally blocks have run and before the stack is
unwound) while exceptions thrown in finally and catch blocks occur during
the 2nd phase, which is after all user-filters and downstream (in terms of
the stack) finally blocks have run and the stack has been unwound. If this
occurs a new 2 pass stack walk begins, this time from the site where the new
exception is thrown.
Dave