如何在.NET中调试stackoverflowexception

Chr*_*sto 34 .net debugging

场景:

我刚刚开始实现一堆代码,但是当我执行它时,我会抛出一个StackOverflowException?StackOverflowException没有堆栈跟踪,所以我卡住了.我知道为什么会发生堆栈溢出,但要修复它我需要知道它的根目录是什么.

我得到的是:tag-you-it.dll中出现未处理的"System.StackOverflowException"类型异常

选项:

  1. 扫描所有更改并尝试确定问题所在.(可能很慢)
  2. 使用调试器并逐步执行直到找到问题.(可能比1好)
  3. 使用配置文件并查找最常用的方法.

PS:

这是一种假设情况(虽然并不常见),因此没有可用的代码.

Nei*_*ell 16

这几乎总是归因于递归.要么是调用自身的方法,要么是调用调用它的方法的方法,等等.

找到它:

  • 更新:我没有意识到,但显然你不能得到一个堆栈跟踪StackOverflowException(我想与无法捕获一个有关的事情).但是有办法获取转储这里提到.
  • ReSharper将显示调用自身的方法(它在侧栏中放置一个绿色小圈用于递归调用),但它不会捕获涉及两个或更多方法的递归.
  • 使用像ANTS Profiler这样的工具来查看哪些方法被调用次数最多.
  • 请留意可能会调用代码的事件,这些事件意味着同一事件再次触发,从而导致循环.

偶尔你会得到这样的拼写错误:

private string name;

public string Name
{
    get { return Name; } // Ooops! This is recursive, all because of a typo...
}
Run Code Online (Sandbox Code Playgroud)

这就是我个人现在更喜欢使用自动属性的原因之一.

  • 1.您没有获得具有SO异常的堆栈跟踪.2.递归可能是罪魁祸首,而resharper可能有所帮助,但是由于其他结构,它并不总是有助于找到循环循环.3.个人资料看起来不错. (4认同)

Bat*_*nit 11

WinDbg可以完成工作,甚至包括获得合理的(clr)堆栈跟踪.您需要获得WinDbg,除非您已经使用Visual Studio或Windows SDK安装它.注意:使用新GUI的"WinDbg预览"对我来说很好.

我建议从WinDbg开始你的过程,但当然你也可以把它附加到一个正在运行的过程,如果这更适合你.

注意:在启动进程后,CLR未加载,并且.loadby SOS.dll clr将失败("无法找到模块'clr').您必须等待加载CLR.一旦发生这种情况就停止执行执行:

  • sxe ld clr

完成后,您必须执行以下步骤(在命令窗口/行中输入):

  • SackOverflowException(不是 .loadby SOS.dll clr - 这会导致扩展被加载两次)
  • .loadby sos clr
  • !stoponexception -create System.StackOverflowException (继续调试)

触发StackOverflowException /等待它发生

  • g (将打印堆栈跟踪)

值得注意的来源:


小智 8

转到Debug,exception并选中'Common Language Runtime Exceptions'中的抛出复选框.现在,当您导致stackoverflow异常时,调试器将停止(最终)并显示调用堆栈.

  • 也许值得强调的是,您需要查看Visual Studio的调用堆栈窗口,而不是Exception的StackTrace,它不会被设置(可能是因为一旦堆栈已满,它就无法执行任何需要进一步使用堆栈的操作). (4认同)
  • 你确定它适用于堆栈溢出异常吗?它们的处理方式有点特殊. (3认同)

Bor*_*rja 5

您可以在调试模式下执行该程序并暂停它.在当前的callstack上,你可以看到有一种方法或一组方法多次出现,这些都是有问题的方法.在这个方法上加上一个断点,看看它一直在调用它自己.


And*_*lin 5

ProcDump工具帮助我们为调试问题在这里详细描述。脚步:

  1. 下载工具
  2. 运行进程,记下它的 ID
  3. 通过运行附加调试器procdump -accepteula -e 1 -f C00000FD.STACK_OVERFLOW -g -ma <process ID> d:\home\DebugTools\Dumps(目录必须存在)
  4. 使例外发生,procdump 将使您成为转储。
  5. 在 Visual Studio 中打开转储文件。对于我的示例应用程序,在打开转储文件后,VS 突出显示了发生 SO 的行。

我们可以通过启用CrashDiagnoser扩展在 Azure 上使用相同的技术,如此处所述。基本上它执行与上面相同的步骤。它生成的转储文件可以在 Visual Studio 中下载和打开。