如果帖子太长,我很抱歉,但如果有人至少指出粗体标题,我会很高兴,并指出我正确的方向。我这几天遇到这个问题,但无法在网上找到答案。这些是我到目前为止发现的东西。
1.“访问冲突”异常崩溃了我的托管应用程序
我的 C# WinForms 应用程序有时会在 Windows 窗体 TabControl 中选择 TabPage 时以“访问冲突”异常(“尝试读取或写入受保护的内存”)关闭。从堆栈跟踪(在 Application.Run 周围尝试/捕获)我可以看到异常发生在System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
,在内部调用UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
。
-- 消息:试图读取或写入受保护的内存。 这通常表明其他内存已损坏。 - 堆栈跟踪: 在 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(味精和味精) 在 System.Windows.Forms.Application.ComponentManager .System.Windows.Forms.UnsafeNativeMethods .IMsoComponentManager.FPushMessageLoop (Int32 dwComponentID,Int32 原因,Int32 pvLoopData) 在 System.Windows.Forms.Application.ThreadContext .RunMessageLoopInner(Int32 原因,ApplicationContext 上下文) 在 System.Windows.Forms.Application.ThreadContext .RunMessageLoop(Int32 原因,ApplicationContext 上下文) 在 System.Windows.Forms.Application.Run(ApplicationContext 上下文) 在 MyApp.Program.Main()
2. 故障模块似乎是一个 COM 对象(ChartFX Client Server 6.2)
使用 WinDbg(加载了 SoS),我在 ChartFX.ClientServer.Core.dll(这是我们正在使用的 COM 图表组件)内部的非托管端捕获了它:
(ca84.c98c):访问冲突 - 代码 c0000005(第一次机会) 在任何异常处理之前报告第一次机会异常。 可以预期并处理此异常。 eax=00000000 ebx=06e67c38 ecx=06e67c38 edx=000018c6 esi=06e7df30 edi=317a9e80 eip=31666110 esp=0015e040 ebp=0015e08c iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246 ChartFX_ClientServer_Core!Ordinal5507+0x97b7: 31666110 8a404d mov al,byte ptr [eax+4Dh] ds:0023:0000004d=??
[编辑:]我也无法从 WinDbg 获得未管理的堆栈详细信息(它说“堆栈展开信息不可用”):
0:000> kP ChildEBP RetAddr 警告:堆栈展开信息不可用。以下框架可能是错误的。 0015e08c 3166288b ChartFX_ClientServer_Core!Ordinal5507+0x97b7 0015e394 3165a921 ChartFX_ClientServer_Core!Ordinal5507+0x5f32 0015e480 31678685 ChartFX_ClientServer_Core!Ordinal5496+0x26a 0015e568 3167bef4 ChartFX_ClientServer_Core!Ordinal5492+0x975 0015e668 316a356b ChartFX_ClientServer_Core!Ordinal5492+0x41e4 0015e77c 31709496 ChartFX_ClientServer_Core!Ordinal443+0x5745 0015e7d0 31707f70 ChartFX_ClientServer_Core!Ordinal2584+0x3cdc 0015e7f8 3170817d ChartFX_ClientServer_Core!Ordinal2584+0x27b6 0015e81c 3162fd76 ChartFX_ClientServer_Core!Ordinal2584+0x29c3 0015e86c 7719f8d2 ChartFX_ClientServer_Core!Ordinal899+0x6b6 0015e898 7719f794 USER32!GetMessageW+0x93 0015e910 771a06f6 USER32!GetWindowLongW+0x115 0015e940 771a069c USER32!CallWindowProcW+0x75 0015e960 747fcef4 USER32!CallWindowProcW+0x1b 0015e97c 747fd073 comctl32!Ordinal377+0x5c 0015e9e0 747fd027 comctl32!DefSubclassProc+0x92 0015ea04 747fd4e6 comctl32!DefSubclassProc+0x46 0015ea20 747fd073 comctl32!DefSubclassProc+0x505 0015ea84 747fd118 comctl32!DefSubclassProc+0x92 0015eae4 7719f8d2 comctl32!DefSubclassProc+0x137
3、Bug 不易复现(虽然一般5分钟内就可以引发)
我在几个 TabPages 中有几个 Chart 实例,这通常发生在我切换选项卡时。我仍然不知道如何重现它,除了在它发生之前切换这些选项卡几分钟,所以我不能使用我们的源代码管理来可靠地找到没有这个问题的构建。我通过 VS 设计器自动创建的托管 AxChart 包装类(从 AxHost 派生)访问图表。
4. 我的下一步应该是什么?
如果有人能指出我应该采取的下一步行动来找到真正的原因,我将不胜感激。实验(删除和返回代码)并没有多大好处,因为我不知道如何重现它,所以每次迭代都需要大量时间才能说服自己该错误仍然存在。
我发现人们经常建议“切换编译器优化”之类的东西,但由于异常不是确定性地抛出的,我不想简单地重新排列一些字节并希望它永远不会返回。