Question

To test this problem I have written a minimal windows application. If I force an access violation in the WM_PAINT handler this exception never gets to the debugger. If started without debugger the access violation also does not show up. Usually you should get the Windows Error Reporting dialog.

Digging a bit deeper it seems that something in user32.dll catches all incoming exceptions. Is this normal behavior? Can I control this somehow? Isn't catching all exceptions a security risk? At least it is annoying as hell.

This is with a 32- and 64-bit application on Vista 64. On XP the exception seems to be handled as expected. Other windows messages have the same problem. Maybe all of them?

The WM_PAINT handler:

case WM_PAINT:
    hdc = BeginPaint(hWnd, &ps);
    *(int*)0 = 0;
    EndPaint(hWnd, &ps);
    break;
Was it helpful?

Solution

As a workaround I remove all registered exception handlers in my window procedure. Quite ugly.

LRESULT CALLBACK window_proc( 
    HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    // get thread information block
    NT_TIB* tib;
    __asm {
        mov EAX, FS:[18h]
        mov [tib], EAX
    }
    // old exception handler list
    _EXCEPTION_REGISTRATION_RECORD* old_exception_handler = tib->ExceptionList;
    // remove all exception handler with exception of the default handler
    while( tib->ExceptionList->Next != (_EXCEPTION_REGISTRATION_RECORD*)-1 ) {
        tib->ExceptionList = tib->ExceptionList->Next;
    }

    LRESULT result = DefWindowProc( hwnd, uMsg, wParam, lParam );

    // restore old exception handler
    tib->ExceptionList = old_exception_handler;

    return result;
}

OTHER TIPS

It's a known defect. Check the hotfix. http://support.microsoft.com/kb/976038

DispatchMessage seems to now contain a SEH try catch block that inhibits exceptions generated by window procs.

You can still catch these exceptions in the debugger - depending on your visual studio version you need to open the debug->exceptions dialog and tick the "Break when an exception is thrown" column for all Win32 exceptions, or at least exception 0xc0000005

Exception will be thrown in WinXP and in Vista. I've just tested this in Vista in Debug and Release configurations. Do you have the same issue in new Win32 Application project?

I've noticed that, when you have Aero enabled (which is by default in Vista), resizing windows tends to create many, many page faults. These aren't normal virtual memory-needs-to-be-paged-in faults, either. I suspect (though it's just a theory), that Aero redirects the graphics output to a protected chunk of memory, and catches the faults in order to know which bits of the visible surface need to be recomposited on the desktop. Perhaps that is eating other access violations as well.

Starting from XP, the Vector Exception Handling functionality can be used. It has priority over all other kinds of exceptions. In my example, it correctly caught the Access Violation in the WM_PAINT message. Unfortunately, it also catches all other kinds of exceptions, which I should probably solve by checking for the exception code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top