OpenGL应用程序导致d3d11.dll中的Stack Overflow

时间:2017-11-11 02:57:48

标签: c++ windows opengl dll stack-overflow

此问题仅在将Windows 10更新至版本1703后才开始发生,该程序在版本1607上正常运行。

创建OpenGL 4.6上下文时,在调用SwapBuffers()时会在d3d11.dll中触发堆栈溢出异常。下面是堆栈内容的摘要(从下往上阅读)。为什么我的纯OpenGL程序调用d3d11.dll中的函数?我不知道如何调试这个,任何提示都会受到赞赏。

系统规格:GeForce GT 745A,驱动程序版本388.13,Windows 10版本1703,i7 4790S,8GB内存

编辑:已加载的符号,有一个更有用的调用堆栈:

d3d11.dll!NDXGI::CDevice::SubmitCommandCB(void *,struct _D3DDDICB_SUBMITCOMMAND const *)    Unknown
-- This block repeats several times...
nvwgf2umx.dll!00007ffdd4a226d5()    Unknown
nvwgf2umx.dll!00007ffdd4a18830()    Unknown
nvwgf2umx.dll!00007ffdd4a2363d()    Unknown
nvwgf2umx.dll!00007ffdd4d60d27()    Unknown
nvwgf2umx.dll!00007ffdd4a226d5()    Unknown
-------------------------------------------
nvwgf2umx.dll!00007ffdd4a18830()    Unknown
nvwgf2umx.dll!00007ffdd4a2363d()    Unknown
nvwgf2umx.dll!00007ffdd4d60d27()    Unknown
nvwgf2umx.dll!00007ffdd4194afb()    Unknown
nvwgf2umx.dll!00007ffdd418e57e()    Unknown
nvwgf2umx.dll!00007ffdd41b3f1d()    Unknown
nvwgf2umx.dll!00007ffdd4183518()    Unknown
nvwgf2umx.dll!00007ffdd4183750()    Unknown
d3d11.dll!NDXGI::CDevice::CreateDriverInstance(void *,void *,void *,void *,bool,bool,enum D3D_FEATURE_LEVEL,unsigned int,long (**)(struct D3D10DDI_HDEVICE,unsigned int,unsigned __int64,void *,unsigned __int64,void *))   Unknown
d3d11.dll!CDevice::CreateDriverInstance(class CContext *,void *,void *,void *,void *,unsigned int,long (**)(struct D3D10DDI_HDEVICE,unsigned int,unsigned __int64,void *,unsigned __int64,void *))  Unknown
d3d11.dll!CContext::LUCCompleteLayerConstruction(void)  Unknown
d3d11.dll!NOutermost::CDeviceChild::LUCCompleteLayerConstruction(void)  Unknown
d3d11.dll!NOutermost::CDevice::CreateLayeredChild(unsigned int,void const *,unsigned __int64,struct ID3D11LayeredUseCounted *,struct _GUID const &,void * *)    Unknown
d3d11.dll!CDevice::LLOCompleteLayerConstruction(void)   Unknown
d3d11.dll!NDXGI::CDevice::LLOCompleteLayerConstruction(void)    Unknown
d3d11.dll!NOutermost::CDevice::FinalConstruct(struct NOutermost::CDevice::TConstructorArgs const &) Unknown
d3d11.dll!TComObject<class NOutermost::CDevice>::TComObject<class NOutermost::CDevice>(void *,struct NOutermost::CDevice::TConstructorArgs const &,struct _GUID const &,void * *)   Unknown
d3d11.dll!TComObject<class NOutermost::CDevice>::CreateInstance(struct NOutermost::CDevice::TConstructorArgs const &,void *,void *,struct _GUID const &,void * *)   Unknown
d3d11.dll!D3D11CreateLayeredDevice(unsigned int,void const *,unsigned __int64,struct ID3D11LayeredDevice *,struct _GUID const &,void * *)   Unknown
d3d11.dll!D3D11CoreCreateLayeredDevice()    Unknown
d3d11.dll!D3D11RegisterLayersAndCreateDevice(struct D3D11_EXTENSIONS const &,class NDXGI::CUMDAdapter *,enum D3D_FEATURE_LEVEL,enum D3D_FEATURE_LEVEL,unsigned __int64,unsigned int,struct ID3D11Device * *)    Unknown
d3d11.dll!D3D11CoreCreateDevice()   Unknown
d3d11.dll!D3D11CreateDeviceAndSwapChainImpl(struct IDXGIAdapter *,enum D3D_DRIVER_TYPE,struct HINSTANCE__ *,unsigned int,enum D3D_FEATURE_LEVEL const *,unsigned int,unsigned int,struct DXGI_SWAP_CHAIN_DESC const *,struct IDXGISwapChain * *,struct ID3D11Device * *,enum D3D_FEATURE_LEVEL *,struct ID3D11DeviceContext * *)    Unknown
d3d11.dll!D3D11CreateDeviceAndSwapChain()   Unknown
d3d11.dll!D3D11CreateDeviceImpl(struct IDXGIAdapter *,enum D3D_DRIVER_TYPE,struct HINSTANCE__ *,unsigned int,enum D3D_FEATURE_LEVEL const *,unsigned int,unsigned int,struct ID3D11Device * *,enum D3D_FEATURE_LEVEL *,struct ID3D11DeviceContext * *)  Unknown
d3d11.dll!D3D11CreateDevice()   Unknown
nvoglv64.dll!0000000058f193a9() Unknown
nvoglv64.dll!0000000058f18438() Unknown
nvoglv64.dll!0000000058f40b8e() Unknown
nvoglv64.dll!0000000058f3fcd3() Unknown
nvoglv64.dll!0000000058f22607() Unknown
nvoglv64.dll!0000000058f41a42() Unknown
nvoglv64.dll!00000000590291fd() Unknown
nvoglv64.dll!000000005903437d() Unknown
nvoglv64.dll!00000000590452e7() Unknown
nvoglv64.dll!0000000058ee8ffe() Unknown
nvoglv64.dll!00000000590095e2() Unknown
nvoglv64.dll!0000000058febb4d() Unknown
nvoglv64.dll!0000000058febc60() Unknown
nvoglv64.dll!0000000058ef9e66() Unknown
nvoglv64.dll!0000000058ef9fd5() Unknown
nvoglv64.dll!0000000058ef9dc4() Unknown
nvoglv64.dll!0000000058ef98c6() Unknown
nvoglv64.dll!0000000058ee355a() Unknown
opengl32.dll!wglSwapBuffers()   Unknown
gdi32full.dll!SwapBuffers() Unknown

1 个答案:

答案 0 :(得分:3)

在彻底检查代码和相关输入数据之前,我们只能推测可能的原因。

查看调用链中的重复块,您可能在驱动程序中的某处无限递归时触发了堆栈。这可能是由于传递给OpenGL API调用的错误参数或者由于OpenGL实现中的错误引起的。在指责Nvidia或Microsoft之前,您应该彻底检查您的程序。为了调试此错误,您可以尝试以下操作:

  • 在其他任何事情之前,实施适当的OpenGL错误检查。 确保从所有OpenGL调用中检索返回代码,检查它们是否失败,打印调试消息并触发断点或在任何这些调用失败时终止程序(参见例如here)。在调试模式下实现调试回调扩展,如here
  • 在传统的C ++调试器下运行程序,就像在Visual Studio中一样。检查堆栈,并堆积可能的损坏。启用更多编译器警告,如果他们能找到任何可疑的东西,请尝试各种静态代码检查器和运行时分析器。
  • 在图形调试器下运行程序,例如Nvidia Nsight,并在管道的各个阶段和着色器中查找API调用中可能出现的错误
  • 查找并隔离导致错误的OpenGL函数调用。逐渐删除或注释掉看起来最可疑的代码片段(例如,更接近崩溃的代码,使用堆内存的代码等)。查看错误是否消失。如果是,则可能已删除导致错误的代码。将它带回来,看看是否再次出现错误。从大块代码开始,逐步减少删除的代码量,使搜索更精确。最终目标是提出一个再现错误的minimal code example
  • 当您找到它时,请在StackOverflow上发布此最小代码(例如,将您的问题添加为更新),以便社区可以将其检出。
  • 如果您的最小示例中没有错误,但它崩溃了,请将错误报告(包括最小示例代码)提交给Nvidia。同时,您也可以尝试不同的驱动程序版本,看看它们是否受到影响。
  • 您也可以尝试在Intel或AMD显卡上运行代码。例如,您已将英特尔图形集成到CPU中。如果问题也可以在另一个GPU上观察到,那么很可能不是Nvidia的错(两个不同的供应商在同一个地方发生同样的错误的可能性很小)。
  • 如果您的代码可以跨操作系统移植,或者至少是最小的示例,请尝试在另一个操作系统上构建并运行它。 Linux有很好的工具来调试C ++代码。有时只需更改编译器就会发现许多明显的错误。此外,您将拥有valgrind,clang清洁剂和OpenGL堆栈的不同实现,包括图形驱动程序(例如,有两种不同的Nvidia驱动程序实现,Nvidia的专有驱动程序和开源Nouveau驱动程序)。 Linux上还有与OpenGL相关的调试工具。
  • 请注意,在解析代码时试图隔离错误的呼叫时,您可能找不到一个,因为在某些情况下需要多次调用来引发问题。这些调用可以彼此相邻,或者它们可以分布在多个渲染帧上。当使用多线程和/或多个上下文时,事情变得特别困难。在这些情况下,最小化代码量,删除线程和上下文应该会有所帮助。
  • 请注意,错误未出现在您之前的配置(例如,不同的Windows版本)或其他供应商的OpenGL实现上这一事实并不一定意味着没有错误。它可能被不同的实现隐藏或忽略。在满足特定条件之前,某些错误可能不会显现。您尝试的配置越多(操作系统,编译器,OpenGL实现,驱动程序),您可以暴露的错误就越多。希望上面的提示可以帮助您找到这些错误和条件。

快乐的调试!