【问题标题】:How do I get from an ASP.NET process dump to a managed call stack?如何从 ASP.NET 进程转储到托管调用堆栈?
【发布时间】:2014-05-06 22:09:27
【问题描述】:

我们有一个大型 ASP.NET 应用程序,它偶尔会由于 StackOverflowExceptions 而崩溃。因为这些aren't handled very elegantly by .NET,我们被简化为事后调试,没有任何正常的异常日志和堆栈跟踪。一旦我们找到问题发生的位置,通常很容易解决;困难的部分是指出错误发生在代码库中的哪个位置。

我们在崩溃后获得的进程转储文件似乎对这项工作有很大帮助,但到目前为止,我们一直无法弄清楚如何最好地使用它。您可以(非常、非常、缓慢地)使用 Visual Studio“调试”该过程,但这基本上需要永远加载 MSFT 符号,然后不会为我们的应用程序 DLL 加载符号(因此您看不到有趣的部分调用堆栈)。

似乎必须有一条直截了当的方法:

  • 故障转储文件
  • 设置托管应用程序 DLL/PDB

到完整的托管调用堆栈;任何人都可以描述(或指向教程)这样做(使用 VS、WinDbg 或任何其他工具)吗?

【问题讨论】:

  • 我很想知道您在哪些领域发现了这些异常。我不记得曾经在 ASP.NET 中发现过 StackOverflowException。
  • @JohnSaunders:我们看到的一个例子是开发人员使用 Aggregate 和 Concat 而不是 SelectMany 组合一堆列表。最近的案例似乎是一个非常复杂的查询导致 EF 表达式访问者溢出堆栈(我怀疑一个很大的 IN 子句)。
  • 哇。感谢您的回答。这些可能无法在单元测试中捕获,我敢打赌 try/catch 不会捕获它们。
  • won't load the symbols for our application DLLs Debug -> Windows -> Modules 窗口,看看为什么找不到您的 pdb。(右键单击您的 dll 并选择“符号加载信息”)我认为您做得很好(MSFT 符号将被缓存并更快地加载第一次之后)

标签: c# windbg crash-dumps stack-overflow postmortem-debugging


【解决方案1】:

是的,有一种方法可以获取托管堆栈,等等。

您正在寻找的是WinDbgSOS.dll 调试器扩展。 SOS.dll 调试器扩展位于安装 .NET 框架的同一文件夹中(即 C:\Windows\Microsoft.NET\Framework\v4.0.30319\SOS.dll)

将 SOS.dll 加载到 WinDbg 后,您可以查询:

  • 托管调用堆栈:!clrstack
  • 托管线程:!threads
  • 堆栈(局部)变量!clrstack –l
  • 函数调用参数!clrstack -p
  • 关于对象的信息!做地址
  • 内存消耗!dumpheap
  • 对象持有对内存地址的引用 !gcroot 地址
  • 托管锁!syncblk

这是cheat-sheet with commands to get around using sos.dll

【讨论】:

  • 这听起来很棒。由于我从未使用过 WinDbg 或 SOS,您介意发布一个示例命令序列以访问调用堆栈吗?
  • 我跑得有点晚了,但如果你在谷歌上搜索如何使用 WinDbg 和 SOS.dll 进行调试,我相信你会找到一些教程。也就是说,你可能能够捕获这些异常并生成一些堆栈跟踪,这将消除使用 WinDbg + SOS.dll 的需要,尽管它更强大可能是一个乏味的过程..
  • 如何在没有 WinDbg 的情况下捕获异常并生成跟踪?
  • @ChaseMedallion - 你是对的.. 请忽略关于堆栈跟踪的评论.. 我忽略了你正在处理 StackOverFlowException 的事实。但您应该可以使用 SOS.dll 扩展名进行故障排除。
【解决方案2】:

你应该用这种方法走得很远:

确保你有正确的符号

.symfix d:\symbols

在 WinDbg 中加载 .NET 扩展

.loadby sos clr
.loadby sos mscorwks

选择有异常的线程

~#s

打印异常

!pe

和调用栈

!clrstack
!dumpstack

如果您对 SOS 或 mscordacwks 的版本有疑问,因为转储不是来自同一台机器,请使用 Mscordacwks Collector 从服务器获取正确的版本。

还要注意,总是预先分配一个 StackOverflowException,但不一定会抛出。类似命令的输出

!dumpheap -stat -type StackOverflowException

可能会产生误导。

【讨论】:

    猜你喜欢
    • 2019-01-19
    • 1970-01-01
    • 2016-01-12
    • 2012-02-13
    • 2011-12-30
    • 2010-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多