Windbg 堆栈跟踪问题

Posted

技术标签:

【中文标题】Windbg 堆栈跟踪问题【英文标题】:Windbg stack trace issue 【发布时间】:2010-10-09 14:31:08 【问题描述】:

我正在调试托管代码的故障转储,当使用 !threads 在这里显示所有线程时,几个线程具有 Exception 字段值和各种异常。

我的问题是如何快速识别哪个异常是导致进程崩溃的根异常?为什么这么多线程与异常值相关联的任何想法 - 我认为应该只有一个线程(具有未处理的异常)导致进程崩溃,为什么这么多线程显示异常? :-)

提前致谢, 乔治

这里是!threads的一部分的输出示例,FooException和GooException是我的应用程序定义的异常类型。

48 f 14c4 000000001d8bc4a0 b020 已启用 0000000000000000:0000000000000000 0000000000162080 0 MTA FooException (0000000093365da0) 49 10 17e8 000000001acc26d0 200b020 已启用 0000000000000000:0000000000000000 0000000000162080 0 MTA FooException (0000000093364670) 50 11 135c 000000001acc3180 200b020 已启用 0000000000000000:0000000000000000 00000000000162080 0 MTA FooException (00000000dd707f70) 51 12 1740 000000001aca2ec0 200b020 启用 0000000000000000:0000000000000000 0000000000162080 0 MTA FooException (00000000937e8a60) 52 13 814 000000001aca3970 b020 已启用 0000000000000000:0000000000000000 0000000000162080 0 MTA GooException (000000009336c550) 53 14 6ac 000000001accb010 b020 启用 0000000000000000:0000000000000000 0000000000162080 0 MTA FooException (0000000093355f58) 54 15 1114 000000001accbac0 b020 启用 0000000000000000:0000000000000000 0000000000162080 0 MTA 56 16 d44 000000001accc570 200b020 已启用 0000000000000000:0000000000000000 0000000000162080 0 MTA GooException (00000000933c0598) 58 17 ff4 000000001accd020 200b020 已启用 0000000000000000:0000000000000000 0000000000162080 0 MTA FooException (00000000a8a39c48) 59 18 780 000000001accdad0 b020 启用 0000000000000000:0000000000000000 0000000000162080 0 MTA 60 19 8fc 000000001acce580 b020 已启用 0000000000000000:0000000000000000 0000000000162080 0 MTA FooException (00000000abd5ff08) 61 1a 2e8 000000001accf030 b020 启用 0000000000000000:0000000000000000 0000000000162080 0 MTA FooException (00000000ac163ea0) 62 1b 11e8 000000001d8bd010 b020 已启用 0000000000000000:0000000000000000 0000000000162080 0 MTA FooException (0000000093367c78) 63 1c 1520 000000001d8bd5e0 200b020 启用 0000000000000000:0000000000000000 0000000000162080 0 MTA 64 1d 1330 000000001d8be090 b020 已启用 0000000000000000:0000000000000000 0000000000162080 0 MTA FooException (00000000937d9540) 65 1e 7f8 000000001d8beb40 b020 已启用 0000000000000000:0000000000000000 0000000000162080 0 MTA FooException (000000009339a038) 66 1f a70 000000001d8bf5f0 b020 已启用 0000000000000000:0000000000000000 0000000000162080 0 MTA FooException (00000000937d8b88) 67 20 150 000000001d8c00a0 b020 启用 0000000000000000:0000000000000000 0000000000162080 0 MTA 68 21 1628 000000001d8c0b50 b020 已启用 0000000000000000:0000000000000000 0000000000162080 0 MTA FooException (0000000093355200) 69 22 1148 000000001d8c1600 200b020 已启用 0000000000000000:0000000000000000 0000000000162080 0 MTA GooException (000000009380ada8) 70 23 16a8 000000001d8c20b0 b020 已启用 0000000000000000:0000000000000000 0000000000162080 0 MTA FooException (0000000093365178) 71 24 1640 000000001d8c2b60 b020 已启用 0000000000000000:0000000000000000 0000000000162080 0 MTA FooException (0000000093343a78) 72 25 1568 000000001d8c3610 b020 已启用 0000000000000000:0000000000000000 0000000000162080 0 MTA FooException (000000009380cc08)

【问题讨论】:

也许 !threads 的输出在这里有用? 感谢保罗的好主意,我已经添加了更多信息。 :-) 【参考方案1】:

在调试转储时,可以使用 "~" 命令找到出错的线程,然后在其中一个旁边查找 "."线程。然后你切换到那个线程并运行kb。您应该会在本机调用堆栈中看到对 RaiseException() 的调用。

一旦您知道感兴趣的线程,您也可以运行 !clstack 来获取托管调用堆栈。

您还可以在线程上运行 !pe 以转储 (!PrintException) 输出。

这应该让你大部分时间..根据我概述的步骤随意评论和分享更多数据,我们应该能够快速解决这个问题

为了回答您的问题,在线程上出现异常的一段时间内,!threads 输出将表明这一点。所以看起来你有很多异常需要追踪。

另一种技术(值得另一个 TAG :-)

要跟踪其他异常,您可以使用 Visual Studion 并在 UI 中启用对抛出异常的中断。如果你胆子大,可以运行 Mdbg 并运行以下命令来捕捉被抛出的异常

Open a VS.NET 2005/2008 Command Prompt
mdbg
>pro //Lists the processes
>a <PID> //attach to the processes
>ca ex //catches all exceptions
>g //go until break
//When it breaks on an exception
>where -v -c 200 // dumps the managed call stack (verbose) with a count of 200 frames
>print //prints out locals on the stack
>g //go to next exception
>de //Detach when done.. process stays running
>q //Quit the debugger

MDbg 的好处是您可以进行源代码级调试。 (也许我会为这些创建一个 MDbg 标签)

谢谢, 亚伦

【讨论】:

【参考方案2】:

乔治2, 您是否尝试过命令 "!analyze -v" ?你加载了 sos dot net 调试器扩展吗? (尝试 .chain 命令查看它是否在其中)。分析 -v 很有帮助。 . .

【讨论】:

以上是关于Windbg 堆栈跟踪问题的主要内容,如果未能解决你的问题,请参考以下文章

如何使用大量 CPU 快速获取线程的托管堆栈跟踪

如何使用 WinDBG 列出所有托管线程的调用堆栈?

Windbg可以看到Visual Studio中看不到的有效函数调用堆栈

Windbg Call Stack窗口的使用

调用堆栈和堆栈跟踪有啥区别?

Javascript 异常堆栈跟踪