3 ms·
Short story about exception filters: they're mostly there for crash dumps. The background is that there is a piece of functionality in Windows previously calle
by Locke1689 12y ago
Short story about exception filters: they're mostly there for crash dumps.
The background is that there is a piece of functionality in Windows previously called Watson, now called Windows Error Reporting. It's that dialog that pops up when an application crashes that asks if you'd like to report the crash to Microsoft. If you do, it sends a crash dump to Microsoft, where it can then be routed to the owner of the application, even if the application isn't actually developed by Microsoft.
So a lot of developers in the know have designed their applications so that unrecoverable errors actually purposely cause the application to crash so that they can get a dump from WER. One of the standard ways of doing this is simply wrapping your code in a catch at the top level and then calling Environment.FailFast to crash the process.
The problem is that sometimes the stack is destroyed in this process. Note that I didn't say the stack trace -- the stack is destroyed. You can see this if you catch and rethrow an exception. The locals from the original exception are gone, so now the dump is far more difficult to debug.
Exception filters let you get around this because they don't actually pop anything, including the exception, from the stack, so if you FailFast, you crash with the full stack of the process.
A number of .NET developers had previously figured this out and were doing a bunch of nasty stuff to get this behavior, like including a VB net module with an exception filter fail-fast, or ildasm/ilasming their assembly. We tried a bunch of these methods on the compiler and they were all a source of many really obnoxious bugs, so eventually another compiler developer and I just said "screw it" and implemented exception filters in C#. All the bugs went away and we lived happily ever after.
Oh, and now exception filters are in the language.
- dfox 12y agoMain purpose of this mechanism is ability to not catch some exceptions at all so that full state of memory (primarily stack itself) is preserved in crash dump or for inspection in attached debugger (which seems like more useful case to me). With that purpose in mind, wrapping your application on the top level with try ... catch (Exception) {abort()} negates any benefit that you may get out of exception filters.
- anon4 12y agoHonest question, I'm not familiar with C#: would putting the Log in the finally clause not have the same behaviour? That is, bool _operation_X_success = false; try { ... _operation_X_success = true; } finally [ if (!_operation_X_success) { Log("blah blah"); } }
- SideburnsOfDoom 12y agoThe finally clause does not have access to the exception details, as it executes regardless of whether there is an exception or not. You can't do "Log(ex);" in the finally block. And you would want to put the exception into the log. You also need a boolean and a few extra lines of control code as your example shows.