【问题标题】:Exceptions that can't be caught by try-catch block in application code应用程序代码中的 try-catch 块无法捕获的异常
【发布时间】:2012-11-26 12:29:41
【问题描述】:

MSDN 声明 StackOverflowException can't be caught by try-catch block 从 .NET Framework 2 开始。

从 .NET Framework 2.0 版开始,StackOverflowException 对象无法被 try-catch 块捕获,相应的进程默认终止。

还有其他具有相同行为的例外吗?

【问题讨论】:

  • @Oded 请参阅备注部分“版本注意事项”块。引用:“从 .NET Framework 2.0 版开始,StackOverflowException 对象无法被 try-catch 块捕获,相应的进程默认终止。”
  • @Blachshma 亲爱的编辑们,你能教我这些大写字母是什么意思吗?
  • @BorisTreukhov 什么大写字母
  • 为什么这个问题被关闭了? .NET 程序员不应该知道为什么他们的应用程序在没有诊断的情况下崩溃到桌面?

标签: c# exception


【解决方案1】:

是的,还有其他一些:

  • ThreadAbortedException 很特殊。除非 catch 块调用 ResetAbort(),否则它总是会在被捕获时重新引发。当 CLR 粗鲁地中止线程时,它是完全无法捕获的。例如,当 AppDomain 被卸载时完成,通常在程序退出时完成。

  • 由本机代码启动的线程中的非托管代码引发的任何本机异常都是无法捕获的。这里的常见场景是启动自己的线程的 COM 组件。 CLR 无法捕获此类异常,它不了解线程并且无法注入 catch 块。如果本机代码未捕获异常,则 Windows 终止进程。

  • 终结器抛出的任何异常,除非它们是关键终结器。他们将中止终止进程的终结器线程。

  • 从 .NET 4.0 开始,ExecutionEngineException 是无法捕获的。当 CLR 检测到其内部数据结构被破坏时,它会抛出它。最常见的情况是垃圾收集器忙时引发的 AccessViolationException。在 GC 堆受损时继续执行托管代码是一个冒险的提议,并且可以利用,.NET 4 完全放弃了它。

  • 从 CLR 的 .NET 4.0 版本开始,但也可能存在于与早期版本互操作的非托管代码中,Microsoft 的安全 CRT 可以在检测到安全问题时立即终止程序。这实际上并不是一个异常,该过程会立即终止,因为代码认为该过程已受到损害并且无法安全地处理异常。一个常见的情况是原生函数的堆栈帧被破坏,这是原生代码中的一个常见问题,被病毒代码用来修改返回地址以运行任意代码。一种称为“堆栈缓冲区溢出”的攻击场景。在 .NET 4.0 发布初期,CLR 代码中有一些误报,但我已经有一段时间没有看到了。您可以通过编写超出 stackalloc 范围的内容自行触发此类中止。

  • 非常臭名昭著的是,当您在 64 位操作系统的 WOW64 仿真层中以 32 位模式运行代码并且连接了调试器时,Windows 消息处理程序会引发异常。以 Winforms 中麻烦的 Load 事件而闻名,但也出现在其他消息和其他运行时环境中。丑陋的细节在this answer

  • 从 .NET 4.5 开始,Microsoft 将异常归类为 损坏状态异常 (CSE)。它们可以被捕获,但这只能由顶级异常处理程序来完成,该处理程序除了为用户的利益生成诊断信息并无条件终止应用程序外,什么也不做。后台程序在this magazine article 中提供。

  • 在您的代码开始运行之前抖动引发的任何异常都无法被捕获或报告。无法编译 Main() 方法是常见的情况,通常是 FileNotFoundException。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-11
    • 1970-01-01
    • 1970-01-01
    • 2014-03-22
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    相关资源
    最近更新 更多