未捕获WM_PAINT中的访问冲突

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

深入挖掘看来,user32.dll中的某些内容会捕获所有传入的exception。 这是正常的行为? 我能不能控制这个? 没有捕获所有的例外安全风险? 至less这是讨厌的地狱。

这是Vista 64和32位和64位应用程序。在XP上,exception似乎按预期处理。 其他Windows消息也有同样的问题。 也许他们都是?

WM_PAINT处理程序:

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

Solutions Collecting From Web of "未捕获WM_PAINT中的访问冲突"

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

 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;
     //除了默认处理程序之外,移除所有异常处理程序
     while(tib-> ExceptionList-> Next!=(_EXCEPTION_REGISTRATION_RECORD *) -  1){
         tib-> ExceptionList = tib-> ExceptionList-> Next;
     }

     LRESULT结果= DefWindowProc(hwnd,uMsg,wParam,lParam);

     //恢复旧的异常处理程序
     tib-> ExceptionList = old_exception_handler;

    返回结果;
 }

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

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

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

在WinXP和Vista中将抛出异常。 我刚刚在Vista中调试和发布配置。 新的Win32应用程序项目中是否有同样的问题?

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

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