A vectored exception handler (see kernel32!AddVectoredExceptionHandler) lets you add to a global list of filters that get executed by the OS when a native exception is thrown. More specifically, this list is executed by the OS before the filters in the FS:0 chain are executed. This means you can get your exception handler to run even if you don’t have any sort of try/catch block. Matt Pietrek has a great explanation and demo here.
Sounds cool? But with great power comes great responsibility. This is a very dangerous thing, especially in managed code.
My advice is to just play it safe and avoid vectored exception handlers in managed apps.
1. The vectored exception handler can interfere with CLR exception processing. For example, if the VEH swallows the exception.
2. The VEH can break Interop-debugging (mixed-mode) and cause it to hang. Interop-debugging does very evil things that don’t play well with a VEH. For example, if the VEH generates any debug events (such as an int3), that can cause great pain in the debugger. Of if the VEH swallows an exception, it will prevent CLR’s FS:0 handlers from getting it and doing critical work for interop-debugging.
3. Since the VEH occurs at any native exception, including ones thrown from the middle of the CLR, a vectored exception handler can cause reentrancy problems. For example, if your VEH calls managed code, then you may be executing managed code at a point where the CLR is not prepared for it. I think we have a reentrancy MDA to help detect things like this.
(I’m sure there are other reasons I’m missing, don’t be surprised to see this list grow)
If you follow enough constraints, it’s possible to write a “safe” VEH – but imo, why tempt fate?
Exposing from managed code?
Brad details how we almost added managed support for this via an ExceptionThrown event on the appdomain. That’s very scary and would have caused lots of problems. For example, different customers would have different needs and it would be difficult to satisfy them all:
– what exceptions get notified? Native ones? Managed ones?
– what about CLR-internal ones? Eg, if inside the CLR, an exception is thrown and caught, should it show up? (It will with the VEH).
– what about Hardware vs. Software ones? Should an STATUS_BREAKPOINT show up?
– What about hardware exceptions (like Access Violations) that get wrapped by managed exceptions? At the native 1st-chance notification, you may not have a managed exception object. But at the managed notification, it may be too late.
– what about knowing when exceptions are caught?
I think the VEH is dangerous enough, that exposing something like it from managed code would have caused a lot of grief.
If you absolutely need some sort of VEH functionality, consider:
1. One alternative is to have an out-of-process debugger harness sniff for exceptions. (see Mdbg exception harness for an example). That’s slower, but a lot safer. And you also get more information about the managed exception, such as what type it is and where it’s caught on the stack.
2. The profiler API also has exception notifications.
3. IL filters .