Quickly seeing where an exception may land in the debugger
A co-worker asked me recently how he could predict where an exception that was about to be thrown would land while debugging a managed application. The real answer to this question is “you can’t – step into the throw and see”. The EH system in the CLR has lots of complicated algorithms for determining this, and it needs to interact with other code on the stack (eg. there may be some native code with it’s own SEH filter that can do arbitrary logic). Luckily, unlike for native debugging, managed debugging can generally “step into” exception throws and reliably land in the handler.
But occasionally people still find themselves looking up the callstack, searching the code for ‘try’ blocks that are active. Surely there’s a way to automate that? Of course the debugger has all the information necessary to automate that, but unfortunately the VS debugger is not easily extensible in this way, so there’s not a lot you can do from the debugger process. However, as usual, func-eval offers a nice work-around for the lack of easy extensibility. Using the technique in my “Run-time exception checking” post, we can func-eval code which gets the EH handler info for the current stack and displays it nicely in the watch window. I’ve posted a sample (source and binary) which does that here. To use it, download ExceptionHandlerInfo.dll, and then while stopped in the debugger enter Assembly.LoadFrom(@"c:\mypath\ExceptionHandlerInfo.dll") into the immediate window to get it loaded into the debuggee process. Now, whenever you want to quickly see what handlers are active on the current stack, you can enter “Microsoft.Samples.ExceptionHandlerInfo.EHInfoCollector.GetActiveEHClauses()” into the watch window:
In this example, we can see that there is first a “catch System.ArgumentException” at Program.cs line 35 in method '”Program.Catcher” which is the 2nd (#1) frame on the current stack. Above that on the stack there is a “catch Exception” and a “Finally” block in the “Program.Main” method, and then a “Finally” block inside the VS hosting process code (for which we don’t have PDBs to provide a source location).
You can drill info EHInfo objects further if you want more details on a particular frame:
And if you want to automate scanning all the active EH clauses for the one most likely to catch the currently active exception (eg. when stopping on first-chance exceptions), you can enter “Microsoft.Samples.ExceptionHandlerInfo.EHInfoCollector.GuessCatchHander($exception.GetType())”:
Now someone just needs to integrate this with a VS macro so I can jump to the most likely catcher with a single keypress ;-)