You need to understand the call stack and how exception work. An exception propagate up the stack by jumping from one "try" point to another. This is a kind of "time machine" mechanism.
I tried to explain it in my past answers (I am the author of a very early implementation of Structured Exception Handling, at the time when it was in CLU and then Ada, but no even in C++ yet):
Does Exception in C# Constructor Cause Caller Assignment to Fail?[
^],
where was stored .net exceptions in operating system[
^].
First of all, you need to understand what is the call stack and its role, and then you need to understand that the exception mechanism has its own stack which elements point to the positions in the call stack, per thread. It allows you to trace how the exception propagated to a certain point of your code.
In addition to understanding the theory, I can advise one practical step which can give you a clear vision of the stack in each particular case. Catch all exceptions somewhere on the top stack frame. Put a break point on the exception handler and run it under the debugger the way to observe the exception. When execution stops at the break point, open the Debug window called "Call stack". In this window, you can click on the lines each corresponding to some point on the call stack. On click, a source code window will be shown, with the cursor set on the point in code.
It will help you to understand the exception stack diagnostics. See also:
http://msdn.microsoft.com/en-us/library/system.diagnostics.stacktrace%28v=vs.110%29.aspx[
^],
http://msdn.microsoft.com/en-us/library/system.diagnostics.stackframe%28v=vs.110%29.aspx[
^].
—SA