StackOverflowException 是在哪里创建的?

Where is StackOverflowException created?

浏览 MSDN,我发现以下 quote(强调我的):

OpCodes.Throw

Throws the exception object currently on the evaluation stack.

The stack transitional behavior, in sequential order, is:

  1. An object reference (to an exception) is pushed onto the stack.

  2. The object reference is popped from the stack and the exception thrown.

关于抛出的异常是堆栈溢出异常的情况,我找不到任何信息。当堆栈已满时,如何将其压入堆栈?

CLR 是否总是至少为 WhosebugException 保留一些 space?它是否与所有其他异常分开处理?我们在这里讨论的是同一个堆栈吗?

如果立即弹出,为什么需要首先将其压入堆栈?或者步骤2不是由Throw操作码完成的,而是只有在捕获到异常时才完成?

这是否记录在某处(我希望它出现在链接页面上)。

  OpCodes.Throw

这是一条 MSIL 指令,仅在程序有意抛出异常时才会生成。由 C# 中的 throw 关键字生成。任何程序都不会抛出SOE,除非程序员在鲍尔默峰的右边。

SOE是操作系统产生的SEH异常。它是 OS 可以告诉程序正在尝试涂鸦超过线程分配堆栈的末尾。底层 OS 功能是 guard page. The CLR dutifully intercepts it 并将其转换为托管异常。它很快就会结束,SOE 是一个无法恢复的事故,您只能在控制台模式应用程序中获得诊断。该线程拼命地离开堆栈 space 以在托管代码中执行任何有意义的操作,它甚至无法可靠地创建 SOE 对象。这是在 CLR 中预先分配的,众所周知,您会在内存分析器中看到它。这回答了你的问题。

更多来自 OS 生成的其他非常常见的异常和程序 (MSIL) 很少抛出的异常是 NullReferenceException、DivideByZeroException、AccessViolationException 等。一切都非常讨厌,从来不是你想抓住的那种,因为你会隐藏一个编程错误。

它们有一个子类,由 CLR 而不是 OS 抛出。实际上,这是一个很小的区别,因为 CLR 实际上是托管程序的 OS。常见的有 OutOfMemoryException、ExecutionEngineException、TypeLoadException、MissingMethodException 等。你也永远不想抓住他们。


长话短说,程序失败不仅仅是编译的C#程序报告的。操作系统、抖动和 CLR 也有抱怨的理由。