一尘不染

应用程序代码中的try-catch块无法捕获的异常

c#

MSDN指出,从.NET Framework 2开始,StackOverflowException try-
catch块无法捕获

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

是否有其他具有相同行为的例外情况?


阅读 336

收藏
2020-05-19

共1个答案

一尘不染

是的,还有其他一些:

  • ThreadAbortedException是特殊的。除非捕获块调用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事件,但也出现在其他消息和其他运行时环境中。这个答案中有丑陋的细节。

  • 从.NET 4.5开始,Microsoft将异常分类为 损坏状态异常 (CSE)。它们 可以 被捕获,但是只能由顶级异常处理程序完成,该异常处理程序除了为用户的利益生成诊断并无条件终止应用程序之外,什么也不做。这本杂志文章提供了Backgrounder 。

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

2020-05-19