Since .NET 4, some SEHException
s indicate corrupted process states, and are termed "corrupted state exceptions". These are things like segfaults/access violations, where the exception is thrown after memory corruption has been detected.
While these errors are still mapped back to managed .NET SEHExceptions
, they are not catchable by default, so try { ... } catch (Exception ex) { ... }
won't handle them.
You can opt-in to handling these exceptions (either via an attribute or a policy change in your app's config file), but it is not recommended, as your program could now be processing invalid data:
The CLR has always delivered SEH exceptions to managed code using the same mechanisms as exceptions raised by the program itself. This isn't a problem as long as code doesn't attempt to handle exceptional conditions that it cannot reasonably handle. Most programs cannot safely continue execution after an access violation. Unfortunately, the CLR's exception handling model has always encouraged users to catch these serious errors by allowing programs to catch any exception at the top of the System.Exception hierarchy. But this is rarely the right thing to do.
Writing catch (Exception e) is a common programming error because unhandled exceptions have serious consequences. But you might argue that if you don't know what errors will be raised by a function, you should protect against all possible errors when your program calls that function. This seems like a reasonable course of action until you think about what it means to continue execution when your process is possibly in a corrupted state. Sometimes aborting and trying again is the best option: nobody likes to see a Watson dialog, but it's better to restart your program than to have your data corrupted.
Programs catching exceptions arising from contexts they don't understand is a serious problem. But you can't solve the problem by using exceptions specifications or some other contract mechanism. And it's important that managed programs be able to receive notification of SEH exceptions because the CLR is a platform for many kinds of applications and hosts. Some hosts, such as SQL Server, need to have total control of their application's process. Managed code that interoperates with native code sometimes must deal with native C++ exceptions or SEH exceptions.
But most programmers who write catch (Exception e) don't really want to catch access violations. They'd prefer that execution of their program stops when a catastrophic error occurs rather than letting the program limp along in an unknown state. This is especially true for programs that host managed add-ins such as Visual Studio or Microsoft Office. If an add-in causes an access violation and then swallows the exception, the host could be doing damage to its own state (or user files) without ever realizing something went wrong.
The article this quote is from (in MSDN magazine) goes into much more detail.
If you do decide to handle these exceptions, there is a lot to consider - as the article states "It's very difficult to write correct code that handles a CSE and continues running the process safely."
In particular, any finally
blocks that the exception has passed over have not been executed (so, e.g. any file handles are dangling until collected), and even constrained execution regions may be skipped!
In addition, you should probably report this as a bug to Microsoft, as GetAssemblyName
shouldn't be throwing this kind of exception.