代码之家  ›  专栏  ›  技术社区  ›  Mikhail

OpenGL禁止基于MFC对话框的应用程序中出现异常

  •  5
  • Mikhail  · 技术社区  · 15 年前

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

    int* i = 0;
    *i = 3;
    

    我正在运行程序的调试版本,当我单击该按钮时,Visual Studio将捕获焦点并发出“访问冲突写入位置”异常警报,程序无法从错误中恢复,我所能做的就是停止调试。这是正确的行为。

    现在我在 OnInitDialog() 方法:

        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);
    

    当然,这并不是我所做的,而是我的代码的简化版本。现在奇怪的事情开始发生了:所有初始化都很好,在 OnInITIAL() ,但当我单击按钮时…不会引发异常。什么都没发生。完全。如果我在 *i = 3; 按F11键,处理函数立即停止,并将焦点返回到应用程序,应用程序继续正常工作。我可以再次点击按钮,同样的事情也会发生。

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

    如果我评论这句话 wglMakeCurrent(DC, hrc); ,一切都像以前一样正常工作,引发异常,Visual Studio捕获异常并显示带有错误消息的窗口,之后必须终止程序。

    我在安装了最新驱动程序(2010年1月11日)的Windows7 64位Nvidia Geforce 8800下遇到此问题。我的同事有32位的WindowsVista,没有这样的问题——在这两种情况下都会引发异常和应用程序崩溃。

    希望好人能帮助我:)

    PS问题最初发布在 this 话题。

    5 回复  |  直到 13 年前
        1
  •  3
  •   ralphtheninja    14 年前

    好的,我发现了更多关于这个的信息。在我的例子中,安装的是Windows 7 kiusercallbackexceptionhandler 作为异常处理程序,在调用wndproc并给我执行控制之前。这是由 NTDLL!KiuserCallbackDispatcher(KiuserCallbackDispatcher) . 我怀疑这是微软为防止黑客入侵SEH而采取的安全措施。

    解决方案是用try/except框架包装wndproc(或hookproc),以便在Windows捕获异常之前捕获该异常。

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

    我们已经就此联系了Nvidia 但他们说这不是他们的 但微软可以 请告诉我你是如何定位 异常处理程序?有吗? 一些附加信息,例如 微软的反馈?

    我用了“!exchanin“—windbg中获取此信息的命令。

        2
  •  1
  •   Mark Ingram    14 年前

    您可以使用矢量异常处理,而不是包装wndproc或挂接所有wndproc:

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

        3
  •  0
  •   Ben Voigt    14 年前

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

    首先,找出这是与异常引发有关,还是只与访问内存位置零有关(尝试其他异常)。

    如果将Visual Studio配置为在首次访问冲突时停止,它是否会中断?

    在glmakecurrent和compare之前和之后调用virtualquery(空,…)。可能是Nvidia OpenGL驱动程序virtualloc page zero(一个坏主意,但不是不可能或非法的)。

        4
  •  0
  •   Community rohancragg    7 年前

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

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

        5
  •  0
  •   Community rohancragg    7 年前

    我在研究类似问题时发现了这个问题。我们的问题是在64位Windows上运行32位应用程序时对异常的无声消费。

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

    微软提供了一个修复方案,但是如果您有多个目标平台,部署它有点困难:

    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?