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

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

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

是否存在相同行为的其他exception?

是的,还有其他一些:

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

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

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

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

  • 从CLR的.NET 4.0版本开始,但可能也存在于您在早期版本中互操作的非托管代码中,Microsoft的安全CRT可以在检测到安全问题时立即终止程序。 这实际上并不是一个例外,由于代码认为流程受到破坏而无法安全地处理exception,因此流程会立即终止。 常见的情况是本机函数的堆栈框架被粉碎,这是本机代码中的常见问题,并且由病毒代码用于修改返回地址以运行任意代码。 一种称为“堆栈缓冲区溢出”的攻击场景。 在.NET 4.0发布之后的早期,CLR代码中出现了一些错误警报但我在很长一段时间内都没有看到过。 您可以通过写入stackalloc的范围来自行触发这样的中止。

  • 相当臭名昭着,当您在64位操作系统上的WOW64仿真层中以32位模式运行代码并且连接了调试器时,Windows消息处理程序抛出exception。 以Winforms中令人烦恼的Load事件而闻名,但也出现在其他消息和其他运行时环境中。 丑陋的细节在这个答案中 。

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

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