【问题标题】:How to find out the out-most stacks when `System.StackOverflowException` is raised?引发`System.StackOverflowException`时如何找出最外面的堆栈?
【发布时间】:2017-06-09 23:37:27
【问题描述】:

在 Visual Studio 2015 for C# 中,我调试了一个程序。调试器在某处暂停并引发System.StackOverflowException

在 mscorlib.dll 中发生了“System.StackOverflowException”类型的未处理异常

这意味着正在进行无限递归。

我想找出最初调用了哪个方法,然后导致了异常,所以我转向调用堆栈窗口,但是堆栈太多,以至于最外面的堆栈已经从调用堆栈窗口中截断:

...
Visual Studio 支持的最大堆栈帧数 已超过。

  • System.StackOverflowException 发生时,有什么方法可以找出最外面的堆栈吗?

  • 有没有办法限制在引发System.StackOverflowException 之前的最大堆栈帧数,以便所有堆栈帧都可以显示在“调用堆栈”窗口中?

谢谢。

【问题讨论】:

  • 第一次看到第二条消息时,当我遇到 Stackoverflow 异常时,总是可以查看调用堆栈。
  • 您是否看不到足够的堆栈以了解您的调用周期在哪里,然后从那里开始工作?
  • 使用ETW to trace Exception raising,在这里您可以看到引发异常时的堆栈。使用 WPR 和我的配置文件来捕获数据并分析 WPA 中的 ETL

标签: c# visual-studio


【解决方案1】:

之前有没有办法限制栈帧的最大数量 引发 System.StackOverflowException,以便所有堆栈帧 可以在调用堆栈窗口中显示吗?

临时 hack:缩小堆栈帧,直到找到原因。然后将大小恢复为默认值。没有针对此的项目设置,但这个旧技巧可能仍然有效:

EDITBIN.EXE /STACK:<stacksize> file.exe

有什么方法可以找出最外面的堆栈 System.StackOverflowException 发生了吗?

一种方法是使用 Trace 或 Debug 类将所有调用的日志记录添加到任何递归函数函数中。调用此函数“Cursed()” 如果您的代码中有 10 个位置调用“Cursed()”,则在调用之前为每个位置添加跟踪:

Trace.WriteLine("Foo calling Cursed()");
... 
Trace.WriteLine("Bar calling Cursed()");

你可以添加任何你想要的变量。

您可以在 support.microsoft.com 上查看如何使用跟踪和调试,“如何在 Visual C# 中跟踪和调试”-https://support.microsoft.com/en-us/help/815788/how-to-trace-and-debug-in-visual-c

如果您查看调试或跟踪输出,您会看到哪些函数和值触发了无限递归。

添加更多日志记录、断言、条件断点以进一步缩小范围。

【讨论】:

    【解决方案2】:

    您可以使用我的Runtime Flow 工具(30 天试用)运行您的程序,并且应该能够看到 StackOverflowException 之前的所有方法调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-18
      • 2013-10-30
      • 1970-01-01
      • 2011-11-24
      • 1970-01-01
      • 1970-01-01
      • 2012-09-13
      相关资源
      最近更新 更多