7

我有一些调用 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?

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

当我查看导致 VS2013 崩溃的事件日志中的错误时,我得到以下信息:

应用程序:devenv.exe 框架版本:v4.0.30319 描述:进程因未处理的异常而终止。异常信息:异常代码 c0000005,异常地址 4DA44C1F 堆栈:Microsoft.VisualStudio.Debugger.Clr.NativeDkmClrModuleInstance.ProcF4BC786AEBAC294EE9C4C0BB1B0F56A7(IntPtr, IntPtr ByRef) 上 Microsoft.VisualStudio.Debugger.Clr.DkmClrModuleInstance.GetMetaraceData.Conport() .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.IntelliTraceProcessState.AlertModuleLoad(Microsoft.VisualStudio.Debugger.DkmModuleInstance) 在 Microsoft.IntelliTrace.Concord.NotifyPoints 在 Microsoft.IntelliTrace.Concord.Integration.CpdeNotifyPointServiceAdapter.BindToModule(Microsoft.VisualStudio.Debugger.Clr.DkmClrModuleInstance) .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,时间戳:0x5361f453 错误模块名称:vsdebugeng.impl.DLL,版本:12.0.30501.0,时间戳:0x5361f482 异常代码:0xc0000005 错误偏移:0x00094c1f 错误进程 id: 0x1c9c 错误应用程序启动时间:0x01cfe7cc0cf50465 错误应用程序路径:C:\Program Files (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

4

1 回答 1

4

请记住,没有“CorruptedStateException”之类的东西。这只是一个收集词,一组 CLR 团队选择为“非常讨厌”的例外。他们故意不记录他们在该集合中放入了什么样的异常,除了“大约十几个”并且它们以 Windows SEH 异常开始。我知道的唯一一个肯定在那个集合中的是 AccessViolationException。在您的情况下使 VS 崩溃的那个。很常见,就像它们一样讨厌。

该功能已添加到 .NET 4.0 以帮助程序员做您所做的事情,使用catch (Exception). 然后让程序继续运行。这有一个糟糕的诀窍,它们还捕获真正令人讨厌的异常,它们永远不应该捕获的那种异常,因为它们保证是不可恢复的。常常不知不觉。这导致的程序故障很难诊断,可能需要一段时间才能检测到错误行为。

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

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

当然,请确保在 VS 捕获时不要让 VS 继续运行。调试器状态被炸成碎片,调试会话肯定已经结束,试图继续使用它的程序员会以失败告终。所以显示一个消息框并快速失败或重新抛出。

于 2014-10-15T16:23:09.780 回答