以下以skinhgy为例,windbg附加运行

1.

bp 命令是在某个地址下断点, 可以 bp 0x7783FEB 也可以 bp MyApp!SomeFunction 。

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

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

2)WinDBG 不会把bp断点保存工作空间中

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

  1. 0:000> x Simple1Demo!CSimple1DemoApp::InitInstance
  2. 00640080 Simple1Demo!CSimple1DemoApp::InitInstance (void)
  3. 0:000> bp 00640080
  4. 0:000> bl
  5. 0 e 00640080     0001 (0001)  0:**** Simple1Demo!CSimple1DemoApp::InitInstance
  6. 0:000> x Kernel32!LoadLibraryW
  7. 7c80aeeb kernel32!LoadLibraryW = <no type information>
  8. 0:000> bp Kernel32!LoadLibraryW
  9. 0:000> bl
  10. 0 e 00640080     0001 (0001)  0:**** Simple1Demo!CSimple1DemoApp::InitInstance
  11. 1 e 7c80aeeb     0001 (0001)  0:**** kernel32!LoadLibraryW
  12. 0:000> bp $exentry
  13. 0:000> bl
  14. 0 e 00640080     0001 (0001)  0:**** Simple1Demo!CSimple1DemoApp::InitInstance
  15. 1 e 7c80aeeb     0001 (0001)  0:**** kernel32!LoadLibraryW
  16. 2 e 0061c895     0001 (0001)  0:**** Simple1Demo!ILT+14480(_wWinMainCRTStartup)

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

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

如bp /1 00640080

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

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

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

  1. 0:000> bc*
  2. 0:000> bl
  3. 0:000> bp 7c80aeeb 3
  4. 0:000> bl
  5. 0 e 7c80aeeb     0003 (0003)  0:**** kernel32!LoadLibraryW

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

  1. 0:000> g
  2. Breakpoint 0 hit
  3. eax=00000002 ebx=7ffdc000 ecx=00000000 edx=00a8660c esi=0263f76e edi=0263f6f2
  4. eip=7c80aeeb esp=0012fd68 ebp=0012fdb0 iopl=0         nv up ei pl nz na po nc
  5. cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
  6. kernel32!LoadLibraryW:
  7. 7c80aeeb 8bff            mov     edi,edi
  8. 0:000> bl
  9. 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开头的函数都下断点:

  1. 0:000> bc*
  2. 0:000> bl
  3. 0:000> bm *!draw*
  4. 1: 00695930 @!"Simple1Demo!DrawState"
  5. 2: 0175c790 @!"SkinLog!DrawState"
  6. 3: 019f65d0 @!"SkinScroll!DrawState"
  7. 4: 10119d10 @!"SkinHgy!DrawState"
  8. 0:000> bl
  9. 1 e 00695930     0001 (0001)  0:**** Simple1Demo!DrawState
  10. 2 e 0175c790     0001 (0001)  0:**** SkinLog!DrawState
  11. 3 e 019f65d0     0001 (0001)  0:**** SkinScroll!DrawState
  12. 4 e 10119d10     0001 (0001)  0:**** SkinHgy!DrawState

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

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

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

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

使用星号(*)来指定所有断点

最后介绍下ba断点

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

ba Access Size [地址]

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

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

如果Access是e,Size必须是1

比如要对内存0x0483DFE进行写操作的时候下断点,可以用命令 ba w4 0x0483DFE

AccessSize 之间不能加入空格

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

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

可以用:

  1. 0:005> ~1  bp Simple1Demo!DrawState
  2. 0:005> bl
  3. 0 e 0134bfc0     0001 (0001)  0:~001 Simple1Demo!DrawState
  4. 0:005> bp Simple1Demo!DrawState
  5. 0:005> bl
  6. 0 e 0134bfc0     0001 (0001)  0:~001 Simple1Demo!DrawState

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

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

另外,在初始断点命中时,尚不能设置硬件断点,如果设置,会得到如下错误:

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

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

Windbg命令学习15(bp bm bu bl bc ba断点)的更多相关文章

  1. windbg命令学习3

    3.进程与线程: 既可以显示进程和线程列表,又可以显示指定进程或线程的详细信息.调试命令可以提供比taskmgr更详尽的进程资料,在调试过程中不可或缺. 3.1. 进程命令 进程命令包括以下:显示进程 ...

  2. windbg命令学习2

    一.windbg查看内存命令: 当我们在调试器中分析问题时, 经常需要查看不同内存块的内容以分析产生的原因, 并且在随后验证所做出的假设是否正确. 由于各个对象的状态都是保存在内存中的, 因此内存的内 ...

  3. windbg命令学习4

    4.查看调用栈 k命令:显示的是一定数量的栈帧, 其中帧的数量是由.kframes命令来控制的, 默认值是256. 我们如何来判断函数的栈指针,参数地址和局部变量地址呢? 举一个简单的windbg的k ...

  4. windbg命令学习1

    一.windbg 常用知识: 1. Windbg中的调试命令,分为三种:基本命令,元命令和扩展命令.基本命令和元命令是调试器自带的,元命令总是以“.”开头,而扩展命令是外部加入的,总是以感叹号“!”开 ...

  5. 学习使用常用的windbg命令(u、dt、ln、x)

    http://blog.csdn.net/wesley2005/article/details/51501514 目录: (1) u命令(反汇编) (2) dt命令(查看数据结构) (3) ln命令( ...

  6. 【Redis】命令学习笔记——列表(list)+集合(set)+有序集合(sorted set)(17+15+20个超全字典版)

    本篇基于redis 4.0.11版本,学习列表(list)和集合(set)和有序集合(sorted set)相关命令. 列表按照插入顺序排序,可重复,可以添加一个元素到列表的头部(左边)或者尾部(右边 ...

  7. 【Redis】命令学习笔记——哈希(hash)(15个超全字典版)

    本篇基于redis 4.0.11版本,学习哈希(hash)相关命令. hash 是一个string类型的field和value的映射表,特别适合用于存储对象. 序号 命令 描述 实例 返回 HSET ...

  8. WinDbg 命令集锦

    //断点相关 bp + 地址 设置断点bl  显示已经设定的断点bu + 地址 设置断点,但是这种类型断点再下一次启动时被记录bc 清除断点对于断点范围,可以用*匹配,-表示一个范围,表达多个可用,号 ...

  9. Windbg命令的语法规则系列(三)

    五.源文件行语法 可以将源文件行号指定为MASM表达式的全部或部分.这些数字计算出与该源代码行对应的可执行代码的偏移量.不能使用源代码行作为C++表达式的一部分.必须用重音符(`)将源文件和行号表达式 ...

随机推荐

  1. CI Weekly #22 | flow.ci 新版 iOS 构建流程的 4 大变化

    好久不见,最近 flow.ci 针对 iOS 项目重新设计了创建项目的流程,较之前相比有 4 个变化: 在创建项目阶段加入项目有效性检测,大大减少了构建失败率,有问题早发现! 在创建项目阶段加入项目配 ...

  2. 2013-2014 ACM-ICPC, NEERC, Southern Subregional Contest Problem F. Judging Time Prediction 优先队列

    Problem F. Judging Time Prediction 题目连接: http://www.codeforces.com/gym/100253 Description It is not ...

  3. JVM进程cpu飙高分析

    在项目快速迭代中版本发布频繁  近期上线报错一个JVM导致服务器cpu飙高 但内存充足的原因现象.  对于耗内存的JVM程序来而言,  基本可以断定是线程僵死(死锁.死循环等)问题. 这里是纪录一下排 ...

  4. 怎么让链式调用setTimeout停止

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. AxonFramework

    AxonFramework

  6. 从Redis的数据丢失说起(转)

    碰到一个悲催的事情:一台Redis服务器,4核,16G内存且没有任何硬件上的问题.持续高压运行了大约3个月,保存了大约14G的数据,设置了比较完备的Save参数.而就是这台主机,在一次重起之后,丢失了 ...

  7. Mui --- app与服务器之间的交互原理、mui ajax使用

    1.APP与服务器之间的交互原理 app端(客户端)与服务端的交互其实理解起来和容易,客户端想服务器端发送请求,服务器端进行数据运算后返回最终结果.结果可以是多种格式: 1.text 文本格式 2.x ...

  8. Android自己定义控件系列二:自己定义开关button(一)

    这一次我们将会实现一个完整纯粹的自己定义控件,而不是像之前的组合控件一样.拿系统的控件来实现.计划分为三部分:自己定义控件的基本部分,自己定义控件的触摸事件的处理和自己定义控件的自己定义属性: 以下就 ...

  9. 沉浸式Web初体验

    沉浸就是让人专注在当前的情境下感到愉悦和满足,而忘记真实世界的情境.心流理论能有力解释人们废寝忘食地投入一件事情的状态. 心流理论的核心就是说当人的技能与挑战最佳匹配时能达到心流状态.比如玩一个游戏, ...

  10. android studio每次启动都要在fetching Android sdk compoment information停好久 怎么解决?

    网上有人给出了方案:1)进入刚安装的Android Studio目录下的bin目录.找到idea.properties文件,用文本编辑器打开.2)在idea.properties文件末尾添加一行: d ...