【问题标题】:Detecting if an exception is a Corrupted State Exception检测异常是否为损坏状态异常
【发布时间】:2014-10-15 14:14:21
【问题描述】:

我有一些调用 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.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) 在 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

【问题讨论】:

  • 异常的类型是什么?
  • 这是一个 CSE,我只是添加了 CSE 处理代码,因为类型和调用堆栈是我所追求的......由于 CSE 没有被处理,我得到的只是一个停止。 .. 我将从事件查看器中获得的内容添加到问题中
  • 你知道Exceptiontype 吗?如果是这样,您可以使用catch(CorruptedStateException ex) 来隔离该特定异常。
  • 没有像 CorruptedStateException 这样的东西,CSE 根本不是从 Exception 派生的,它是完全不同的东西。您使用泛型 (Exception ex) 捕获它并将注释添加到要捕获它的方法中,然后仅针对该方法将其重定向到 Exception。这是 .Net 4 中的一个变化 ...这是一篇关于它的好帖子 csbubblog.wordpress.com/2011/12/20/c4-cse
  • 另一个更简洁的:csharp.2000things.com/2013/08/28/…

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


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 在我在那里简化的实际方法中还有很多问题。但我明白你关于将它移到更高的观点......我会将它移到 appDomin 部分的顶部,现在它更深了。谢谢,
  • CSE 会在 appDomain 中冒泡吗?如果 CSE 扔在里面,父母会抓住它吗?
猜你喜欢
  • 2023-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-15
  • 2017-02-18
  • 2012-02-16
  • 2019-08-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多