【问题标题】:access violation in WM_PAINT not caught未捕获 WM_PAINT 中的访问冲突
【发布时间】:2010-12-02 01:22:33
【问题描述】:

为了测试这个问题,我编写了一个最小的 Windows 应用程序。如果我在WM_PAINT 处理程序中强制访问冲突,则此异常永远不会到达调试器。如果在没有调试器的情况下启动,访问冲突也不会出现。通常你应该得到 Windows 错误报告对话框。

深入挖掘,似乎 user32.dll 中的某些内容捕获了所有传入的异常。这是正常行为吗?我能以某种方式控制它吗?捕获所有异常不是安全风险吗?至少它很烦人。

这适用于 Vista 64 上的 32 位和 64 位应用程序。在 XP 上,该异常似乎已按预期处理。其他windows消息也有同样的问题。也许所有这些?

WM_PAINT 处理程序:

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

【问题讨论】:

    标签: c++ windows exception winapi access-violation


    【解决方案1】:

    作为一种解决方法,我删除了窗口过程中所有已注册的异常处理程序。很丑。

    LRESULT CALLBACK window_proc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { // 获取线程信息块 NT_TIB* tib; __asm { mov EAX, FS:[18h] mov [tib], EAX } // 旧的异常处理程序列表 _EXCEPTION_REGISTRATION_RECORD* old_exception_handler = tib->ExceptionList; // 删除除默认处理程序之外的所有异常处理程序 而( tib->ExceptionList->Next != (_EXCEPTION_REGISTRATION_RECORD*)-1 ) { tib->ExceptionList = tib->ExceptionList->下一步; } LRESULT 结果 = DefWindowProc(hwnd, uMsg, wParam, lParam); // 恢复旧的异常处理程序 tib->ExceptionList = old_exception_handler; 返回结果; }

    【讨论】:

      【解决方案2】:

      这是一个已知的缺陷。检查修补程序。 http://support.microsoft.com/kb/976038

      【讨论】:

        【解决方案3】:

        DispatchMessage 现在似乎包含一个 SEH try catch 块,该块禁止窗口 procs 生成的异常。

        您仍然可以在调试器中捕获这些异常 - 根据您的 Visual Studio 版本,您需要打开调试->异常对话框并勾选所有 Win32 异常或至少异常的“抛出异常时中断”列0xc0000005

        【讨论】:

        • 我知道,但这只是使用调试器时的解决方案。在处理 Windows 消息时可能引发的所有其他异常是什么?您是否有任何官方(或非官方)文档或对此更改的理由?
        【解决方案4】:

        在 WinXP 和 Vista 中会抛出异常。我刚刚在 Vista 中的调试和发布配置中对此进行了测试。您在新的 Win32 应用程序项目中是否有同样的问题?

        【讨论】:

          【解决方案5】:

          我注意到,当您启用 Aero 时(在 Vista 中是默认设置),调整窗口大小往往会产生很多很多页面错误。这些也不是正常的虚拟内存需要分页错误。我怀疑(尽管这只是一个理论),Aero 将图形输出重定向到受保护的内存块,并捕获故障以了解需要在桌面上重新合成可见表面的哪些位。也许这也在吞噬其他访问违规。

          【讨论】:

          • 从Vista开始,显存是虚拟化的。这不应与应用程序中的任何异常相关联。至少 Aero 启用与否不会改变 Windows 消息中的异常处理。
          • 你是对的。无论是否启用桌面合成,都会删除该异常。
          【解决方案6】:

          从 XP 开始,可以使用向量异常处理功能。它优先于所有其他类型的异常。在我的示例中,它正确地捕获了 WM_PAINT 消息中的访问冲突。不幸的是,它还捕获了所有其他类型的异常,我应该通过检查异常代码来解决。

          【讨论】:

            猜你喜欢
            • 2010-10-02
            • 1970-01-01
            • 2022-01-07
            • 2016-01-07
            • 2023-03-19
            • 2021-05-14
            • 2013-05-12
            • 2010-11-01
            相关资源
            最近更新 更多