为什么 .NET 不记录 StackOverflow 异常的堆栈跟踪?

发布于 2024-12-05 05:26:42 字数 726 浏览 1 评论 0原文

如果我这样写:

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 能够记录堆栈跟踪。显然,堆栈跟踪可以通过某种方式供外界使用。如果运行时由于检测到堆栈溢出而终止进程,那么它也知道堆栈是什么。

在具有许多复杂交互的大型应用程序中,通常不可能重新创建导致堆栈溢出的条件。在这种情况下,堆栈跟踪是弄清楚发生了什么情况的唯一方法。为什么微软认为记录这些信息并不重要?是否存在不明显的合理设计决策?

If I write this:

class Program
{
    static void Main(string[] args)
    {
        throw new Exception("lol");
    }
}

and run the exe from the command line, I get two entries in my event log. One is an application error that says there was an unhandled exception, and the other contains the stack trace with the source as .NET Runtime.

If I write this:

class Program
{
    static void Main(string[] args)
    {
        Recurse4Evr();
    }

    static void Recurse4Evr()
    {
        Recurse4Evr();
    }
}

I only get one entry in my event log, which says Application Error and that there was a stack overflow exception. There isn't that second entry with the stack trace, so it's basically useless.

Why isn't the stack trace also logged? If I setup DebugDiag and attach it to my process and then there is a stack overflow, DebugDiag is able to log the stack trace. Obviously the stack trace is available to the outside world in some way. If the runtime is terminating the process because it detected a stackoverflow, then it also knows what the stack is.

In large applications that have many complex interactions, it is often not possible to recreate the conditions that led to a stack overflow. In this situation, a stack trace is the only way to figure out what happened. Why did microsoft decide it wasn't important to log this information? Was there a legitimate design decision that isn't obvious?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

失去的东西太少 2024-12-12 05:26:42

堆栈溢出被认为是不可恢复的情况,因此运行时会终止进程。

总结:

来自 Damien_The_Unknowner

来自 StackOverflowExceptions:

在 .NET Framework 的早期版本中,您的应用程序可以捕获 StackOverflowException 对象(例如,从无界递归中恢复)。但是,目前不鼓励这种做法,因为需要大量额外代码才能可靠地捕获堆栈溢出异常并继续程序执行。

从 .NET Framework 2.0 版开始,try-catch 块无法捕获 StackOverflowException 对象,并且默认情况下会终止相应的进程。因此,建议用户编写代码来检测和防止堆栈溢出。例如,如果您的应用程序依赖于递归,请使用计数器或状态条件来终止递归循环。请注意,托管公共语言运行时 (CLR) 的应用程序可以指定 CLR 卸载发生堆栈溢出异常的应用程序域并让相应的进程继续运行。有关详细信息,请参阅 ICLRPolicyManager 接口和托管公共语言运行时。


来自 JaredPar

从 2.0 开始,只能捕获 StackOverflow 异常在以下情况下。

  1. CLR 在托管环境中运行,其中主机专门允许处理 StackOverflow 异常
  2. stackoverflow 异常是由用户代码引发的,而不是由于实际的堆栈溢出情况 (参考)

Stack overflow is considered a non-recoverable situation and for such the runtime kills the process.

to sum up:

from Damien_The_Unbeliever

From the MSDN page on StackOverflowExceptions:

In prior versions of the .NET Framework, your application could catch a StackOverflowException object (for example, to recover from unbounded recursion). However, that practice is currently discouraged because significant additional code is required to reliably catch a stack overflow exception and continue program execution.

Starting with the .NET Framework version 2.0, a StackOverflowException object cannot be caught by a try-catch block and the corresponding process is terminated by default. Consequently, users are advised to write their code to detect and prevent a stack overflow. For example, if your application depends on recursion, use a counter or a state condition to terminate the recursive loop. Note that an application that hosts the common language runtime (CLR) can specify that the CLR unload the application domain where the stack overflow exception occurs and let the corresponding process continue. For more information, see ICLRPolicyManager Interface and Hosting the Common Language Runtime.


from JaredPar

Starting with 2.0 a StackOverflow Exception can only be caught in the following circumstances.

  1. The CLR is being run in a hosted environment where the host specifically allows for StackOverflow exceptions to be handled
  2. The stackoverflow exception is thrown by user code and not due to an actual stack overflow situation (Reference)
你在我安 2024-12-12 05:26:42

这显然是不可能的。如果您想要堆栈跟踪以便找到导致应用程序终止的违规代码,则需要附加第 3 方工具,例如 DebugDiag 或 AdsPlus。祝你好运,这些工具基本上没有文档。

This is apparently not possible. If you want a stack trace so you can find the offending code that killed your application, you need to attach a 3rd party tool like DebugDiag or AdsPlus. Good luck, there is basically no documentation for these tools.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文