13.windbg-!runaway、~、|(控制进程、线程切换)

!runaway

!runaway命令显示每个线程消费的时间

Bit 0 (0x1) 让调试器显示每个线程消耗的用户模式时间(user time),默认不加就是0x1

Bit 1 (0x2) 显示每个线程消耗的内核时间(kernel time)。 Bit 2 (0x4) 显示每个线程从创建开始经历了多少时间。 就是三者的组合:1 2 3 4 5 6 7
0:002> !runaway 
 User Mode Time
  Thread       Time
   0:890       0 days 0:00:00.031
   2:a00       0 days 0:00:00.000
   1:1174      0 days 0:00:00.000
0:002> !runaway 1
 User Mode Time
  Thread       Time
   0:890       0 days 0:00:00.031
   2:a00       0 days 0:00:00.000
   1:1174      0 days 0:00:00.000
0:002> !runaway 2
 Kernel Mode Time
  Thread       Time
   0:890       0 days 0:00:00.062
   2:a00       0 days 0:00:00.000
   1:1174      0 days 0:00:00.000
0:002> !runaway 3
 User Mode Time
  Thread       Time
   0:890       0 days 0:00:00.031
   2:a00       0 days 0:00:00.000
   1:1174      0 days 0:00:00.000
 Kernel Mode Time
  Thread       Time
   0:890       0 days 0:00:00.062
   2:a00       0 days 0:00:00.000
   1:1174      0 days 0:00:00.000
0:002> !runaway 4
 Elapsed Time
  Thread       Time
   0:890       0 days 0:38:34.825
   1:1174      0 days 0:38:34.793
   2:a00       0 days 0:38:24.528
0:002> !runaway 7
 User Mode Time
  Thread       Time
   0:890       0 days 0:00:00.031
   2:a00       0 days 0:00:00.000
   1:1174      0 days 0:00:00.000
 Kernel Mode Time
  Thread       Time
   0:890       0 days 0:00:00.062
   2:a00       0 days 0:00:00.000
   1:1174      0 days 0:00:00.000
 Elapsed Time
  Thread       Time
   0:890       0 days 0:38:41.825
   1:1174      0 days 0:38:41.793
   2:a00       0 days 0:38:31.528

该扩展命令可以用来快速找出哪些线程循环失去控制消耗了太多CPU时间。输出中以调试器的内部线程号和16进制线程ID来标识每个线程。还会显示调试器ID,当然,主要用于分析dump文件

~ (Thread Status)

波形符(~) 命令显示指定线程或当前进程中的所有线程的信息

0:002> ~  
   0  Id: 433c.4154 Suspend: 1 Teb: 7efdd000 Unfrozen
   1  Id: 433c.33e4 Suspend: 1 Teb: 7efda000 Unfrozen
.  2  Id: 433c.c50 Suspend: 1 Teb: 7efd7000 Unfrozen
0:002> ~*    ///<显示线程和入口函数
   0  Id: 433c.4154 Suspend: 1 Teb: 7efdd000 Unfrozen
      Start: test1!ILT+120(_wmainCRTStartup) (00a6107d) 
      Priority: 0  Priority class: 32  Affinity: f
   1  Id: 433c.33e4 Suspend: 1 Teb: 7efda000 Unfrozen
      Start: test1!ILT+35(?ThreadProcYAKPAXZ) (00a61028) 
      Priority: 0  Priority class: 32  Affinity: f
.  2  Id: 433c.c50 Suspend: 1 Teb: 7efd7000 Unfrozen
      Start: ntdll!DbgUiRemoteBreakin (77e6fb5a) 
      Priority: 0  Priority class: 32  Affinity: f
0:002> ~0
   0  Id: 433c.4154 Suspend: 1 Teb: 7efdd000 Unfrozen
      Start: test1!ILT+120(_wmainCRTStartup) (00a6107d) 
      Priority: 0  Priority class: 32  Affinity: f
0:002> ~0s    ///<切换线程
eax=00000000 ebx=0044f5e4 ecx=00000006 edx=00000000 esi=00000003 edi=71b16740
eip=76c07cb0 esp=0044f494 ebp=0044f51c iopl=0         nv up ei pl zr na pe nc

我们可以发现,~和~*还是有点区别的,~*会把入口函数和优先级都打印出来

//暂停、恢复线程----------------------------------------------------------------------------------------------------

0  Id: 433c.4154 Suspend: 1 Teb: 7efdd000 Unfrozen意思是0号线程,进程ID为433c,线程ID为4154,暂停数为1,未冻结状态,每个线程都包含了一个暂停计数(Suspend Count),以及一个冻结/解冻(Frozen/Unfrozen)的状态。

暂停计数由Windows内核使用的值,可以通过SuspendThread和ResumeThread这两个系统函数来控制的,核心编程里说一个线程创建时,暂停次数为1,

当线程完全初始化后,系统就要查看CREATE_SUSPEND标志是否已经传递给CreateThread。如果该标志没有传递,系统便将线程的暂停计数递减为0,

该线程可以调度到一个进程中

也可以用~<tid>n增加暂停计数,用~<tid>m减少暂停计数,如下:

0:001> ~1n
0:001> ~1
.  1  Id: 433c.33e4 Suspend: 2 Teb: 7efda000 Unfrozen
      Start: test1!ILT+35(?ThreadProcYAKPAXZ) (00a61028) 
      Priority: 0  Priority class: 32  Affinity: f
0:001> g
此时g运行,会发现1号线程被暂停了,必须使用~1m来恢复

冻结状态是调试器的状态,在window操作系统中是不支持这个概念,对于每个被冻结的线程,调试器将记住这个状态,并且在调试事件被处理之前增加线程的挂起计数,当调试事件被处理完毕时,挂起计数将被递减,对应的命令为:

冻结~<tid>f

解冻~<tid>u

冻结命令数量必须和解冻命令数量相等

| (Process Status)

这个在多进程切换时比较有效:

先模拟一个多进程调试:

windbg先打开test1

再附加到test2上:

0:002> |               ///< <span style="font-family: 'Courier New', Courier, mono;">查看总进程列表,目前只有一个</span>
.  0	id: 433c	create	name: test1.exe
0:002> .attach 0n7860  ///< 附加test2
Attach will occur on next execution
0:002> g               ///< 运行
*** wait with pending attach
Symbol search path is: srv*
Executable search path is: 
ModLoad: 00300000 0031b000   D:\windbg\test2\Debug\test2.exe
ModLoad: 77dd0000 77f50000   C:\Windows\SysWOW64\ntdll.dll
eax=7efda000 ebx=00000000 ecx=00000000 edx=77e6fb5a esi=00000000 edi=00000000
eip=77de000c esp=0079fe54 ebp=0079fe80 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!DbgBreakPoint:
77de000c cc              int     3
1:004> |<span style="white-space:pre">	</span>     ///< 再次查看总进程列表,目前已有两个
   0	id: 433c	create	name: test1.exe
.  1	id: 1eb4	attach	name: D:\windbg\test2\Debug\test2.exe
和线程切换相同:使用:

1:004> |0s
切换回0号进程


 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值