The SetUnhandledExceptionFilter API Function

[Previous] [Next]

In C++ code, you have the opportunity to handle crashes by guarding the sections of code in which you think a hard crash might occur. As we all know, however, crashes have a habit of never happening where you expect them. Unfortunately, when your users experience crashes in your program, they just see the Application Error dialog box, and then maybe Dr. Watson gives them a little information to send to you to figure out the problem. As I mentioned early in this chapter, you can devise your own dialog boxes to get the information you really need to solve the crash. The way you do this is through the magic of the SetUnhandledExceptionFilter API function. I've always referred to these handlers as crash handlers. Amazingly, this functionality has been in Microsoft Win32 since Microsoft Windows NT 3.5, but it's almost undocumented. In the July 1999 MSDN, this function was mentioned in only nine topics.

In my experience, crash handlers have excellent debugging capabilities. In one project I worked on, when a crash occurred, in addition to putting up a dialog box with our technical support number on it, I logged all the information I could about the crash, including the state of the user's system, into a file. I also iterated through the program's main objects so that I could report down to the class level which objects were active and what they contained. I was logging almost too much information about the program's state. With a crash report, I had a 90 percent chance of duplicating the user's problem. If that isn't proactive debugging, I don't know what is!

Needless to say, I find SetUnhandledExceptionFilter powerful. Just by looking at the function name—SetUnhandledExceptionFilter—you can probably guess what the function does. The one parameter to SetUnhandledExceptionFilter is a pointer to a function that is called in the final __except block for the application. This function returns the same value that any exception filter would return: EXCEPTION_EXECUTE_HANDLER, EXCEPTION_CONTINUE_EXECUTION, or EXCEPTION_CONTINUE_SEARCH. You can do any exception handling you want in the filter function, but as I warned earlier in the C++ _set_se_translator discussion, you need to be careful about blown stacks in your filter function. To be on the safe side, you might want to avoid any C run-time library calls as well as MFC. If you write your exception filter function in Visual Basic, you should be extra careful about what you access from the Visual Basic run-time library. Although I'm obligated to warn you about these possibilities, I can assure you that the vast majority of your crashes will be access violations—you shouldn't have any problems if you write a complete crash handling system in your function provided you check the exception reason first and avoid function calls if the stack is blown.

Your exception filter also gets a pointer to an EXCEPTION_POINTERS structure. In Listing 9-5, I'll present several routines that translate this structure for you. Because each company has different crash handler needs, I'll let you write your own.

You need to keep in mind a couple of issues when you're using SetUnhandledExceptionFilter. The first is that you can't use standard user-mode debuggers to debug any unhandled exception filter you set. This is a known bug. Knowledge Base article Q173652 says that under a debugger the unhandled exception filter isn't called. This bug can be a bit of a pain, but in a C++ program, one workaround you can use to debug your unhandled exception filter is to call it from a regular SEH exception filter. You can find an example of this workaround in the Baz function in CH_TESTS.CPP, which is part of this book's source code.

Another issue is that the crash handler you specify by calling SetUnhandledExceptionFilter is global to your process. If you build the coolest crash handler in the world for your ActiveX control and the container crashes—even if it's not your fault—your crash handler will be executed. Don't let this possibility keep you from using SetUnhandledExceptionFilter, though; I have some code that might help you out.



Debugging Applications
Debugging Applications for MicrosoftВ® .NET and Microsoft WindowsВ® (Pro-Developer)
ISBN: 0735615365
EAN: 2147483647
Year: 2000
Pages: 122
Authors: John Robbins

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net