检测异常是否为损坏状态异常

时间:2014-10-15 14:14:22

标签: c# exception visual-studio-2013 corrupted-state-exception

我有一些调用Rotativa的代码,它调用了wkhtml2pdf。我怀疑从行为中我看到wkhtml2pdf.exe导致损坏的状态异常(CSE)被抛出。我想抓住并记录CSE,如果抛出,我可以追踪它发生的位置。

当我在调试器中让应用程序一夜之间运行时,当我回来时VS已关闭。有时它已重新启动,有时不会。怀疑内存腐败我开始研究并偶然发现了CSE处理。

我正在做这样的事情:

[HandleProcessCorruptedStateExceptions]
void DoStuff()
{
     try
     {
          DOThatThingThatMakesTheDebuggerHaltAndShutDown();
     }
     catch(Exception ex)
     {
            //how do I detect that it's a CSE in here, so I can log it especially blatantly
     }
}

有没有办法检测常规捕获中的异常是否为CSE?

我看到一个kludge,他们有2个一般的例外条款。内部的不处理CSE并设置标志。如果在没有旗帜的情况下调用外部,那么它就是CSE,但我希望能有更清洁的东西。我想做的是记录这个不好的状态,然后将它传递给应用程序以正常冒泡。

当我查看导致VS2013失败的事件日志中的错误时,我得到了这个:

  

应用程序:devenv.exe Framework版本:v4.0.30319描述:   由于未处理的异常,进程被终止。例外信息:   异常代码c0000005,异常地址4DA44C1F堆栈:at   Microsoft.VisualStudio.Debugger.Clr.NativeDkmClrModuleInstance.ProcF4BC786AEBAC294EE9C4C0BB1B0F56A7(IntPtr的,   IntPtr ByRef)at   Microsoft.VisualStudio.Debugger.Clr.DkmClrModuleInstance.GetMetaDataImport()   在   Microsoft.IntelliTrace.Concord.MetadataHelper..ctor(Microsoft.VisualStudio.Debugger.Clr.DkmClrModuleInstance)   在   Microsoft.IntelliTrace.Concord.Integration.CpdeNotifyPointServiceAdapter.InstallBreakpoint(Microsoft.VisualStudio.Debugger.Clr.DkmClrModuleInstance,   Microsoft.VisualStudio.Debugger.Interop.Internal.NP_INSTALL_REQUEST)
  在   Microsoft.IntelliTrace.Concord.Integration.CpdeNotifyPointServiceAdapter.BindToModule(Microsoft.VisualStudio.Debugger.Clr.DkmClrModuleInstance)   在   Microsoft.IntelliTrace.Concord.IntelliTraceProcessState.AlertModuleLoad(Microsoft.VisualStudio.Debugger.DkmModuleInstance)   在   Microsoft.IntelliTrace.Concord.NotifyPoints.NotifyPointManager.OnModuleInstanceLoad(Microsoft.VisualStudio.Debugger.DkmModuleInstance,   Microsoft.VisualStudio.Debugger.DkmWorkList,   Microsoft.VisualStudio.Debugger.DkmEventDescriptorS)at   Microsoft.VisualStudio.Debugger.EntryPoint.IDkmModuleInstanceLoadNotification_OnModuleInstanceLoad(IntPtr的,   IntPtr,IntPtr,IntPtr)

接着是:

  

错误应用程序名称:devenv.exe,版本:12.0.30501.0,时间   标记:0x5361f453错误模块名称:vsdebugeng.impl.DLL,版本:   12.0.30501.0,时间戳:0x5361f482异常代码:0xc0000005故障偏移量:0x00094c1f故障进程id:0x1c9c故障应用程序   开始时间:0x01cfe7cc0cf50465故障应用程序路径:C:\ Program   文件(x86)\ Microsoft Visual Studio 12.0 \ Common7 \ IDE \ devenv.exe   错误模块路径:C:\ Program Files(x86)\ Microsoft Visual Studio   12.0 \ Common7 \ Packages \ Debugger \ vsdebugeng.impl.DLL报告ID:097b17c6-5438-11e4-8409-001f2904053c

1 个答案:

答案 0 :(得分:4)

请记住,没有" CorruptedStateException"。它只是一个收集词,CLR团队选择的一组例外,过度讨厌"。他们故意没有记录他们在那个集合中放置了什么样的例外情况,除了那些"关于十几个"并且他们以Windows SEH例外开始。我知道的唯一一个肯定是该集合的是AccessViolationException。在你的情况下崩溃VS的那个。很常见,就像他们来的那样令人讨厌。

该功能已添加到.NET 4.0中,以帮助执行您所做操作的程序员,使用catch (Exception)捕获所有异常处理。然后让程序继续运行。这有一个很糟糕的诀窍,他们也抓住了真正令人讨厌的例外,他们永远不会抓到这种例外,因为他们保证不可恢复。通常是在不知不觉中。这导致的程序失败非常难以诊断,可能需要一段时间才能检测到错误行为。

我可以推测该集合中有哪些其他SEH例外。但这只是猜测。关键是你没有知道。使用[HandleProcessCorruptedStateExceptions]的任何方法都应该是一个外部异常处理程序,在线程入口处激活。像Main()。并且非常很少,SEH处理程序应该做的事情,让用户知道程序失败的原因并调用Environment.FailFast()。

所以编程catch (Exception) 没有属性现在很好,CLR会在寻找处理程序时跳过它。你不能不小心吞下讨厌的东西。您的情况可能有点不同,看起来像没有明确定义的线程入口点的加载项。使用try / catch将方法的主体移动到另一个方法中,并省略该方法的属性。要通过方法使用属性调用,它现在可以安全地假设它捕获了一个令人讨厌的属性。

当然,确保在捕获时不要让VS继续运行。调试器状态被破坏,调试会话肯定会结束,程序员试图继续使用它将会很糟糕。因此,显示一个消息框并快速失败或重新抛出。