如果我这样写:
class Program
{
static void Main(string[] args)
{
throw new Exception("lol");
}
}
并从命令行运行 exe,我在事件日志中看到两个条目。一个是应用程序错误,表明存在未处理的异常,另一个包含源为 .NET 运行时的堆栈跟踪。
如果我这样写:
class Program
{
static void Main(string[] args)
{
Recurse4Evr();
}
static void Recurse4Evr()
{
Recurse4Evr();
}
}
我的事件日志中只收到一项,其中显示“应用程序错误”并且存在堆栈溢出异常。堆栈跟踪中没有第二个条目,因此它基本上没有用。
为什么不记录堆栈跟踪?如果我设置 DebugDiag 并将其附加到我的进程,然后出现堆栈溢出,则 DebugDiag 能够记录堆栈跟踪。显然,堆栈跟踪可以通过某种方式供外界使用。如果运行时由于检测到堆栈溢出而终止进程,那么它也知道堆栈是什么。
在具有许多复杂交互的大型应用程序中,通常不可能重新创建导致堆栈溢出的条件。在这种情况下,堆栈跟踪是弄清楚发生了什么情况的唯一方法。为什么微软认为记录这些信息并不重要?是否存在不明显的合理设计决策?
堆栈溢出被认为是不可恢复的情况,因此运行时会终止该进程。
总结:
来自达米安_不信者 https://stackoverflow.com/questions/1599219/c-catch-a-stack-overflow-exception/1599236#1599236
从 MSDN 页面上堆栈溢出异常 http://msdn.microsoft.com/en-us/library/system.stackoverflowexception.aspxs:
在 .NET Framework 的早期版本中,您的应用程序可以捕获 StackOverflowException 对象(例如,从无界递归中恢复)。但是,目前不鼓励这种做法,因为需要大量附加代码才能可靠地捕获堆栈溢出异常并继续程序执行。
从 .NET Framework 2.0 版开始,StackOverflowException 对象无法被 try-catch 块捕获,并且默认情况下会终止相应的进程。因此,建议用户编写代码来检测和防止堆栈溢出。例如,如果您的应用程序依赖于递归,请使用计数器或状态条件来终止递归循环。请注意,托管公共语言运行时 (CLR) 的应用程序可以指定 CLR 卸载发生堆栈溢出异常的应用程序域并让相应的进程继续运行。有关详细信息,请参阅 ICLRPolicyManager 接口和托管公共语言运行时。
来自贾里德帕尔 https://stackoverflow.com/questions/1599219/c-catch-a-stack-overflow-exception/1599238#1599238
从 2.0 开始,StackOverflow 异常只能在以下情况下捕获。
- CLR 在托管环境中运行,其中主机专门允许处理 StackOverflow 异常
- stackoverflow 异常是由用户代码引发的,而不是由于实际的堆栈溢出情况(参考 http://blogs.msdn.com/jaredpar/archive/2008/10/22/when-can-you-catch-a-stackoverflowexception.aspx)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)