views:

214

answers:

5

We're having problems with Windows silently eating exceptions and allowing the application to continue running, when the exception is thrown inside the message pump. For example, we created a test MFC MDI application, and overrode OnDraw:

void CTestView::OnDraw(CDC* /*pDC*/)
{
    *(int*)0 = 0; // Crash

    CTestDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    // TODO: add draw code for native data here
}

You would expect a nasty error message when running the application, but you actually get nothing at all. The program appears to be running perfectly well, but if you check the output window you will see:

First-chance exception at 0x13929384 in Test.exe: 0xC0000005: Access violation writing location 0x00000000.
First-chance exception at 0x77c6ee42 in Test.exe: 0xC0150010: The activation context being deactivated is not active for the current thread of execution.

I know why I'm receiving the application context exception, but why is it being handled silently? It means our applications could be suffering serious problems when in use, but we'll never know about it, because our users will never report any problems.

+2  A: 

functions that may be of interest:

SetUnhandledExceptionFilter()
_set_invalid_parameter_handler()
_RTC_SetErrorFuncW()
_CrtSetReportHookW2()

PS, be aware that SetUnhandledExceptionFilter() can be overriden by other dlls loaded into your .exe. eg, flash and nvidia direct3d do this. I use api hooking to cure this.

steelbytes
Hi, thanks for the suggestions, but I've tried all 4 (on the line before the crash) and the exception still isn't caught.
Mark Ingram
just because you call SetUnhandledExceptionFilter right before the msg loop, doesn't mean that during the message loop a dll doesn't override it. suggest placing a breakpoint on SetUnhandledExceptionFilter() (in kernel32, not the call in your exe).
steelbytes
A: 

Your output looks like you're using Visual Studio...
If not forget about my answer.
You can specify which exceptions will be thrown normally, meaning that Visual Studio catches them and your progam stops where the access violation occurred. Do this in the Debug/Exceptions... menu. If you are not sure what to enable, just enable them all...

Simon Linder
That's fine for when you are debugging it yourself, but no good when you've released the product to a customer.
Mark Ingram
Yes, that is true.
Simon Linder
+4  A: 

After browsing similar questions I stumbled across this answer: http://stackoverflow.com/questions/2162897/opengl-suppresses-exceptions-in-mfc-dialog-based-application/2287800#2287800

"Ok, I found out some more information about this. In my case it's windows 7 that installs KiUserCallbackExceptionHandler as exception handler, before calling my WndProc and giving me execution control. This is done by ntdll!KiUserCallbackDispatcher. I suspect that this is a security measure taken by Microsoft to prevent hacking into SEH.

The solution is to wrap your wndproc (or hookproc) with a try/except frame."

Mark Ingram
A: 

These are first-chance exceptions that are being caught & handled in Microsoft code. When running in the debugger, any exception is immediately noted. This is the "first-chance". The program is then allowed to continue so that the debugger can determine if the exception is handled by the program. If it is handled, then the debugger simply notes an exception was thrown and keeps on going. If the exception is not handled (an "unhandled exception"), then the debugger breaks into the program (this is the "second-chance", when you, as a developer, need to get involved, or your program will crash).

The first-chance exceptions you are seeing are being thrown in Microsoft code, and are also being caught and dealt with in Microsoft code. You probably shouldn't be too concerned with them. You will also see them in your own code, when you catch a thrown exception and carry on.

If you're still concerned, then you can tell the debugger to break on first-chance exceptions. In VS 2008, open your project and go to the "Exceptions" entry under the "Debug" menu. You'll get a dialog which will allow you to break whenever any exception is thrown, rather then just when an exception is unhandled.

Check out the links below for more information: http://blogs.msdn.com/davidklinems/archive/2005/07/12/438061.aspx http://blogs.msdn.com/davidklinems/archive/2005/07/18/440150.aspx

T.J. Boberek
As you can see from my original question, the code isn't in Microsoft code, it's in something I've written :)
Mark Ingram
Sorry -- you're right, I mis-read the code in the question. Something has to be handling that exception for you, otherwise the debugger would break into the application. Do you have any try/catch blocks? It's strange that this happens in OnDraw(). Do you have any try/catch blocks in derived versions of WindowProc or OnWndMsg? It may be a SEH unhandled exception filter, but those should not be called under the debugger. To check this, call SetUnhandledExceptionFilter() with a NULL parameter right before the crash and check the return value. If it's non-NULL, there's a filter set.
T.J. Boberek
A: 

Sorry for using answer form to ask this (I cannot leave comments), but how do you think the post you've marked as a "best answer" really solves the problem? You posted link to answer on my question. In my case, this behavior (swallowed exceptions) was caused by OpenGL initialization. And what was the reason in your case? Yes, try/catch block is a good workaround, but it doesn't explain the source of this externally placed exception handler.

And could you please tell me, how did you trace this KiUserCallbackExceptionHandler? What is the technique that provide you ability to watch registered exception handlers? I appreciate your answers.

Mikhail
Hi, I used the answer that was provided in that question to determine I need to try / catch around my WndProc message handlers. This is a horrible work around, but the best that you can do. See my bug report here:http://connect.microsoft.com/VisualStudio/feedback/details/550944/hardware-exceptions-on-x64-machines-are-silently-caught-in-wndproc-messages
Mark Ingram
That's the helpful link. Thanks.
Mikhail