WPF应用程序和DirectX光栅化器中的访问冲突异常

8

我有一个WPF应用程序,在进行一些琐碎的操作(打开和关闭一些应用程序控件)后就崩溃了。当我打开崩溃转储文件时,我看到异常是:

FAULTING_IP: 
rgb9rast!D3D8RGBRast::CRGBContext::PackGenVertex+b4
000007fe`f7625b88 428b0c10        mov     ecx,dword ptr [rax+r10]

EXCEPTION_RECORD:  ffffffffffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: 000007fef7625b88 (rgb9rast!D3D8RGBRast::CRGBContext::PackGenVertex+0x00000000000000b4)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 0000000000000000
Parameter[1]: 000000009f011620
Attempt to read from address 000000009f011620

这表明在DirectX光栅化中发生了访问冲突错误,故障线程堆栈跟踪为(我省略了调用地址)。

rgb9rast!D3D8RGBRast::CRGBContext::PackGenVertex+0xb4
rgb9rast!D3D8RGBRast::CRGBContext::DoDrawOneGenIndexedPrimitive+0x72b
rgb9rast!D3D8RGBRast::CRGBContext::DP2DrawIndexedPrimitive2+0x1d4
rgb9rast!DX8SDDIFW::SDP2MFnParser::ParseDP2<DX8SDDIFW::CStdDrawPrimitives2<D3D8RGBRast::CRGBContext,D3D8RGBRast::CRGBStateSet,D3D8RGBRast::static_hash_map<unsigned long,D3D8RGBRast::CRGBStateSet,32,D3D8RGBRast::hash<unsigned long>,std::equal_to<unsigned long>,D3D8RGBRast::allocator<std::pair<unsigned long const ,D3D8RGBRast::CRGBStateSet> > >,DX8SDDIFW::CDP2DataWrap<D3D8RGBRast::SDP2NextCmdExt>,D3D8RGBRast::block<long (__cdecl D3D8RGBRast::CRGBContext::*)(DX8SDDIFW::CDP2DataWrap<D3D8RGBRast::SDP2NextCmdExt> & __ptr64,_D3DHAL_DP2COMMAND const * __ptr64,void const * __ptr64) __ptr64,89>,D3D8RGBRast::block<long (__cdecl D3D8RGBRast::CRGBContext::*)(_D3DHAL_DP2COMMAND const * __ptr64,void * __ptr64) __ptr64,89> >::TMFnCaller,D3D8RGBRast::block<long (__cdecl D3D8RGBRast::CRGBContext::*)(DX8SDDIFW::CDP2DataWrap<D3D8RGBRast::SDP2NextCmdExt> & __ptr64,_D3DHAL_DP2COMMAND const * __ptr64,void const * __ptr64) __ptr64,89>,DX8SDDIFW::CConstDP2CmdIterator<D3D8RGBRast::SDP2NextCmdExt> >+0x69
rgb9rast!DX8SDDIFW::CStdDrawPrimitives2<D3D8RGBRast::CRGBContext,D3D8RGBRast::CRGBStateSet,D3D8RGBRast::static_hash_map<unsigned long,D3D8RGBRast::CRGBStateSet,32,D3D8RGBRast::hash<unsigned long>,std::equal_to<unsigned long>,D3D8RGBRast::allocator<std::pair<unsigned long const ,D3D8RGBRast::CRGBStateSet> > >,DX8SDDIFW::CDP2DataWrap<D3D8RGBRast::SDP2NextCmdExt>,D3D8RGBRast::block<long (__cdecl D3D8RGBRast::CRGBContext::*)(DX8SDDIFW::CDP2DataWrap<D3D8RGBRast::SDP2NextCmdExt> & __ptr64,_D3DHAL_DP2COMMAND const * __ptr64,void const * __ptr64) __ptr64,89>,D3D8RGBRast::block<long (__cdecl D3D8RGBRast::CRGBContext::*)(_D3DHAL_DP2COMMAND const * __ptr64,void * __ptr64) __ptr64,89> >::DrawPrimitives2+0x345
rgb9rast!DX8SDDIFW::CSubDriver<D3D8RGBRast::CRGBDriver,D3D8RGBRast::CRGBContext,D3D8RGBRast::CRGBSurfAllocator,D3D8RGBRast::CRGBPerDDrawData,D3D8RGBRast::set<D3D8RGBRast::CRGBContext * __ptr64,std::less<D3D8RGBRast::CRGBContext * __ptr64>,D3D8RGBRast::allocator<D3D8RGBRast::CRGBContext * __ptr64> >,D3D8RGBRast::map<_DDRAWI_DIRECTDRAW_LCL * __ptr64,D3D8RGBRast::CRGBPerDDrawData,std::less<_DDRAWI_DIRECTDRAW_LCL * __ptr64>,D3D8RGBRast::allocator<std::pair<_DDRAWI_DIRECTDRAW_LCL * __ptr64 const,D3D8RGBRast::CRGBPerDDrawData> > >,D3D8RGBRast::set<D3D8RGBRast::IRGBSurface * __ptr64,std::less<D3D8RGBRast::IRGBSurface * __ptr64>,D3D8RGBRast::allocator<D3D8RGBRast::IRGBSurface * __ptr64> >,DX8SDDIFW::SFakeEntryPointHook<D3D8RGBRast::CRGBDriver> >::DrawPrimitives2+0x26
d3d9!SwDrawPrimitives2+0x7c
d3d9!CD3DDDIDX8::FlushStates+0x161
d3d9!CD3DBase::FlushStatesNoThrow+0x22
d3d9!CVertexBuffer::Lock+0xce
d3d9!CVertexBufferMT::Lock+0x7e
d3d9!CTLStream::Lock+0x6d
d3d9!CD3DDDIDX8::StartPrimTL+0x3b
d3d9!CD3DDDIDX8::ProcessIndexedPrimitiveC+0xa0
d3d9!CD3DBase::DrawIndexedPrimitive+0x489
wpfgfx_v0400!CD3DDeviceLevel1::DrawIndexedTriangleList+0x49
wpfgfx_v0400!CHw3DGeometryRenderer<unsigned long>::Render+0x152
wpfgfx_v0400!CHwShader::FixedFunctionDrawMesh3D+0x158
wpfgfx_v0400!CHwShader::DrawMesh3D+0x88
wpfgfx_v0400!CHwSurfaceRenderTarget::DrawMesh3D+0x1fb
wpfgfx_v0400!CHw3DSoftwareSurface::DrawMesh3D+0x38
wpfgfx_v0400!CSwRenderTargetSurface::DrawMesh3D+0x49
wpfgfx_v0400!CMetaRenderTarget::DrawMesh3D+0xee
wpfgfx_v0400!CModelRenderWalker::RealizeMaterialAndRender+0x17a
wpfgfx_v0400!CModelRenderWalker::ProcessMaterialAndRender+0x160
wpfgfx_v0400!CModelRenderWalker::RenderGeometryModel3D+0x11b
wpfgfx_v0400!CModelRenderWalker::PreSubgraph+0x19
wpfgfx_v0400!CModelIterator::Walk+0x64
wpfgfx_v0400!CModelRenderWalker::RenderModels+0x70
wpfgfx_v0400!CRender3DContext::PreSubgraph+0xd3
wpfgfx_v0400!CGraphIterator::Walk+0x4b
wpfgfx_v0400!CRender3DContext::Render+0xd9
wpfgfx_v0400!CDrawingContext::Render3D+0x277
wpfgfx_v0400!CMilViewport3DVisual::RenderContent+0x50
wpfgfx_v0400!CDrawingContext::PreSubgraph+0x766
wpfgfx_v0400!CGraphIterator::Walk+0x4b
wpfgfx_v0400!CDrawingContext::DrawVisualTree+0x23d
wpfgfx_v0400!CDrawingContext::Render+0x393
wpfgfx_v0400!CSlaveHWndRenderTarget::Render+0x206
wpfgfx_v0400!CRenderTargetManager::Render+0x4d
wpfgfx_v0400!CComposition::Render+0x28
wpfgfx_v0400!CComposition::ProcessComposition+0x13a
wpfgfx_v0400!CComposition::Compose+0x51
wpfgfx_v0400!CPartitionThread::RenderPartition+0x28
wpfgfx_v0400!CPartitionThread::Run+0x61
wpfgfx_v0400!CPartitionThread::ThreadMain+0x1c
kernel32!BaseThreadInitThunk+0xd
ntdll!RtlUserThreadStart+0x1d

当我检查应用程序时,只有部分PC会出现这种情况。所有电脑都有.Net 4.5和Directx 11。
导致这种情况的原因是什么?在调试/调查转储文件时,我看不到任何可以导致此问题的托管代码。
我唯一的提示是应用程序中有一些3D内容,可能与故障线程堆栈跟踪中的某些3D渲染方法相关。


1
你能理解发生了什么吗?这个问题解决了吗?我想我们在转储文件中有相同的堆栈跟踪。任何帮助都将不胜感激(即使您不记得 :))。 - Chuck Norris
1
@ChuckNorris 作为部分解决方案/测试,尝试关闭软件渲染,看看是否仍然会出现崩溃。另外,如果是我,我会尝试创建一个 [MCVE] 来重现这个问题。我知道你需要花费很多时间缓慢地删除代码以将其缩小到较小的规模,但很可能会让你朝着原因迈进一步。 - Lynn Crumbling
2
有一个相关的问题(现在已被删除,标记为“废弃”),没有得到回答:https://stackoverflow.com/questions/57219993/app-frozen-inside-wpfgfx-v0400-dll-utility-polygonbounds-and-utility-pathgeometr。也许那里有一些相关或有用的信息。 - StayOnTarget
1
@LynnCrumbling 很棒的想法!谢谢。 - StayOnTarget
1
这是被提及的半相关删除问题的文本:https://pastebin.com/cWtDB0D7 - StayOnTarget
显示剩余10条评论
1个回答

2
DirectX Rasterize(如果我没记错的话,是9和以上版本)决定了三角形如何绘制。针对三角形的三个点,你可以顺时针或逆时针绘制它们,同时你可以确定三角形表面是向内还是向外的 - 这提供了交点。此外,它还提供了设置Multisample和AntialiasedLine的功能——这些功能(高处理能力)允许更平滑的线条渲染。请记住,在2D屏幕上不存在真正的直线——你可能熟悉计算机图形中的阶梯效应或Jaggies。
现在当我们使用DirectX时,实际上是在编程电脑显卡的GPU。因此,显卡必须具备DirectX准备就绪的能力——这取决于版本。
检查您的PC硬件并确定内置或PCI显卡是否符合DirectX11规范。
此外,您可以调整WPF应用程序的渲染设置——如果您愿意,可以将其调低或完全关闭,位置在这里
更多信息:
来自MSDN文档
注意ProcessRenderMode指定了偏好,但不一定会改变实际的渲染模式。系统的其他部分可能会覆盖此偏好并强制将系统切换到软件渲染。
您可以通过在Windows搜索框中使用dxdiag来检查系统的DirectX信息(我认为适用于Windows 7及以上版本)。

感谢您的回答。正如我在其中一条评论中提到的,我们正在使用仅软件渲染,因此我不知道GPU如何参与其中。 另一方面,我们的应用程序中没有使用任何绘图等功能。这听起来像是在使用仅软件模式时发生的内部WPF错误。我们想了解哪个部分可能会导致这种情况,并且如何修复它。 - Chuck Norris
我看到你的更新了。但是我不知道我们如何修复这个错误。 - Chuck Norris
你能分享这个应用程序或者应用程序的演示吗? - Alex Leo
这是一个相当大的企业应用程序,我不认为我可以分享它。 - Chuck Norris
1
我完全理解 - 我唯一能建议的是在每个被渲染的窗口中设置SoftwareOnly - 或者添加一些日志记录以查看异常在流程中触发的位置 - - Alex Leo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接