我有一些代码正在调用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
}
}
是否有方法检测异常是否是General Catch中的CSE?
我看到他们有两个通用的例外条款。内部的不处理CSE并设置标志。如果外部的一个在没有标志的情况下被调用,那么它就是CSE,但我希望有更干净的东西。我想做的是记录这个糟糕的状态,然后将其传递给应用程序以正常弹出。
当我看到导致VS2013失败的事件日志中的错误时,我得到的是:
应用程序:devenv.exe Framework版本:v4.0.30119描述:进程由于未处理的异常而终止。异常信息:异常代码c0000005,异常地址4DA4C1F堆栈:位于Microsoft.VisualStudio.Debugger.Clr.NativeDkmClrModuleInstance.ProcF4BC786AEBAC294EE9C4C0BB1B0F56A7(IntPtr,IntPtr ByRef)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.DkmClrModuleIstance,Microsoft.VisualStudio.Debugger.Interop.Interal.NP_INSTALL_REQUEST)
在Microsoft.IntelliTrace.Concord.IIntegration.CpdeNotifyPointServiceAdapter.BindToModule(Microsoft.VisualStudio.Debugger.Clr.DkmClrModule实例)在Microsoft.IntelliTrace.Concord.IIntelliTraceProcessState.AlertModuleLoad(Microsoft.VisualStudio.Debugger.DkmModuleInstance)在Microsoft.IntelliTrace.Concord.NotifyPoints.NotifyPointManager.OnModuleInstanceLoad(Microsoft.VisualStudio.Debugger.DkmModuleInstance,Microsoft.VisualStudio.Debugger.DkmWorkList,Microsoft.VisualStudio.Debugger.DkmEventDescriptorS)Microsoft.VisualStudio.Debugger.EntryPoint.IDkmModuleInstanceLoadNotification_OnModuleInstanceLoad(IntPtr,IntPtr、IntPtr和IntPtr)
然后是:
出现故障的应用程序名称:devenv.exe,版本:12.0.30501.0,时间stamp: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 Studio12.0\Common7\Packages\Debugger\vsdebugeng.impl.DLL报告Id:097b17c6-5438-11e4-8409-001f2904053c
请记住,不存在"CorruptedStateException"这类情况。这只是一个收集词,CLR团队将其选为"过于恶劣"的一组例外。他们故意不记录他们在该集中放入了什么类型的异常,除了"大约有十几个",并且它们最初是作为Windows SEH异常。我所知道的唯一一个肯定在那个集合中的是AccessViolationException。在你的案例中导致VS崩溃的那个。很普通,很讨厌。
该功能被添加到.NET 4.0中,以帮助程序员使用catch (Exception)
处理所有异常。然后让程序继续运行。这有一个糟糕的byting技巧,他们也会捕捉到真正令人讨厌的异常,这种异常是他们永远不应该捕捉到的,因为它们肯定是不可恢复的。通常是无意中。这导致的程序故障非常难以诊断,可能需要一段时间才能检测到不当行为。
我可以推测集合中还有哪些SEH例外。但这只是猜测。关键是你不需要知道。任何具有[HandProcessCorruptedStateExceptions]的方法都应该是外部异常处理程序,在线程条目处激活。像Main()一样。并且很少做,这是SEH处理程序应该做的事情,只需让用户知道程序失败的原因并调用Environment.FailFast().
因此,在没有属性的情况下编程catch (Exception)
现在很好,CLR在查找处理程序时会跳过它。你不能不小心吞下这些讨厌的东西。您的情况可能有点不同,看起来像是一个没有定义良好的线程入口点的外接程序。将带有try/catch的方法体移到另一个方法中,并省略该方法上的属性。要由带有属性的方法调用,现在可以放心地假设它捕获了其中一个讨厌的对象。
当然,要确保当VS被捕获时,你不会让它运行。调试器状态被炸成碎片,调试会话肯定已经结束,程序员试图继续使用它的结果会很糟糕。因此,显示一个消息框并快速失败或重新引发。