James BB

Hiya,

I'm using SetUnhandledExceptionFilter in a DLL entry-function, to catch unhandled exceptions and ultimately write out a mini crash-dump file. The problem is that since rebuilding my development PC, it no longer seems to be working. I've installed MSVS 2005, along with the Platform SDK.

The return values from the function shown in the IDE debugger indicate that it is working correctly, but obviously the debugger takes over when an exception occurs so I can't test it that way. When running the program outside the debugger however, I still get the standard Application Error window - my handler function is not given control.

Does anyone know why this might not be working Perhaps it is something to do with the exception handler being set in the DLL, as if I set it in the executable it works fine.

Any help or suggestions would be very much appreciated, thanks

James




Re: Windows SDK SetUnhandledExceptionFilter Problem

Avery Lee

The problem is that not only you, but everyone else in the process is trying to do the same thing.

The hook set by SetUnhandledExceptionFilter() is process-wide. What's most likely happening is that someone else has called SUEF() after you, so your hook is no longer active. Every instance of the C Runtime Library (CRT) will do this in order to support terminate() handling, which means one hook for every DLL or EXE that statically links to the CRT and one for every DLL version of the CRT (MSVCRT, MSVCR80, etc). For the exceptions that the CRT's hook handles, most notably unhandled C++ exceptions, the last one that hooks the unhandled exception filter will win. Unfortunately, the managed execution engine MSCOREE.DLL is statically linked, and it's loaded from XP's COMCTL32.DLL. This essentially makes _set_terminate_handler() completely useless.

Basically, the only sure way to ensure that your unhandled exception filter is used is to patch SetUnhandledExceptionFilter() itself -- not for the light of heart, and you should understand the ramifications of patching a system DLL in-memory before considering it. You also said that you were in a DLL, which makes this worse. If you're being loaded as a plugin in an application I would strongly advise that you not take the unhandled exception hook as you are probably interfering with the exception handling of the main program. Some say that you should save and restore the hook, but that still has collision issues, and it's also impossible to unhook safely when someone has hooked above you -- it's a bit like DOS interrupt vector hooking.

The safest way to handle this problem is to avoid the unhandled exception hook entirely and simply use __try/__except around all of your DLL entry points instead -- a bit of a sledgehammer approach, but a sure way to scope the handling to your own code. Do not use try/catch, as it will not catch non-C++ exceptions in VC8 and up.

One more thing: starting with VC8, certain detected errors in the CRT will result in the CRT explicitly pulling off any installed handler with SetUnhandledExceptionFilter(NULL) and forcing the default OS handler. You can disable this behavior with _set_invalid_parameter_handler(), but it only works for errors raised in the instance of the CRT that you are using.