1

我有一个 .NET 3.5 WPF 应用程序,当仅在 Win 7 64 位上运行时,它偶尔会占用 96-99% 的 CPU 时间。当然,当这种情况发生时,甚至应用程序本身也会停止正常工作。这是另一个仅在 64 位版本的 Windows 7 上发生的问题。

应用程序当前处于这种状态,我想使用 WinDbg 或其他一些调试工具来捕获尽可能多的信息。任何在线可以实时提供帮助的人?

首先,这是我可以从 Process Explorer 中获得的信息:如附图所示在此处输入图像描述,我的线程数为 40,其中一堆具有起始地址:

mscorwrks.dll!GetMetaDataInternalInterfaceFromPublic+0x934c.  

目前大约有 24 个线程将其显示为起始地址。但我无法将其与我的代码中的任何内容联系起来。

因此,我目前使用 WinDbg 附加到该进程,该进程已暂停所有线程。然后我做了

!runaway 3

这给了我:

0:039> !runaway 3
 User Mode Time
  Thread       Time
  33:29bc      0 days 0:27:48.711
  21:2880      0 days 0:26:22.021
  34:18cc      0 days 0:24:38.873
  18:2a04      0 days 0:23:56.753
  23:2618      0 days 0:18:58.947
  24:27e8      0 days 0:17:36.859
  30:21d4      0 days 0:17:05.800
  32:248c      0 days 0:17:04.286
  35:2b00      0 days 0:16:20.809
  22:2680      0 days 0:15:37.597
   5:2a28      0 days 0:15:10.234
  31:ee4       0 days 0:15:07.348
  20:20f0      0 days 0:14:32.903
  17:29ac      0 days 0:14:02.202
  10:20dc      0 days 0:00:51.152
  11:2ad0      0 days 0:00:11.247
  37:2c14      0 days 0:00:06.489
  38:2f3c      0 days 0:00:01.466
  25:1db8      0 days 0:00:00.920
   1:2a84      0 days 0:00:00.452
   0:1494      0 days 0:00:00.093
   2:1ba0      0 days 0:00:00.078
  29:53c       0 days 0:00:00.015
  27:278c      0 days 0:00:00.015
   7:8d4       0 days 0:00:00.015
   4:2620      0 days 0:00:00.015
  39:215c      0 days 0:00:00.000
  36:2088      0 days 0:00:00.000
  28:26e0      0 days 0:00:00.000
  26:2960      0 days 0:00:00.000
  19:2a10      0 days 0:00:00.000
  16:2a70      0 days 0:00:00.000
  15:24a8      0 days 0:00:00.000
  14:2208      0 days 0:00:00.000
  13:2bcc      0 days 0:00:00.000
  12:2a6c      0 days 0:00:00.000
   9:1a38      0 days 0:00:00.000
   8:2a98      0 days 0:00:00.000
   6:1200      0 days 0:00:00.000
   3:2af8      0 days 0:00:00.000
 Kernel Mode Time
  Thread       Time
  11:2ad0      0 days 0:00:03.650
  10:20dc      0 days 0:00:02.230
  33:29bc      0 days 0:00:00.686
  34:18cc      0 days 0:00:00.577
  21:2880      0 days 0:00:00.327
  18:2a04      0 days 0:00:00.327
  24:27e8      0 days 0:00:00.280
  35:2b00      0 days 0:00:00.249
   1:2a84      0 days 0:00:00.218
  30:21d4      0 days 0:00:00.156
  22:2680      0 days 0:00:00.140
   5:2a28      0 days 0:00:00.140
  37:2c14      0 days 0:00:00.124
  23:2618      0 days 0:00:00.109
   2:1ba0      0 days 0:00:00.109
  25:1db8      0 days 0:00:00.093
  20:20f0      0 days 0:00:00.093
  17:29ac      0 days 0:00:00.093
   0:1494      0 days 0:00:00.078
   7:8d4       0 days 0:00:00.062
  32:248c      0 days 0:00:00.046
   3:2af8      0 days 0:00:00.046
  31:ee4       0 days 0:00:00.031
   8:2a98      0 days 0:00:00.031
  38:2f3c      0 days 0:00:00.015
  27:278c      0 days 0:00:00.015
  16:2a70      0 days 0:00:00.015
  15:24a8      0 days 0:00:00.015
  39:215c      0 days 0:00:00.000
  36:2088      0 days 0:00:00.000
  29:53c       0 days 0:00:00.000
  28:26e0      0 days 0:00:00.000
  26:2960      0 days 0:00:00.000
  19:2a10      0 days 0:00:00.000
  14:2208      0 days 0:00:00.000
  13:2bcc      0 days 0:00:00.000
  12:2a6c      0 days 0:00:00.000
   9:1a38      0 days 0:00:00.000
   6:1200      0 days 0:00:00.000
   4:2620      0 days 0:00:00.000

当我发出g继续该过程时,我得到

0:039> g
(2944.1d6c): Break instruction exception - code 80000003 (first chance)
mscorlib_ni+0x367240:
000007fe`f8337240 cc              int     3

并且进程保持暂停。我该如何继续?

4

3 回答 3

2

首先,您需要修复您的符号。附加 windbg 后,执行以下操作:

.symopt+0x100;.symfix c:\websym;.reload

我的猜测是线程 39 是注入的调试器线程,因此可以在点击 g 后获得一次中断指令。如果你不止一次得到它,那就有问题了。

但在点击 g 之前,切换到 !runaway 输出中的第一个线程(在您的情况下为 33),如下所示:~33s

然后加载正确的 .NET 调试器扩展 dll。如果在 .NET 4 之前,请执行以下操作:

.loadby sos.dll mscorwks

如果 .NET 4 及更高版本执行以下操作:

.loadby sos.dll clr

现在执行此操作以查看托管堆栈:

!clrstack

然后按g,让它运行几秒钟,再次闯入,然后再次发出!clrstack。重复几次,让您了解线程 33 正在做什么。请注意,每次中断时,您都必须在发出 !clrstack 之前切换回线程 33。

如果未显示托管堆栈,则发出 kb 以查看本机堆栈。

您可能还想查看您是否为该线程管理了异常。!pe 将为您执行此操作(在您切换到该线程后)。您还可以转储所有托管异常对象。我认为命令是!dumpallexceptions,但请检查帮助(使用!帮助)以确定。请注意,.NET 在启动时预分配了 3 个异常对象,这些异常对象(大多数情况下)可以在 !dumpallexceptions 输出中被忽略(其中一个与内存不足的情况有关)。

马克

于 2012-04-16T19:12:19.710 回答
0

我认为 clr 异常是阻止您继续该过程的原因。使用“sxi clr”抑制这些异常并继续

于 2012-04-17T11:38:20.527 回答
0

一个简单的技巧是在 CPU 使用率高时捕获一组挂起转储(一分钟间隔),然后在 WinDbg 中对其进行分析。使用 runaway 可以查看哪些线程消耗 CPU 最多,然后检查其调用堆栈以找到可能的原因。

您所做的称为实时调试,对于初学者来说并不容易。

于 2012-04-17T13:04:51.350 回答