翻译《The Old New Thing》- Using the “gu“ debugger command to find the infinite loop

Using the "gu" debugger command to find the infinite loop - The Old New Thing (microsoft.com)icon-default.png?t=N7T8https://devblogs.microsoft.com/oldnewthing/20070426-00/?p=27103

Raymond Chen 2007年04月26日


 使用 “gu” 调试器命令寻找死循环

        有人说,“你的程序占用了100%的CPU”,然后递给你一个调试会话。 这通常发生是因为一个线程陷入了一个死循环中。 如果你幸运的话,这是一个容易诊断的死循环类型,因为它只是一个没有返回的函数。 (更复杂的情况是,一个函数做了一些工作然后返回,然后这些工作有一些延迟效果导致函数再次运行,如此等等。) 让我们假设我们是幸运的,因为,嗯,调试是一种好的练习。

        第一步是找到使用所有CPU的线程。 借助 !runaway 调试器扩展,这实际上是相当容易的。

0:011> !runaway
 User Mode Time
 Thread    Time
 192c      0 days 0:05:22.457
 1384      0 days 0:00:16.063
 14ac      0 days 0:00:08.392
 48c       0 days 0:00:03.955
 1db0      0 days 0:00:00.010
 1888      0 days 0:00:00.010
 1078      0 days 0:00:00.000
 1470      0 days 0:00:00.000
 1f84      0 days 0:00:00.000
 1d60      0 days 0:00:00.000
 1850      0 days 0:00:00.000
 134c      0 days 0:00:00.000
 19fc      0 days 0:00:00.000
 1b4       0 days 0:00:00.000

        哇,线程 0x192c 肯定使用了很多CPU时间,但这并不意味着它是处于100% CPU循环中的线程,因为CPU时间是线程生命周期内的累积时间。也许那个线程有很多CPU时间是因为它存在的时间最长。 你需要做的是恢复执行一小会儿,然后再次中断,看看谁的CPU时间增加了

0:011> g
^C
(1928.1d34): Break instruction exception - code 80000003 (first chance)
eax=7ffd9000 ebx=00000001 ecx=00000002 edx=00000003 esi=00000004 edi=00000005
eip=7c901230 esp=0124ffcc ebp=0124fff4 iopl=0         nv up ei pl zr na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000246
ntdll!DbgBreakPoint:
7c901230 cc               int     3
0:011> !runaway
 User Mode Time
 Thread    Time
 192c      0 days 0:05:23.679
 1384      0 days 0:00:16.063
 14ac      0 days 0:00:08.392
 48c       0 days 0:00:03.955
 1db0      0 days 0:00:00.010
 1888      0 days 0:00:00.010
 1078      0 days 0:00:00.000
 1470      0 days 0:00:00.000
 1ea4      0 days 0:00:00.000
 1d60      0 days 0:00:00.000
 1850      0 days 0:00:00.000
 134c      0 days 0:00:00.000
 19fc      0 days 0:00:00.000
 1b4       0 days 0:00:00.000

        啊哈,我们看到线程 0x192c 是唯一一个CPU时间有明显增加的线程。 那很可能就是导致100% CPU使用率的线程。

0:011> ~~[192c]s
eax=00000000 ebx=77d5e581 ecx=0012daa0 edx=0000000c esi=01d18140 edi=00000000
eip=77d5e590 esp=0012da78 ebp=0012da88 iopl=0         nv up ei pl zr na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
USER32!FindWindowA+0xf:
77d5e590 50               push    eax
ChildEBP RetAddr
0012da88 1000714b USER32!FindWindowA+0xf
0012dbc8 100061f3 ABC!CAlpha::FindTarget+0x27f
0012dbf4 603517e8 ABC!CBeta::TransferData+0x18a
0012dc28 10002d9d DEF!CGamma:TransferData+0xc
0012dc48 00505303 ABC!CBeta::BeginAsync+0x51
0012dc5c 0090a21a GHI!CPrintSession::Open+0x2a51
0012dd20 009099d8 GHI!CPrintSession::Init+0x252
0012e060 009097e6 GHI!CPrintOptions::GetSettings+0x24a
0012e0a4 0090973d GHI!CPrintOptions::OpenSettings+0x248
0012e130 00909664 GHI!CDocumentMenu::OnInvoke+0x24
...

        现在,神奇的 “gu” 命令就派上用场了。 你输入 “gu” 来运行当前函数直到它返回。 如果你得到另一个提示符,那么再次输入 “gu”, 来运行那个函数直到它返回。 以此类推,直到你找到那个不返回的函数。 那就是包含无限循环的函数。

        现在你可以开始调查为什么那个函数卡住了。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

0x0007

可不可奖励我吃只毛嘴鸡 馋😋

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值