为了测试这个问题,我编写了一个最小的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;
答案 0 :(得分:5)
作为一种解决方法,我在窗口过程中删除所有已注册的异常处理程序。相当难看。
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; }
答案 1 :(得分:5)
这是一个已知的缺陷。检查此修补程序。 http://support.microsoft.com/kb/976038
答案 2 :(得分:3)
DispatchMessage现在似乎包含一个SEH try catch块,它禁止窗口过程产生的异常。
您仍然可以在调试器中捕获这些异常 - 取决于您打开debug-> exceptions对话框所需的visual studio版本,并勾选所有Win32异常的“抛出异常时断开”列,或者至少异常0xc0000005
答案 3 :(得分:0)
在WinXP和Vista中会抛出异常。我刚刚在Vista的Debug和Release配置中对此进行了测试。您是否在新的Win32应用程序项目中遇到同样的问题?
答案 4 :(得分:0)
我注意到,当您启用Aero(默认情况下在Vista中)时,调整窗口大小往往会产生许多页面错误。这些也不是正常的虚拟内存需要分页故障。我怀疑(虽然这只是一个理论),Aero将图形输出重定向到受保护的内存块,并捕获故障以便知道需要在桌面上重新组合可见表面的哪些位。也许这也正在侵犯其他访问权限。
答案 5 :(得分:0)
从XP开始,可以使用矢量异常处理功能。它优先于所有其他类型的例外。在我的示例中,它正确捕获了WM_PAINT消息中的访问冲突。不幸的是,它还捕获了所有其他类型的异常,我应该通过检查异常代码来解决这些异常。