OpenGL抑制MFC基于对话框的应用程序中的异常

时间:2010-01-29 15:25:45

标签: debugging opengl visual-studio-2005 mfc exception-handling

我有一个用MSVS2005创建的基于MFC驱动的基于对话框的应用程序。这是我一步一步的问题。我的对话框和相应的点击处理程序上有一个按钮,代码如下:

int* i = 0;
*i = 3;

我正在运行程序的调试版本,当我点击按钮时,Visual Studio会捕获焦点并提醒“访问违规写入位置”异常,程序无法从错误中恢复,我所能做的就是停止调试。这是正确的行为。

现在我在OnInitDialog()方法中添加一些OpenGL初始化代码:

    HDC DC = GetDC(GetSafeHwnd());
    static PIXELFORMATDESCRIPTOR pfd =
    {
      sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
      1, // version number
      PFD_DRAW_TO_WINDOW | // support window
      PFD_SUPPORT_OPENGL | // support OpenGL
      PFD_DOUBLEBUFFER, // double buffered
      PFD_TYPE_RGBA, // RGBA type
      24, // 24-bit color depth
      0, 0, 0, 0, 0, 0, // color bits ignored
      0, // no alpha buffer
      0, // shift bit ignored
      0, // no accumulation buffer
      0, 0, 0, 0, // accum bits ignored
      32, // 32-bit z-buffer
      0, // no stencil buffer
      0, // no auxiliary buffer
      PFD_MAIN_PLANE, // main layer
      0, // reserved
      0, 0, 0 // layer masks ignored
    };

    int pixelformat = ChoosePixelFormat(DC, &pfd);
    SetPixelFormat(DC, pixelformat, &pfd);

    HGLRC hrc = wglCreateContext(DC);
    ASSERT(hrc != NULL);
    wglMakeCurrent(DC, hrc);

当然这不是我所做的,它是我的代码的简化版本。好吧现在奇怪的事情开始发生了:所有初始化都很好,OnInitDialog()没有错误,但是当我点击按钮时......没有抛出任何异常。什么都没发生。完全没有。如果我在*i = 3;设置断点并在其上按F11,则处理程序函数立即停止,焦点将返回给应用程序,该应用程序继续正常工作。我可以再次点击按钮,同样的事情会发生。

似乎有人处理了发生访问冲突的异常,并默默地将执行返回到主应用程序消息接收周期。

如果我对行wglMakeCurrent(DC, hrc);发表评论,那么一切正常,抛出异常并且Visual Studio捕获它并显示带有错误消息的窗口,之后程序必须终止。

我在安装了网站的Windows 7 64位NVIDIA GeForce 8800和最新驱动程序(11.01.2010)上遇到此问题。我的同事有32位Windows Vista并且没有这样的问题 - 抛出异常并且两种情况下应用程序崩溃。

嗯,希望好人帮助我:)。

PS最初在this主题下发布的问题。

5 个答案:

答案 0 :(得分:3)

好的,我发现了一些关于此的更多信息。在我的情况下,它是Windows 7,在调用我的WndProc并给我执行控制之前,将 KiUserCallbackExceptionHandler 安装为异常处理程序。这是由 ntdll!KiUserCallbackDispatcher 完成的。我怀疑这是微软为防止入侵SEH而采取的一项安全措施。

解决方案是使用try / except帧包装你的wndproc(或hookproc),这样你就可以在Windows之前捕获异常。

感谢Skywing在http://www.nynaeve.net/

  

我们已经联系过nVidia   问题,但他们说这不是他们的   错误,而是微软的。可以   你能告诉你如何定位   异常处理程序你有吗?   一些额外的信息,例如一些   微软的反馈意见?

我在WinDbg中使用了“!exchain”命令来获取此信息。

答案 1 :(得分:1)

您可以使用向量异常处理,而不是包装WndProc或挂钩所有WndProcs:

http://msdn.microsoft.com/en-us/library/ms679274.aspx

答案 2 :(得分:0)

首先,两种行为都是正确的。取消引用空指针是“未定义的行为”,而不是保证的访问冲突。

首先,找出这是与抛出异常有关还是仅与访问内存位置零有关(尝试不同的异常)。

如果将Visual Studio配置为在第一次机会访问违规时停止,它是否会中断?

在glMakeCurrent之前和之后调用VirtualQuery(NULL,...)并进行比较。也许nVidia OpenGL驱动VirtualAlloc页面零(一个坏主意,但不是不可能或非法)。

答案 3 :(得分:0)

我有类似的行为(nVidia的驱动程序安装了一个矢量异常处理程序,最终导致崩溃),请参阅: https://stackoverflow.com/questions/4876796/why-does-an-exception-handled-by-nvidias-opengl-driver-in-copydown-memmove-late

安装最新的nVidia驱动程序(2011年1月)时它就消失了。

答案 4 :(得分:0)

当我看到类似的问题时,我发现了这个问题。在64位Windows上运行32位应用程序时,我们的问题变成了异常的异常消耗。

http://connect.microsoft.com/VisualStudio/feedback/details/550944/hardware-exceptions-on-x64-machines-are-silently-caught-in-wndproc-messages

Microsoft提供了一个修复程序,但如果您有多个目标平台,那么部署它会有些挑战:

http://support.microsoft.com/kb/976038

这是一篇关于描述行为的主题的文章:

http://blog.paulbetts.org/index.php/2010/07/20/the-case-of-the-disappearing-onload-exception-user-mode-callback-exceptions-in-x64/

堆栈溢出上的这个线程也描述了我遇到的问题: Exceptions silently caught by Windows, how to handle manually?