NetRoc's Blog

N-Tech

 

WinDbg 文档翻译----49

cc682/NetRoc

http://netroc682.spaces.live.com/

ba (Break on Access)

ba 命令设置一个数据断点。该断点在指定内存被访问时触发。

语法

用户模式

[~Thread] ba[ID] Access Size [Options] [Address [Passes]] ["CommandString"] 

内核模式

ba[ID] Access Size [Options] [Address [Passes]] ["CommandString"] 

参数

Thread

指定要设置断点的线程。该语法的更多信息,查看线程语法。仅有用户模式可以指定线程。

ID

指定一个可选的数字用来标识该断点。如果没有指定ID,则使用第一个可用的断点号。在ba和ID号之间不能加入空格。每种处理器都只支持一定数量的数据断点。但这对ID号码的值没有任何限制。如果使用中括号([])将ID括起来,ID 可以包含任何表达式。该语法的更多信息,查看数值表达式语法。

Access

指定断点触发的访问类型。该参数可以是下面的值之一。

选项

行为

e (执行)

当CPU取指定地址的指令时中断到调试器。

r (读/写)

当CPU读写指定地址时中断到调试器。

w (写)

当CPU写指定地址时中断到调试器。

i (i/o)

(Microsoft Windows XP和之后版本、仅内核模式、仅x86系统)当指定Address的I/O端口被访问时中断到调试器。

 

在Access 和Size 之间不能加入空格。

注意  在Windows Server 2003 Service Pack 1 (SP1)上,在基于Itanium的计算机上使用WOW64模拟x86,数据断点的执行选项不能使用,但是可以使用读写选项。

Size

指定要监控访问的位置的大小,以字节为单位。在x86处理器上,该参数可以是1、2或4。但是如果Access 为e,Size 必须是1。

在x64处理器上,该参数可以是1、2、4或者8。但是,如果Access 为e,Size 必须是1。

在基于Itanium的处理器上,该参数可以是从1到0x80000000中任何2的幂。

在Access 和Size 间不能加入空格。

Options

指定断点选项。除非单独指出,可以使用任意数量的下面这些选项:

/1

创建一个"一次性" ("one-shot")断点。该断点触发之后就会被从断点列表中永远去除。

/f PredNum

(仅Itanium、仅用户模式) 指定一个断言号。该断点使用相应的断言寄存器(predicate register)进行判定(例如,bp /f 4 address设置一个使用p4断言寄存器进行判定的断点)。关于断言寄存器的更多信息,查看Itanium结构体系。

/p EProcess

(仅内核模式) 指定一个和该断点关联的进程。EProcess 必须是EPROCESS结构的实际地址,而不是PID。这种断点仅在指定的进程上下文内遇到的时候才会触发。

/t EThread

(仅内核模式) 指定一个和断点关联的线程。EThread必须是ETHREAD结构的实际地址而不是线程ID。这种断点仅在指定的线程上下文内遇到的时候才会触发。如果同时使用/p EProcess 和/t EThread ,它们可以按任意顺序排列。

/c MaxCallStackDepth

使得断点仅当调用堆栈小于MaxCallStackDepth 深度时才激活。不能将此选项和/C 组合使用。

/C MinCallStackDepth

使得断点仅当调用堆栈大于MinCallStackDepth深度时才激活。不能将此选项和/c 组合使用。

Address

指定任意合法地址。如果程序访问了该地址的内存,调试器停止执行并显示所有寄存器和标志的当前值。这个地址必须是一个偏移并且根据不同的Size 参数适当的对齐。(例如,如果Size是4,Address必须是4的倍数。)如果省略掉Address,则会使用当前的指令计数器。该语法的更多信息,查看地址和地址区域语法。

Passes

指定断点激活之前要忽略的次数。该数字可以使任何16位值。程序计数器通过该点而不激活断点的次数是该数字减1次。因此,省略该数字等于将它设置为1。注意该数字只计算程序执行通过该点的次数。单步或跟踪通过该点并不计算在内。当到达指定次数后,可以通过清除和重设断点来重置该计数。

CommandString

指定每次遭遇断点指定次数后需要执行的命令列表。这些命令仅在执行g (Go)命令后遇到断点时才执行,而不能在t (Trace) 或p (Step) 命令之后执行。CommandString 中的调试器命令可以包含参数。

必须使用引号将该命令字符串括起来,并且需要使用分号来分隔多条命令。可以使用标准C控制字符(如\n 和\")。二级引号(\")中的分号被当作引号中的字符串的一部分。

该参数是可选的

环境

模式

用户模式、内核模式

目标

仅活动目标

平台

所有

 

注释

调试器使用ID 号来在之后的bc (Breakpoint Clear)、bd (Breakpoint Disable)和be (Breakpoint Enable)命令中引用该断点。使用bl (Breakpoint List) 命令来查看关联到当前设置的所有断点上的ID号。

ba 命令支持由调试寄存器提供的一些功能。可以在特定内存位置被读、写或执行时中断下来。

断点仅在给定地址给定长度的内存被访问时起效。如果被访问的内存仅是和要监控的内存部分重叠,断点不会被触发。

虽然所有断点类型都需要大小,但是执行断点仅在该地址是指令的第一个字节时就可以触发。

在内核模式下调试多处理器系统时,使用bp (Set Breakpoint) 或ba命令设置的断点会应用到所有处理器。例如,当前处理器是3并且输入了ba e1 MemoryAddress 来在MemoryAddress 设置一个断点,任何处理器(不止是处理器3)执行到该地址时都会产生断点陷阱。

不能使用ba 命令来为用户模式进程设置初始断点。

不能对相同地址创建多个仅CommandString 值不同的断点。但是,可以在单个地址创建多个不同条件的断点(例如/p、 /t、/c和/C的值不同)。

内核模式调试时,目标机的用户模式和内核模式数据断点有区别。用户模式数据断点不能作用于内核执行或内存访问。根据用户模式代码是否使用了调试寄存器状态和是否有用户模式调试器附加上去,内核模式数据断点可以作用于用户模式的执行或内存访问。

要将当前进程已存在的数据断点应用到另一个寄存器上下文中,可以使用.apply_dbp (Apply Data Breakpoint to Context)命令。

下面的例子说明ba命令的使用。下例对变量myVar 上的4字节读访问设置断点。

0:000> ba r4 myVar

下面的命令对从0x3F8到0x3FB 端口上的所有串口访问设置断点。该断点在对这些端口进行任何读写操作时都会触发。

kd> ba i4 3f8

附加信息

关于如何使用断点的示例和更多信息、其他断点命令和控制断点的方法、如何在内核调试器下设置用户空间的断点,查看使用断点。关于条件断点的更多信息,查看 设置条件断点。

bc (Breakpoint Clear)

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

语法

bc Breakpoints 

参数

Breakpoints

指定要移除的断点的ID号。可以指定任意多个断点。必须用空格或逗号分隔多个断点。也可以使用连字符(-)来指定断点ID的范围。使用星号(*)来指定所有断点。如果要使用数值表达式作为ID,要将它括在中括号([])内。如果使用带通配符的字符串来匹配断点的符号名,需要将它用引号( " " )括起来。

环境

模式

用户模式、内核模式

目标

仅活动目标

平台

所有

 

注释

使用bl (Breakpoint List)命令来显示所有已设置的断点、它们的ID号和状态。

附加信息

关于如何使用断点、其他断点命令和控制断点的方法、如何在内核调试器下在用户空间设置断点的更多信息,查看使用断点。关于设置条件断点的更多信息,查看设置条件断点。

bd (Breakpoint Disable)

bd 命令禁用但不删除先前设置的断点。

语法

bd Breakpoints 

参数

Breakpoints

指定要禁用的断点的ID号。可以指定任意多个断点。必须用空格或逗号分隔多个断点。也可以使用连字符(-)来指定断点ID的范围。使用星号(*)来指定所有断点。如果要使用数值表达式作为ID,要将它括在中括号([])内。如果使用带通配符的字符串来匹配断点的符号名,需要将它用引号( " " )括起来。

环境

模式

用户模式、内核模式

目标

仅活动目标

平台

所有

 

注释

当一个断点被禁用时,系统不会检查它指定的条件是否触发。

使用be (Breakpoint Enable) 命令来重新启用断点。

使用bl (Breakpoint List)命令来显示所有已设置的断点、它们的ID号和状态。

附加信息

关于如何使用断点、其他断点命令和控制断点的方法、如何在内核调试器下在用户空间设置断点的更多信息,查看使用断点。关于设置条件断点的更多信息,查看设置条件断点。

be (Breakpoint Enable)

be命令启用先前被禁用掉的一个或多个断点。

语法

be Breakpoints 

参数

Breakpoints

指定要启用的断点的ID号。可以指定任意多个断点。必须用空格或逗号分隔多个断点。也可以使用连字符(-)来指定断点ID的范围。使用星号(*)来指定所有断点。如果要使用数值表达式作为ID,要将它括在中括号([])内。如果使用带通配符的字符串来匹配断点的符号名,需要将它用引号( " " )括起来。

环境

模式

用户模式、内核模式

目标

仅活动目标

平台

所有

 

注释

使用bl (Breakpoint List)命令来显示所有已设置的断点、它们的ID号和状态。

附加信息

关于如何使用断点、其他断点命令和控制断点的方法、如何在内核调试器下在用户空间设置断点的更多信息,查看使用断点。关于设置条件断点的更多信息,查看设置条件断点。

bl (Breakpoint List)

bl 命令列出已存在的断点的信息。

语法

bl [Breakpoints] 

参数

Breakpoints

指定要列举的断点的ID号。如果省略掉Breakpoints,调试器列出所有断点。可以指定任意多个断点。必须用空格或逗号分隔多个断点。也可以使用连字符(-)来指定断点ID的范围。使用星号(*)来指定所有断点。如果要使用数值表达式作为ID,要将它括在中括号([])内。如果使用带通配符的字符串来匹配断点的符号名,需要将它用引号( " " )括起来。

环境

模式

用户模式、内核模式

目标

仅活动目标

平台

所有

 

注释

下面是一个bl 命令输出的示例。

0:000> bl
 0 e 010049e0     0001 (0001)  0:**** stst!main

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

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

示例

下面是一个bl命令的示例。

0:000> bl
 0 e 010049e0     0001 (0001)  0:**** stst!main

输出包含如下信息:

  • 断点ID为0。
  • 断点状态为e (启用)。
  • 断点不是未定的(输出中没有u)。
  • 断点的虚拟地址是010049e0。
  • 断点在第一次执行该代码时被激活,并且该代码还没有在调试器中执行过。该信息说明"忽略次数"("passes remaining")还剩余1次(0001),并且初始设置的忽略次数为1 ((0001))。
  • 这不是一个线程相关的断点 (****)。
  • 该断点设置在stst 模块的main上。

附加信息

关于如何使用断点、其他断点命令和控制断点的方法、如何在内核调试器下在用户空间设置断点的更多信息,查看使用断点。关于设置条件断点的更多信息,查看设置条件断点。

bp, bu, bm (Set Breakpoint)

bp、bu和bm命令设置一个或多个软断点(software breakpoints)。可以组合位置、条件和选项来设置各种不同类型的软断点。

语法

用户模式

[~Thread] bp[ID] [Options] [Address [Passes]] ["CommandString"] 
[~Thread] bu[ID] [Options] [Address [Passes]] ["CommandString"] 
[~Thread] bm [Options] SymbolPattern [Passes] ["CommandString"]

内核模式

bp[ID] [Options] [Address [Passes]] ["CommandString"] 
bu[ID] [Options] [Address [Passes]] ["CommandString"] 
bm [Options] SymbolPattern [Passes] ["CommandString"]

参数

Thread

指定要应用该断点的线程。该语法的更多信息,查看线程语法。只能在用户模式下指定线程。如果没有指定线程,则断点应用到所有线程。

ID

指定用于标识该断点的十进制数字。

调试器在创建断点时指派ID,但是之后可以通过br (Breakpoint Renumber)命令来改变它。在其他调试器命令中使用ID来引用断点。要显示断点的ID,可以使用bl (Breakpoint List) 命令。

在命令中使用ID时,不能在命令(bp 或bu)和ID号之间加入空格。

ID 参数总是可选的。如果不指定ID,调试器使用第一个可用的断点号。内核模式下只能设置32个断点。用户模式下可以设置任意多个断点。但是哪种情况下对ID号的值都没有限制。如果使用中括号([])将ID括起来,ID可以包含任意表达式。该语法的详细信息,查看数值表达式语法。

Options

指定断点选项。除非特别指出,可以设置任意数量的下面的选项:

/1

创建一个一次性("one-shot")断点。该断点触发之后就会被从断点列表中永远去除。

/f PredNum

(仅Itanium、仅用户模式) 指定一个断言号。该断点使用相应的断言寄存器(predicate register)进行判定(例如,bp /f 4 address设置一个使用p4断言寄存器进行判定的断点)。关于断言寄存器的更多信息,查看Itanium结构体系。

/p EProcess

(仅内核模式) 指定一个和该断点关联的进程。EProcess 必须是EPROCESS结构的实际地址,而不是PID。这种断点仅在指定的进程上下文内遇到的时候才会触发。

/t EThread

(仅内核模式) 指定一个和断点关联的线程。EThread必须是ETHREAD结构的实际地址而不是线程ID。这种断点仅在指定的线程上下文内遇到的时候才会触发。如果同时使用/p EProcess 和/t EThread ,它们可以按任意顺序排列。

/c MaxCallStackDepth

使得断点仅当调用堆栈小于MaxCallStackDepth 深度时才激活。不能将此选项和/C 组合使用。

/C MinCallStackDepth

使得断点仅当调用堆栈大于MinCallStackDepth深度时才激活。不能将此选项和/c 组合使用。

/a

(仅bm 使用) 在所有指定位置设置断点,不管他们在数据空间还是代码空间。由于数据上的断点可能造成程序错误,所以只能在确认安全的位置使用该选项。

/d

(仅bm 使用) 将断点位置转换为地址。因此,如果代码位置改变了,这个断点还是保持在原来的位置,而不是像使用SymbolPattern 来设置的一样。使用/d 来避免模块加载或重加载时重新求值对断点进行的改变。

/(

(仅bm 使用) 在SymbolString 定义的符号字符串中包含参数列表信息。

这个功能使得可以对具有相同名字但是不同参数列表的重载函数设置断点。例如, bm /( myFunc 同时在myFunc(int a)和myFunc(char a)上设置断点。如果没有"/(",对myFunc 设置的断点会失败,因为这样不能确定断点设置到哪一个myFunc 上。

Address

指定要设置断点处的指令的第一个字节位置。如果省略Address ,则使用当前指令指针。该语法的更多信息,查看地址和地址区域语法。

Passes

指定断点激活之前要忽略的次数。调试器跳过该断点指定次数。该数字可以使任何16位或32位值。

默认情况下,断点在第一次执行断点位置的代码时被激活。这种默认情况和把Passes 设置为1是一样的。要使得断点在程序至少执行该代码一次之后才激活,可以将这个值设置为2或更大。例如,值为2时,使得断点在第二次执行到该代码时被激活。

该参数创建一个在每次执行断点处的代码时被减少1的计数器。要查看Passes 计数器的初始值和当前值,使用bl (Breakpoint List)。

Passes 仅当程序响应g (Go)命令并执行通过断点时才减少。单步或跟踪(tracing)通过它是不会减少的。当Passes 到达1时,可以通过清除并重设断点来重置它。

CommandString

指定每次遭遇断点指定次数后需要执行的命令列表。必须将CommandString 放到引号中。使用分号来分隔多条命令。

CommandString 中的调试器命令可以包含参数。可以使用标准C控制字符(如\n 和\")。二级引号(\")中的分号被当作引号中的字符串的一部分。

CommandString命令仅当程序响应g (Go)命令并执行通过断点时才会执行。单步或跟踪(tracing)执行断点处的命令时是不会触发的。

任何在中断后恢复程序运行的命令(如g 或t)都会结束命令列表的执行。

SymbolPattern

指定符号模板。调试器尝试使用已存在的符号来匹配该模板,并在所有匹配项上设置断点。SymbolPattern可以包含各种通配符和修饰符。该语法的更多信息,查看字符串通配符语法。因为这些字符时用来匹配符号的,这种匹配不区分大小写,并且 头部的单个下划线(_)表示任意数量的起始下划线。

环境

模式

用户模式、内核模式

目标

仅活动目标

平台

所有

 

注释

bp、bu和bm 命令设置新断点,但是它们有不同的特点:

  • bp (Set Breakpoint)命令在指定地址的断点位置上设置断点。如果设置断点时调试器还不能将地址表达式计算为断点位置,bp 断点被自动转换为bu 断点。使用bp 命令来设置在模块被卸载之后就不会再被激活的断点。
  • bu (Set Unresolved Breakpoint)命令设置 延迟的或未定断点。bu 设置在命令中指定的符号引用的断点位置上(不是一个地址上),并且当所引用的模块能够确定时激活。
  • bm (Set Symbol Breakpoint) 命令在能够匹配指定模板的符号上设置断点。该命令可以设置多于一个的断点。默认情况下,当模板被匹配之后,bm 断点和bu 断点相同。即bm 断点是针对符号引用设置的延迟断点。但是bm /d 命令会创建一个或多个bp断点。每个断点都被设置在能够匹配的位置的地址上,并且不会跟随模块状态改变。

使用bp命令时,断点位置始终被转换成地址。如果bp 断点设置的代码被移动了,该断点仍然保持在相同位置并且可能指向不同的代码或者非法位置。

相反的,bu 断点始终和命令指定的符号化的断点位置关联(一般是符号加上一个可选的偏移)。这种关联在符号的值改变或者包含该位置的模块加载或卸载之后仍然保持。

使用bp 设置的断点会保持到使用bc (Breakpoint Clear)命令或WinDbg的Breakpoints 对话框移除为止。但是,因为这些断点指向的是一个地址,bp 断点在包含所引用的位置的模块卸载之后就不再有效了。

bu 设置的断点会保存在WinDbg工作空间中,但是bp 设置的断点不会保存。

当使用鼠标在WinDbg的反汇编窗口或源码窗口中设置断点时,调试器创建bu断点。

bm 在想使用包含通配符的符号模板来设置断点时很有用。bm SymbolPattern 语法和使用x SymbolPattern然后对搜索结果使用bu 是一样的。例如,要在Myprogram 模块中所有以字符串"mem"开头的符号上设置断点,可以使用如下命令。

0:000> bm myprogram!mem* 
  4: 0040d070 MyProgram!memcpy
  5: 0040c560 MyProgram!memmove
  6: 00408960 MyProgram!memset

由于bm命令设置软断点(不是处理器断点),它会自动避开数据位置,以避免破坏数据。

但是,当使用bp 和bm /a时要小心。这些命令可以在数据段中设置软断点。调试器在代码上设置软断点时,会将处理器指令替换为中断指令。但是当调试器在数据段设置软断点时,会把数据替换为中断指令。这种中断指令会破坏数据。只有在只当作代码进行执行的数据上设置软件断点才是安全的。要在数据段设置断点,使用ba (Break on Access)命令。该命令可以设置数据断点而不是软件断点。

要在例如C++公有类这样的任意文本上设置断点,或者在operator new 函数上设置断点,需要将表达式括在园括号中。例如,使用bp (??MyPublic) 或bp (operator new)。

要在MASM表达式类型的任意文本上设置断点,使用bu @!"text"。要使用C++语法文本设置断点,对C++兼容的符号使用bu @@c++(text)。

Bp、bu和bm命令通过将处理器命令替换为中断指令来设置软断点。要调试只读代码或不能改变的代码,使用ba e 命令,e用于设置执行访问。

如果单个逻辑代码行跨越了多个物理行,断点设置在语句或调用的最后一个物理行上。如果调试器在要求的位置不能设置断点,则会将断点放到下一个可用的位置上。

如果指定了Thread,断点设置在指定线程上。例如,~*bp在所有线程上设置断点, ~#bp在产生当前异常的线程上设置,而 ~123bp 在线程123上设置。~bp 和~.bp 命令都在当前线程设置断点。

在内核模是下调试多处理器系统时,使用bp 或ba (Break on Access) 设置的断点会应用到所有处理器。例如,如果当前处理器是3,并且输入bp MemoryAddress来在 MemoryAddress上设置了断点。任何执行到该地址的处理器(不止是处理器3)都会产生断点陷阱。

示例

下面的例子说明了如何使用不bp命令。这个命令在MyTest 函数后面12字节位置处设置断点。该断点忽略前6次对指定代码的执行,但是第7次执行该代码时会中断下来。

0:000> bp MyTest+0xb 7 

下面的命令在RtlRaiseException 上设置断点,显示eax寄存器并显示符号MyVar 的值,然后继续。

kd> bp ntdll!RtlRaiseException "r eax; dt MyVar; g"

附加信息

关于如何使用断点、其他断点命令和控制断点的方法、如何在内核调试器下在用户空间设置断点的更多信息,查看使用断点。关于设置条件断点的更多信息,查看设置条件断点。

br (Breakpoint Renumber)

br 命令重新对一个或多个断点进行编号。

语法

br OldID NewID [OldID2 NewID2 ...] 

参数

OldID

指定断点的当前ID号。

NewID

指定要设置的新ID号。

环境

模式

用户模式、内核模式

目标

仅活动目标

平台

所有

 

注释

可以使用br 命令来一次对任意数量的断点重新编号。对每个断点,按照旧ID、新ID的顺序作为br的参数。

如果已经有一个断点的ID等于NewID ,命令会失败并提示错误信息。

附加信息

关于如何使用断点、其他断点命令和控制断点的方法、如何在内核调试器下在用户空间设置断点的更多信息,查看使用断点。关于设置条件断点的更多信息,查看设置条件断点。

posted on 2008-06-12 14:46 NetRoc 阅读(472) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。

导航

统计

常用链接

留言簿(7)

随笔档案(99)

文章分类(35)

文章档案(32)

Friends

Mirror

搜索

最新评论

阅读排行榜

评论排行榜