问题 无法在WinDbg中切换到托管线程


我正在使用SOS探索使用WinDbg的ASP.NET进程的minidump。如果我列出托管线程,我会看到正常的线程列表:

0:000> !threads
ThreadCount: 8
UnstartedThread: 0
BackgroundThread: 8
PendingThread: 0
DeadThread: 0
Hosted Runtime: no
                                              PreEmptive                                                Lock
       ID OSID        ThreadOBJ     State   GC     GC Alloc Context                  Domain           Count APT Exception
XXXX    1 12bc 00000000001441f0   1808220 Disabled 0000000140b10fc8:0000000140b12f20 000000000017f6e0     0 Ukn (Threadpool Worker)
XXXX    2 1334 0000000000152f90      b220 Enabled  0000000000000000:0000000000000000 0000000000121b90     0 Ukn (Finalizer)
XXXX    3 138c 000000000017b100    80a220 Enabled  0000000000000000:0000000000000000 0000000000121b90     0 Ukn (Threadpool Completion Port)
XXXX    4  81c 000000000017eb40      1220 Enabled  0000000000000000:0000000000000000 0000000000121b90     0 Ukn
XXXX    5  5e4 00000000001bccd0   880a220 Enabled  0000000000000000:0000000000000000 0000000000121b90     0 Ukn (Threadpool Completion Port)
XXXX    6 11e4 0000000004bee280   180b220 Disabled 0000000000000000:0000000000000000 0000000000121b90     0 Ukn (Threadpool Worker)
XXXX    7  73c 0000000004c267e0   180b220 Disabled 0000000140b0f158:0000000140b10f20 000000000017f6e0     3 Ukn (Threadpool Worker) System.StackOverflowException (000000007fff0138) (nested exceptions)
XXXX    8  21c 00000000001ad1c0   180b220 Enabled  0000000000000000:0000000000000000 0000000000121b90     0 Ukn (Threadpool Worker)

但是,如果我尝试切换到线程7(具有异常的那个),我得到这个:

0:000> ~7s
        ^ Illegal thread error in '~7s'

尝试切换到任何托管线程时会发生这种情况。我不知道从哪里开始。我真正需要做的是从该托管线程中查看堆栈跟踪。


3669
2017-07-10 15:06


起源



答案:


输出来自 !threads 显示线程的三个不同ID(WinDbg的ID,托管ID和本机ID)。你需要使用的是最左边的。如您所见,转储中的所有线程都已标记为 XXXX 意味着它们不再可用。这是正常的,但我觉得奇怪的是所有线程都标记为这样。在进程关闭期间是否进行了转储?

根据评论更新

你绝对应该能够得到一个有用的转储 adplus -crash,但显然一切都搞砸了,因为即使终结器线程被终止。我注意到其中一个线程有一个StackoverflowException,这可能就是你所追求的。为此,你可以在第一次机会异常时创建转储,看看你是否能以这种方式获得更多有用的东西。 Adplus有一个 FullOnFirst 那个标志。

额外更新

好的,那个  奇怪的。还有其他一些尝试。

  • 在崩溃之前附加到流程,然后让它 g。这应该在异常时打入调试器。如果需要,可以设置事件以仅打印控制台的任何异常。使用 sxe -c "!pe; !clrstack; gn" clr

  • Adplus曾经是一个vbs脚本,但它在一段时间后被重写为可执行文件。我看过新版本的一些小问题,但没有这样的。您可以尝试使用adplus_old.vbs仍然可用的旧脚本。

  • 尝试 procdump 来自sysinternals。它支持与Adplus相同类型的转储选项(以及更多)。


10
2017-07-10 15:20



是的,转储是在崩溃期间(通过运行) ADPlus -crash)。这是否意味着我根本无法看到这些线程? - andypaxo
谢谢你的明确解释!我刚刚尝试了这个,使用 -fullonfirst,并创建了完整转储。不幸的是结果是相同的,所有线程都不可用。我也尝试直接从堆中获取异常,但消息,堆栈跟踪等都是null。你知道为什么这么少的信息可用吗? - andypaxo
@Brian,不应该 gn 在你的sxe命令中使用? - Marc Sherman
@MarcSherman它应该。谢谢。 - Brian Rasmussen
我有同样的问题附加到过程(使用windbg)。除了上面给出的内容之外,这个过程已经死了,windbg实际上并没有给我任何额外的信息。 (例如!analyze -v,!pe都没有给出任何额外的,所有线程都是XXXX) - 我也有一个stackoverflow异常。所以我想我会尝试使用VS2012(在重新启动我的进程后)附加到进程,令我惊讶的是这给了我所需的堆栈跟踪。 - wal


答案:


输出来自 !threads 显示线程的三个不同ID(WinDbg的ID,托管ID和本机ID)。你需要使用的是最左边的。如您所见,转储中的所有线程都已标记为 XXXX 意味着它们不再可用。这是正常的,但我觉得奇怪的是所有线程都标记为这样。在进程关闭期间是否进行了转储?

根据评论更新

你绝对应该能够得到一个有用的转储 adplus -crash,但显然一切都搞砸了,因为即使终结器线程被终止。我注意到其中一个线程有一个StackoverflowException,这可能就是你所追求的。为此,你可以在第一次机会异常时创建转储,看看你是否能以这种方式获得更多有用的东西。 Adplus有一个 FullOnFirst 那个标志。

额外更新

好的,那个  奇怪的。还有其他一些尝试。

  • 在崩溃之前附加到流程,然后让它 g。这应该在异常时打入调试器。如果需要,可以设置事件以仅打印控制台的任何异常。使用 sxe -c "!pe; !clrstack; gn" clr

  • Adplus曾经是一个vbs脚本,但它在一段时间后被重写为可执行文件。我看过新版本的一些小问题,但没有这样的。您可以尝试使用adplus_old.vbs仍然可用的旧脚本。

  • 尝试 procdump 来自sysinternals。它支持与Adplus相同类型的转储选项(以及更多)。


10
2017-07-10 15:20



是的,转储是在崩溃期间(通过运行) ADPlus -crash)。这是否意味着我根本无法看到这些线程? - andypaxo
谢谢你的明确解释!我刚刚尝试了这个,使用 -fullonfirst,并创建了完整转储。不幸的是结果是相同的,所有线程都不可用。我也尝试直接从堆中获取异常,但消息,堆栈跟踪等都是null。你知道为什么这么少的信息可用吗? - andypaxo
@Brian,不应该 gn 在你的sxe命令中使用? - Marc Sherman
@MarcSherman它应该。谢谢。 - Brian Rasmussen
我有同样的问题附加到过程(使用windbg)。除了上面给出的内容之外,这个过程已经死了,windbg实际上并没有给我任何额外的信息。 (例如!analyze -v,!pe都没有给出任何额外的,所有线程都是XXXX) - 我也有一个stackoverflow异常。所以我想我会尝试使用VS2012(在重新启动我的进程后)附加到进程,令我惊讶的是这给了我所需的堆栈跟踪。 - wal