简体   繁体   English

WM_PAINT中的访问冲突未被捕获

[英]access violation in WM_PAINT not caught

To test this problem I have written a minimal windows application. 为了测试这个问题,我编写了一个最小的Windows应用程序。 If I force an access violation in the WM_PAINT handler this exception never gets to the debugger. 如果我在WM_PAINT处理程序中强制执行访问冲突,则此异常永远不会到达调试器。 If started without debugger the access violation also does not show up. 如果在没有调试器的情况下启动,则访问冲突也不会显示。 Usually you should get the Windows Error Reporting dialog. 通常,您应该获得Windows错误报告对话框。

Digging a bit deeper it seems that something in user32.dll catches all incoming exceptions. 深入挖掘似乎user32.dll中的某些内容会捕获所有传入的异常。 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. 这是在Vista 64上使用32位和64位应用程序。在XP上,异常似乎按预期处理。 Other windows messages have the same problem. 其他Windows消息也有同样的问题。 Maybe all of them? 也许他们都是?

The WM_PAINT handler: WM_PAINT处理程序:

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

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;
}

It's a known defect. 这是一个已知的缺陷。 Check the hotfix. 检查此修补程序。 http://support.microsoft.com/kb/976038 http://support.microsoft.com/kb/976038

DispatchMessage seems to now contain a SEH try catch block that inhibits exceptions generated by window procs. DispatchMessage现在似乎包含一个SEH try catch块,它禁止窗口过程产生的异常。

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 您仍然可以在调试器中捕获这些异常 - 取决于您打开debug-> exceptions对话框所需的visual studio版本,并勾选所有Win32异常的“抛出异常时断开”列,或至少异常0xc0000005

Exception will be thrown in WinXP and in Vista. WinXP和Vista中会抛出异常。 I've just tested this in Vista in Debug and Release configurations. 我刚刚在Vista的Debug和Release配置中对此进行了测试。 Do you have the same issue in new Win32 Application project? 你在新的Win32应用程序项目中有同样的问题吗?

I've noticed that, when you have Aero enabled (which is by default in Vista), resizing windows tends to create many, many page faults. 我注意到,当你启用Aero(默认情况下在Vista中)时,调整窗口大小往往会产生许多页面错误。 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. 我怀疑(虽然这只是一个理论),Aero将图形输出重定向到受保护的内存块,并捕获故障以便知道需要在桌面上重新组合可见表面的哪些位。 Perhaps that is eating other access violations as well. 也许这也是其他访问违规行为。

Starting from XP, the Vector Exception Handling functionality can be used. 从XP开始,可以使用矢量异常处理功能。 It has priority over all other kinds of exceptions. 它优先于所有其他类型的例外。 In my example, it correctly caught the Access Violation in the WM_PAINT message. 在我的示例中,它正确捕获了WM_PAINT消息中的访问冲突。 Unfortunately, it also catches all other kinds of exceptions, which I should probably solve by checking for the exception code. 不幸的是,它还捕获了所有其他类型的异常,我应该通过检查异常代码来解决这些异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM