MSDN声明从.NET Framework 2开始的StackOverflowException
can't be caught by try-catch block。
从.NET Framework 2.0版开始,try-catch块无法捕获StackOverflowException对象,默认情况下会终止相应的进程。
是否存在相同行为的其他异常?
答案 0 :(得分:30)
是的,还有其他一些:
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)的异常。它们可以被捕获,但这应该只由顶级异常处理程序完成,该处理程序除了为用户的利益生成诊断并无条件终止应用程序之外什么都不做。 Backgrounder可在this magazine article。
无法捕获或报告在代码开始运行之前抖动引发的任何异常。无法编译Main()方法是常见的情况,通常是FileNotFoundException。