7

为了测试这个问题,我编写了一个最小的 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;
4

6 回答 6

5

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

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;

    返回结果;
}
于 2009-10-01T09:32:14.227 回答
5

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

于 2010-08-05T18:59:44.273 回答
3

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

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

于 2009-09-29T07:48:43.123 回答
0

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

于 2009-09-28T18:47:39.067 回答
0

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

于 2009-09-30T19:26:01.457 回答
0

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

于 2010-05-25T14:45:32.960 回答