windbg-bp、 bm、 bu、 bl、 bc、 ba(断点、硬件断点)

bp

bp 命令是在某个地址下断点, 能够 bp 0x7783FEB 也能够 bp MyApp!SomeFunction 。函数

对于后者,WinDBG 会自动找到MyApp!SomeFunction 对应的地址并设置断点。 可是使用bp的问题在于:spa

1)当代码修改以后,函数地址改变,该断点仍然保持在相同位置,不必定继续有效;.net

 2)WinDBG 不会把bp断点保存工做空间中线程

bp  Address或bp 伪寄存器或bp符号名称:调试

0:000> x Simple1Demo!CSimple1DemoApp::InitInstance 00640080 Simple1Demo!CSimple1DemoApp::InitInstance (void) 0:000> bp 00640080   
0:000> bl  
 0 e 00640080     0001 (0001)  0:**** Simple1Demo!CSimple1DemoApp::InitInstance  
0:000> x Kernel32!LoadLibraryW  
7c80aeeb kernel32!LoadLibraryW = <no type information>  
0:000> bp Kernel32!LoadLibraryW  
0:000> bl  
 0 e 00640080     0001 (0001)  0:**** Simple1Demo!CSimple1DemoApp::InitInstance  
 1 e 7c80aeeb     0001 (0001)  0:**** kernel32!LoadLibraryW  
0:000> bp $exentry  
0:000> bl  
 0 e 00640080     0001 (0001)  0:**** Simple1Demo!CSimple1DemoApp::InitInstance  
 1 e 7c80aeeb     0001 (0001)  0:**** kernel32!LoadLibraryW  
 2 e 0061c895     0001 (0001)  0:**** Simple1Demo!ILT+14480(_wWinMainCRTStartup)  

上例说明三种用法做用是同样的,都是bp Address(windbg内部会换成符号文件对应的地址,或伪寄存器的地址)code

bp /1 Address表示该断点为一次性断点,有点相似于F4做用于OD,一旦激活就自动删除了:orm

如bp /1 00640080blog

bp Address Passes表示指定断点激活以前要忽略的次数进程

默认状况下,断点在第一次执行断点位置的代码时被激活。这种默认状况和把Passes 设置为1是同样的。要使得断点在程序至少执行该代码一次以后才激活,能够将这个值设置为2或更大。例如,值为2时,使得断点在第二次执行到该代码时被激活。该参数建立一个在每次执行断点处的代码时被减小1的计数器。要查看Passes 计数器的初始值和当前值,使用bl (Breakpoint List)Passes 仅当程序响应g (Go)命令并执行经过断点时才减小。单步或跟踪(tracing)经过它是不会减小的。当Passes 到达1时,能够经过清除并重设断点来重置它。ip

咱们来试试,用bc把之前断点都删除,再设置在第三次运行LoadLibraryW时激活该处断点

0:000> bc*  
0:000> bl  
0:000> bp 7c80aeeb 3  
0:000> bl  
 0 e 7c80aeeb     0003 (0003)  0:**** kernel32!LoadLibraryW  

咱们注意到这个断点显示的是0003 (0003) F5运行:

0:000> g  
Breakpoint 0 hit  
eax=00000002 ebx=7ffdc000 ecx=00000000 edx=00a8660c esi=0263f76e edi=0263f6f2  
eip=7c80aeeb esp=0012fd68 ebp=0012fdb0 iopl=0         nv up ei pl nz na po nc  
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202  
kernel32!LoadLibraryW:  
7c80aeeb 8bff            mov     edi,edi  
0:000> bl  
 0 e 7c80aeeb     0001 (0003)  0:**** kernel32!LoadLibraryW  

咱们注意到这个断点如今显示的是0001 (0003),表示前面忽略了两次,

bu 命令是针对某个符号下断点。 好比 bu MyApp!SomeFunction 。 在代码被修改以后, 该断点能够随着函数地址改变而自动更新到最新位置。  并且bu 断点会保存在WinDbg工做空间中, 下次启动 Windbg 的时候该断点会自动设置上去。另外,在模块没有被加载的时候,bp 断点会失败(由于函数地址不存在),而bu 断点则能够成功。 新版的WinDBG中 bp失败后会自动被转成bu

bm 命令也是针对符号下断点。 可是它支持匹配表达式。 不少时候你下好几个断点。 好比,把MyClass 全部的成员函数都下断点:bu MyApp!MyClass::* , 或者把全部以CreateWindow开头的函数都下断点:bu user32!CreateWindow*

这个函数比较有用,好比我想对Draw开头的函数都下断点:

0:000> bc*  
0:000> bl  
0:000> bm *!draw*  
  1: 00695930 @!"Simple1Demo!DrawState"  
  2: 0175c790 @!"SkinLog!DrawState"  
  3: 019f65d0 @!"SkinScroll!DrawState"  
  4: 10119d10 @!"SkinHgy!DrawState"  
0:000> bl  
 1 e 00695930     0001 (0001)  0:**** Simple1Demo!DrawState  
 2 e 0175c790     0001 (0001)  0:**** SkinLog!DrawState  
 3 e 019f65d0     0001 (0001)  0:**** SkinScroll!DrawState  
 4 e 10119d10     0001 (0001)  0:**** SkinHgy!DrawState

bl(breakpoint list) 命令列出已存在的断点的信息

对于每一个断点,该命令显示如下信息:

  • 断点ID。该ID是一个能够在其余命令中引用这个断点的十进制数字。
  • 断点状态。它能够是e (启用) 或(禁用)。
  • 若是出现字母"u",说明断点是未定的。即,该断点中的符号引用尚未和任何当前已加载的模块匹配。
  • 断点位置的虚拟地址或符号表达式。若是启用了源码行号加载,bl 命令显示文件和行号信息而不是地址偏移。若是该断点未定,则它的地址会被省略并出如今列表末尾。
  • (仅数据断点) 数据断点的类型和大小信息会显示出来。类型能够是e (执行)、 r (读/写)、w (写)或 i (输入/输出)。类型后面是以字节为单位的大小。关于这种类型断点的更多信息,查看ba (Break on Access)
  • 断点被激活前须要忽略的剩余次数,后面是在圆括号中的初始次数。(这种断点的更多信息,查看bp, bu, bm (Set Breakpoint)中对Passes参数的说明。)
  • 关联的进程和线程。若是线程是用三个星号("***")表示的,说明这不是一个指定线程的断点。
  • 符合断点地址的模块和函数以及偏移。若是是未定断点,这里会用括号括起来的断点地址替代。若是断点设置在合法地址,可是没有符号信息,这个域为空。
  • 该断点触发时要自动执行的命令。这个命令以引号括起来。

bc(breakpoint clear) 命令在系统中移除先前设置的断点。

使用星号(*)来指定全部断点

 

内存断点(硬件断点)

ba 命令就是针对数据下断点的命令, 该断点在指定内存被访问时触发。 命令格式为

ba Access Size [地址]

Access 是访问的方式, 好比 e (执行), r (读/写), w (写)

Size 是监控访问的位置的大小,以字节为单位。 值为 一、2或4,还能够是 8(64位机)。

若是Access是e,Size必须是1

好比要对内存0x0483DFE进行写操做的时候下断点,能够用命令 ba w4 0x0483DFE

Access 和Size 之间不能加入空格

0:000> bc*  
0:000> ba r4 00a76748    
0:000> bl  
 0 e 00a76748 r 4 0001 (0001)  0:**** Simple1Demo!`string' 

有时咱们只想让程序断在某个线程上:

能够用:

0:005> ~1  bp Simple1Demo!DrawState  
0:005> bl  
 0 e 0134bfc0     0001 (0001)  0:~001 Simple1Demo!DrawState  
0:005> bp Simple1Demo!DrawState  
0:005> bl  
 0 e 0134bfc0     0001 (0001)  0:~001 Simple1Demo!DrawState  

前面~1 表示只有当指定的线程ID为1执行到达断点的地址上时,调试器才会中止. 

 在X86下dr0-dr3记录了断点地址值,dr6是断点的状态寄存器,dr7是断点的控制寄存器。

另外,在初始断点命中时,尚不能设置硬件断点,若是设置,会获得以下错误:

0:000> ba r1 7c92120f   
        ^ Unable to set breakpoint error  
The system resets thread contexts after the process  
breakpoint so hardware breakpoints cannot be set.  
Go to the executable's entry point and set it then.  

初始断点后系统会重设线程上下文,所以不能设置硬件断点,建议执行到程序的入口后再设置

0:002> ba e1 00bc1b3a   
breakpoint 0 redefined  
  
0:002> r dr0  
dr0=00bc1b3a  
相关文章
相关标签/搜索