浏览MSDN,我发现了以下quote(强调我的):
OpCodes.Throw
抛出当前在评估堆栈上的异常对象。
堆栈过渡行为按顺序排列:
对象引用(异常)被压入堆栈。
- 醇>
从堆栈中弹出对象引用并抛出异常。
我找不到任何关于抛出异常是堆栈溢出异常的情况。当堆栈装满时,它是如何被压入堆栈的?
CLR是否始终为StackOverflowException
保留至少一些空间?它是否与所有其他例外分开处理?我们在这里甚至谈论相同的堆栈吗?
如果它立即弹出,为什么首先需要将它推入堆栈?或者,第2步不是由Throw操作码完成的,而是仅在捕获到异常时才执行?
这是在某处记录的(我希望在链接页面上预期)。
答案 0 :(得分:2)
OpCodes.Throw
这是一条MSIL指令,仅在程序故意引发异常时生成。由C#中的throw
关键字生成。除非程序员在鲍尔默峰的右侧,否则没有程序会抛出SOE。
SOE由操作系统生成,即SEH例外。操作系统可以告诉程序正在尝试在线程的已分配堆栈的末尾划线。底层操作系统功能是guard page。 CLR尽职尽责intercepts it并将其转换为托管例外。即将结束的地方,SOE是一个不可恢复的事故,您只能在控制台模式应用程序中获得诊断。线程拼命地离开堆栈空间以在托管代码中执行任何有意义的操作,甚至无法可靠地创建SOE对象。这是在CLR中预先分配的,这是你在内存分析器中众所周知的。哪个回答你的问题。
来自的地方还有很多,操作系统生成的其他常见异常以及程序(MSIL)难以抛出的异常是NullReferenceException,DivideByZeroException,AccessViolationException等。所有非常讨厌,从来没有你想要捕获的那种,因为你将隐藏编程错误。
它们有一个子类,由CLR而不是操作系统抛出。实际上,这是一个次要的区别,因为CLR实际上是托管程序的操作系统。常见的有OutOfMemoryException,ExecutionEngineException,TypeLoadException,MissingMethodException等。你永远也不想抓住他们。
长话短说,程序失败不仅仅是由编译的C#程序报告的。操作系统,抖动和CLR也有理由抱怨。