cc682/NetRoc
http://netroc682.spaces.live.com/
m (Move Memory)
m 命令将内存内容从一个位置拷贝到另一个。
不要将该命令和~m (Resume Thread)命令混淆。
语法
m Range Address
参数
Range
指定要拷贝的内存区域。该参数的语法的更多信息,查看地址和地址区域语法。
Address
指定目标内存区域的起始地址。该参数的语法的更多信息,查看地址和地址区域语法。
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
Address 指定的内存区域可以是Range 指定的内存区域的一部分。重叠的移动也可以被正确的处理。
附加信息
关于内存操作的更多信息和其他内存相关命令的说明,查看读写内存。
n (Set Number Base)
n命令将默认的数字基数(radix)设置为指定值,或者显示当前基数。
不要将该命令和~n (Suspend Thread)命令混淆。
语法
n [Radix]
参数
Radix
设置用于数值显示的输入的默认基数。可以使用下面的值之一。
|
值
|
说明
|
|
8
|
8进制
|
|
10
|
10进制
|
|
16
|
16进制
|
如果省略Radix,则显示当前的默认基数。
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
当前基数会作用于MASM表达式的输入和输出。它并不作用于C++ 表达式的输入输出。关于这些表达式的更多信息,查看表达式求值。
调试器启动时,默认的基数被设置为16。
在所有MASM表达式中,数字的值使用当前基数(16, 10, 或8)来进行解释。可以通过指定0x 前缀(16进制)、 0n 前缀(10进制)、0t 前缀(8进制)或者0y 前缀(2进制)来覆盖当前基数。
ob, ow, od (Output to Port)
ob、ow和od 命令将一个字节、字或者双字发送到指定端口。
语法
ob Address Value
ow Address Value
od Address Value
参数
Address
指定端口地址。
Value
指定要写入端口的16进制值。
环境
|
模式
|
仅内核模式
|
|
目标
|
仅活动调试
|
|
平台
|
仅x86
|
注释
ob 命令写入单个字节、ow 命令写入一个WORD,od命令写入一个DWORD。
确认写入WORD或者DWORD的端口支持该大小。
参见
ib, id, iw (Input from Port)
p (Step)
p 命令执行一条指令或者一行源码,并且选择性的显示所有寄存器和标志位的结果。当发生子函数调用或中断时,他们被当作单独的一步。
语法
用户模式
[~Thread] p [r] [= StartAddress] [Count] ["Command"]
内核模式
p [r] [= StartAddress] [Count] ["Command"]
参数
Thread
指定要继续执行的线程。所有其它线程都会被冻结。该语法的更多信息,查看线程语法。只能在用户模式下指定线程。
r
打开或关闭对寄存器和标志位的显示。默认情况下,寄存器和标志位会被显示出来。可以通过pr、 tr或.prompt_allow -reg 命令来禁止显示。这三个命令都可以用来控制该设置,并且可以覆盖之前使用这些命令进行任何设置。
也可以通过l-os 命令禁止对寄存器的显示。这个设置和其他三个命令是分开的。要控制哪些寄存器和标志位被显示出来,使用rm (Register Mask) 命令。
StartAddress
指定执行开始的地址。如果没有使用StartAddress,则从指令指针指向的指令开始执行。该语法的更多信息,查看地址和地址区域语法。
Count
指定在停止前要单步执行的指令数量或源码行数。每一步在调试器命令窗口中都会显示为一个单独的动作。默认值为1。
Command
指定在单步完成后要执行的调试器命令。该命令在标准的p结果显示出来之前就会执行。如果还使用了Count,这个命令会在所有步骤都执行完成后才会执行(但是在最后一步的结果显示出来之前)。
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
仅活动调试
|
|
平台
|
所有
|
注释
指定了Count 时,每条指令都会像单步执行它一样被显示出来。
如果调试器在单步的时候遇到call指令或中断,被调用的子函数如果没有遇到断点,会直接执行完成。到达调用或中断的下一条指令时,控制会返回给调试器。
根据调试器运行在汇编模式还是源码模式,每一步都执行单独的一条汇编指令或源代码行。使用l+t 和l-t 命令或者WinDbg工具栏上的按钮来在这些模式之间切换。
在WinDbg中快速的单步执行很多次时,调试信息窗口会在每一步之后都进行刷新。如果这种刷新造成响应时间变长,可以使用.suspend_ui (Suspend WinDbg Interface) 来临时暂停这些窗口的刷新。
附加信息
关于执行p命令的更多信息和其他相关命令的概述,查看控制调试目标。
pa (Step to Address)
pa命令执行程序直到到达指定地址,每一步都会被显示出来。
语法
用户模式
[~Thread] pa [r] [= StartAddress] StopAddress ["Command"]
内核模式
pa [r] [= StartAddress] StopAddress ["Command"]
参数
Thread
指定要继续执行的线程。所有其它线程都会被冻结。该语法的更多信息,查看线程语法。只能在用户模式下指定线程。
r
打开或关闭对寄存器和标志位的显示。默认情况下,寄存器和标志位会被显示出来。可以通过par、pr、tr或.prompt_allow -reg 命令来禁止显示。这些命令都可以用来控制该设置,并且可以覆盖之前使用这些命令进行任何设置。
也可以通过l-os 命令禁止对寄存器的显示。这个设置和其他三个命令是分开的。要控制哪些寄存器和标志位被显示出来,使用rm (Register Mask) 命令。
StartAddress
指定执行开始的地址,否则从指令指针指向的指令开始执行。该语法的更多信息,查看地址和地址区域语法。
StopAddress
指定要停止执行的地址。该地址必须刚好是一条指令的地址。
Command
指定在单步完成后要执行的调试器命令。该命令在标准的pa结果显示出来之前就会执行。如果还使用了StopAddress,这个命令会在到达StopAddress后才会执行(但是在最后一步的结果显示出来之前)。
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
仅活动调试
|
|
平台
|
所有
|
注释
pa 命令使得目标开始执行。这种执行会持续到到达指定的指令或遇到断点。
注意 如果在内核模式下使用该命令,在任何虚拟地址空间中,只要遇到指定的虚拟地址处的指令,执行就会停止。
执行时,所有步骤都会明确的显示出来。调用的函数被当作一个单位来执行。但是,该命令的显示和直接重复使用p (Step)直到程序计数器到达指定地址类似。
例如,下面的命令单步执行目标的代码直到到达当前函数的返回地址。
0:000> pa @$ra
下面的命令演示了pa和kb命令命令一起用来显示堆栈回溯:
0:000> pa 70b5d2f1 "kb"
附加信息
相关命令的更多信息,查看控制调试目标。
pc (Step to Next Call)
pc执行程序直到到达一条call指令。
语法
用户模式
[~Thread] pc [r] [= StartAddress] [Count]
内核模式
pc [r] [= StartAddress] [Count]
参数
Thread
指定要继续执行的线程。所有其它线程都会被冻结。该语法的更多信息,查看线程语法。只能在用户模式下指定线程。
r
打开或关闭对寄存器和标志位的显示。默认情况下,寄存器和标志位会被显示出来。可以通过pcr、 pr、tr或.prompt_allow -reg 命令来禁止显示。这些命令都可以用来控制该设置,并且可以覆盖之前使用这些命令进行任何设置。
也可以通过l-os 命令禁止对寄存器的显示。这个设置和其他三个命令是分开的。要控制哪些寄存器和标志位被显示出来,使用rm (Register Mask) 命令。
StartAddress
指定执行开始的地址,否则从指令指针指向的指令开始执行。该语法的更多信息,查看地址和地址区域语法。
Count
指定遇到多少个call指令该命令才会停下来。默认值为1。
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
仅活动调试
|
|
平台
|
所有
|
注释
pc 命令使的目标开始执行。这种执行一直持续到遇到call指令或断点。
如果程序计数器已经到达一个call指令,整个调用都会被执行。该调用返回后,执行会持续到遇到下一个call时。对这个调用进行执行而不是跟踪,是pc和tc (Trace to Next Call)唯一的不同。
在源码模式下,一行代码可能对应多条汇编指令。Pc命令不会在关联到当前源码行的call指令处停下来。
附加信息
相关命令的更多信息,查看控制调试目标。
pct (Step to Next Call or Return)
pct 命令执行程序,直到遇到call指令或返回指令。
语法
用户模式
[~Thread] pct [r] [= StartAddress] [Count]
内核模式
pct [r] [= StartAddress] [Count]
参数
Thread
指定要继续执行的线程。所有其它线程都会被冻结。该语法的更多信息,查看线程语法。只能在用户模式下指定线程。
r
打开或关闭对寄存器和标志位的显示。默认情况下,寄存器和标志位会被显示出来。可以通过pctr、 pr、tr或.prompt_allow -reg 命令来禁止显示。这些命令都可以用来控制该设置,并且可以覆盖之前使用这些命令进行任何设置。
也可以通过l-os 命令禁止对寄存器的显示。这个设置和其他三个命令是分开的。要控制哪些寄存器和标志位被显示出来,使用rm (Register Mask) 命令。
StartAddress
指定执行开始的地址,否则从指令指针指向的指令开始执行。该语法的更多信息,查看地址和地址区域语法。
Count
指定遇到多少个call或者return指令该命令才会停下来。默认值为1。
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
仅活动调试
|
|
平台
|
所有
|
注释
pct 命令使得目标开始执行,直到遇到call或return指令或断点。
如果程序计数器正在一条call或return指令上,则会执行整个调用或返回。当调用结束或返回之后,继续执行直到遇到其他call或return。对这种调用进行执行而不是跟踪,是pct 和tct (Trace to Next Call or Return)唯一的不同。
源码模式下,一个代码行可能和多条汇编指令关联。pct 不会在当前源码行关联的call或return处停止。
附加信息
相关命令的更多信息,查看控制调试目标。
ph (Step to Next Branching Instruction)
ph命令执行程序直到遇到任何种类的分支指令,包括条件或非条件跳转、调用、返回和系统调用。
语法
用户模式
[~Thread] ph [r] [= StartAddress] [Count]
内核模式
ph [r] [= StartAddress] [Count]
参数
Thread
指定要继续执行的线程。所有其它线程都会被冻结。该语法的更多信息,查看线程语法。只能在用户模式下指定线程。
r
打开或关闭对寄存器和标志位的显示。默认情况下,寄存器和标志位会被显示出来。可以通过phr、 pr、tr或.prompt_allow -reg 命令来禁止显示。这些命令都可以用来控制该设置,并且可以覆盖之前使用这些命令进行任何设置。
也可以通过l-os 命令禁止对寄存器的显示。这个设置和其他三个命令是分开的。要控制哪些寄存器和标志位被显示出来,使用rm (Register Mask) 命令。
StartAddress
指定执行开始的地址,否则从指令指针指向的指令开始执行。该语法的更多信息,查看地址和地址区域语法。
Count
指定遇到多少个分支指令该命令才会停下来。默认值为1。
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
仅活动调试
|
|
平台
|
所有
|
注释
ph 命令使得目标开始执行,直到遇到分支指令或断点。
如果程序计数器正在一条分支指令上,则会先执行该分支指令。当该指令结束之后,继续执行直到遇到其他分支指令。对这种分支进行执行而不是跟踪,是ph 和th (Trace to Next Branching Instruction)唯一的区别。
源码模式下,一个代码行可能和多条汇编指令关联。ph 不会在当前源码行关联的分支指令处停止。
附加信息
相关命令的更多信息,查看控制调试目标。
pt (Step to Next Return)
pt 命令执行程序直到遇到返回指令。
语法
用户模式
[~Thread] pt [r] [= StartAddress] [Count] ["Command"]
内核模式
pt [r] [= StartAddress] [Count] ["Command"]
参数
Thread
指定要继续执行的线程。所有其它线程都会被冻结。该语法的更多信息,查看线程语法。只能在用户模式下指定线程。
r
打开或关闭对寄存器和标志位的显示。默认情况下,寄存器和标志位会被显示出来。可以通过ptr、 pr、tr或.prompt_allow -reg 命令来禁止显示。这些命令都可以用来控制该设置,并且可以覆盖之前使用这些命令进行任何设置。
也可以通过l-os 命令禁止对寄存器的显示。这个设置和其他三个命令是分开的。要控制哪些寄存器和标志位被显示出来,使用rm (Register Mask) 命令。
StartAddress
指定执行开始的地址,否则从指令指针指向的指令开始执行。该语法的更多信息,查看地址和地址区域语法。
Count
指定遇到多少个return指令该命令才会停下来。默认值为1。
Command
指定单步完成后要执行的调试器命令。该命令在标准的pt结果显示之前执行。如果还使用了Count,指定命令在所有步骤完成之后执行(但是在最后一步的结果显示之前)。
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
仅活动调试
|
|
平台
|
所有
|
注释
pt 命令使得目标开始执行,直到遇到return指令或断点。
如果程序计数器正在一条return指令上,则会先执行整个返回过程。返回之后,继续执行直到遇到其他return指令。这种执行而不是跟踪,是pt 和tt (Trace to Next Return)的唯一区别。
源码模式下,一个代码行可能和多条汇编指令关联。pt不会在当前源码行关联的return指令处停止。
下面的例子演示了使用pt和kb命令一起显示调用堆栈:
0:000> pt "kb"
附加信息
相关命令的更多信息,查看控制调试目标。
摘要: cc682/NetRoc
http://netroc682.spaces.live.com/
ib, iw, id (Input from Port)
ib、iw和id 命令从指定端口读取和显示字节、字或双字。
语法
ib Address iw Address id Address
参数
Address
端...
阅读全文
cc682/NetRoc
http://netroc682.spaces.live.com/
写了个隐藏内核调试器的小驱动,可以跳过一些软件对WinDbg、KD这样的内核调试器的检查。
- 跳过驱动中对KdDebuggerEnabled、KdEnteredDebugger的检查。
- 跳过对SharedUserData->KdDebuggerEnabled的检查。
- 跳过NtQuerySystemInformation对SystemKernelDebuggerInformation的检查。
- 跳过KdDisableDebugger的调用。
使用时要先用工具加载HideKd.sys,就可以针对之后加载的驱动或用户模式程序隐藏内核调试器了。这个驱动加载之后只有重起才能卸载,所以要注意不能安装成引导时启动,仅在Windows XP SP2英文版中测试通过。
下载:HideKd
cc682/NetRoc
http://netroc682.spaces.live.com/
e, ea, eb, ed, eD, ef, ep, eq, eu, ew, eza, ezu (Enter Values)
e*命令在内存中输入指定的值。
该命令不要和~E (Thread-Specific Command)限定符混淆。
语法 eD ef
e{b|d|D|f|p|q|w} Address [Values]
e{a|u|za|zu} Address "String"
e Address [Values]
参数
Address
指定要改写数据的开始位置。调试器替换Address 和之后的每个内存位置,直到所有的Values 都被使用到。
Values
指定要写入内存的一个或多个值。多个数字值之间需要使用空格分隔。如果不指定任何值,则显示指定位置的值,并提示输入数据。
String
指定要写入内存的字符串。ea 和eza 命令会把它作为ASCII字符串写入内存; eu 和ezu 命令会把它作为Unicode字符串写入内存。eza 和ezu 命令会写入结尾的NULL字符;ea 和eu 命令不会。String 必须用引号括起来。
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
该命令存在以下这些形式。ed 和eD 命令的第二个字符区分大小写。
|
命令
|
输入
|
|
e
|
输入数据的格式和前一次e* 命令一样。(如果上一次的e*命令是ea、eza、eu或ezu,则最后一个参数是String并且不能省略。
|
|
ea
|
ASCII 字符串(不以NULL结尾)。
|
|
eb
|
字节值。
|
|
ed
|
双字值(4字节)。
|
|
eD
|
双精度浮点数(8字节)。
|
|
ef
|
单精度浮点数(4字节)。
|
|
ep
|
指针大小的值。该命令根据目标机的处理器架构是32位还是64位,可能分别等于ed 或eq。
|
|
eq
|
4字值(8字节)。
|
|
eu
|
Unicode字符串(非NULL结尾)。
|
|
ew
|
字值(2字节)。
|
|
eza
|
NULL结尾的ASCII字符串。
|
|
ezu
|
NULL结尾的Unicode字符串。
|
数字值会以当前基数(16、10,或者8)进行解析。使用n (Set Number Base) 命令来改变默认基数。默认基数可以通过指定0x(16进制)、0n (10进制)、0t (8进制)或0y (2进制)前缀来覆盖。
注意 使用C++ 表达式时默认基数的行为有所不同。查看表达式求值获取详细信息。
使用eb命令输入字节值时,可以通过单引号来指定字符。如果想包含多个字符,每个都必须单独用单引号包含。这样可以输入非null结尾的字符串。例如:
eb 'h' 'e' 'l' 'l' 'o'
这些命令中不能使用C形式的转义字符(如'\0' 或'\n')。
如果省略Values 参数,会提示进行输入。指定的地址和它的内容会显示出来,并且出现Input> 提示符。这时可以进行如下这些操作:
- 通过键入值和ENTER键来输入新的值。
- 通过按下SPACE然后按下ENTER来保持内存的当前值。
- 按下ENTER来退出当前命令。
附加信息
内存操作的概述和内存相关命令,查看读写内存。
f, fp (Fill Memory)
f 和fp命令使用一个重复的模板来填充指定内存。
注意该命令不要和~F (Freeze Thread)命令混淆。
语法
f Range Pattern
fp [MemoryType] PhysicalRange Pattern
参数
Range
指定要填充的虚拟内存区域。该语法的详细信息,查看地址和地址区域语法。
PhysicalRange
(仅内核模式) 指定要填充的物理内存区域。除了不能指定符号名之外,PhysicalRange 的语法和虚拟内存区域一样。
MemoryType
(仅内核模式) 指定物理内存的种类,可以是下面这些之一:
[c]
缓存的内存(Cached memory)。
[uc]
非缓存的内存(Uncached memory)。
[wc]
写聚合内存(Write-combined memory)。
Pattern
指定用于填充内存的一个或多个字节值。
环境
|
模式
|
f: 用户模式、内核模式 fp: 仅内核模式
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
该命令使用指定的pattern 重复尽可能多次来填充range 指定的内存区域。
pattern 参数必须输入一个字节序列。可以输入数字或ASCII字符。
数字值会以当前基数(16、10或者8)进行解析。使用n (Set Number Base) 命令来改变默认基数。默认基数可以通过指定0x(16进制)、0n (10进制)、0t (8进制)或0y (2进制)前缀来覆盖。
注意 使用C++ 表达式时默认基数的行为有所不同。查看表达式求值获取详细信息。
如果使用ASCII字符,每个字符都需要用单引号括起来。不能使用C风格的转义字符(如 '\0' 或'\n')。
如果指定多个字节,它们之间必须用空格分隔。
如果pattern 比指定的范围包含的字节数多,则调试器忽略多余的值。
这里有一些例子。假设当前基数为16,下面的命令将从0012FF40 到0012FF5F 的内存用模板"ABC"重复数次来填充:
0:000> f 0012ff40 L20 'A' 'B' 'C'
下面的命令有相同作用:
0:000> f 0012ff40 L20 41 42 43
下面的例子说明如何与fp命令一起使用不同的物理内存种类c、uc和wc(内核模式):
?: kd> fp c 0012ff40 L20 'A' 'B' 'C'
?: kd> fp uc 0012ff40 L20 'A' 'B' 'C'
?: kd> fp wc 0012ff40 L20 'A' 'B' 'C'
附加信息
内存操作的概述和内存相关命令,查看读写内存。
g (Go)
g 命令开始指定进程或线程的执行。这种执行将会在程序结束、遇到BreakAddress 或者其他造成调试器停止的事件发生时停止。
语法
用户模式语法
[~Thread] g[a] [= StartAddress] [BreakAddress ... [; BreakCommands]]
内核模式语法
g[a] [= StartAddress] [BreakAddress ... [; BreakCommands]]
参数
Thread
(仅用户模式) 指定要执行的线程。语法的详细信息,查看线程语法。
a
使得任何用该命令创建的断点成为处理器断点(就像用ba创建的一样) ,而不是软断点(像用bp 和 bm创建的一样)。如果没有指定BreakAddress,则不会创建断点并且a标志无效。
StartAddress
指定要开始执行的地址。如果没有指定,调试器将执行传递给指令计数器的当前值所指向的地址。语法的详细信息,查看地址和地址范围语法。
BreakAddress
指定断点的地址。如果设置了BreakAddres,它必须是一个指令地址(即该地址必须是某条指令第一个字节的地址)。一次可以以任意顺序设置最多10个断点地址。如果BreakAddress 还未能确定,它将被作为未定断点保存起来。语法的详细信息,查看地址和地址范围语法。
BreakCommands
指定当遇到BreakAddress 设置的断点时要自动执行的命令。BreakCommands 参数必须以一个分号开头。如果指定了多个BreakAddress值,BreakCommands 会应用到每一个上。
注意 BreakCommands 参数仅在包含在其他命令的命令字符串中时可用 — 例如,在另一个断点命令或异常或事件的设置中。在一个命令行上,分号会结束g命令,并且在分号后列出的任何其他命令会在g命令完成后立即执行。
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
仅活动调试
|
|
平台
|
所有
|
注释
如果指定了Thread,则g命令使得指定线程非冻结,而冻结所有其他线程。例如,如果指定~123g、 ~#g或~*g命令,指定的线程不被冻结,而其他所有线程都会被冻结。
附加信息
关于其他执行该命令的方法和相关命令的概述,查看控制调试目标。
gc (Go from Conditional Breakpoint)
gc 命令使用和遇到断点时一样的方式(单步、跟踪或自由执行)来从一个条件断点恢复执行。
语法
gc
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
仅活动调试
|
|
平台
|
所有
|
注释
当一个条件断点的末尾包含一个执行命令时,需要使用gc命令。
例如,下面是一个正确的条件断点命令:
0:000> bp Address "j (Condition) 'OptionalCommands'; 'gc' "
当遇到该断点并且表达式为false时,恢复执行会使用前一次相同的执行类型。例如,如果使用g (Go)命令来到达该断点,则恢复为自由执行。但是如果使用单步或跟踪来到达该断点,也会以单步或跟踪的方式来恢复执行。
换句话说,下面是一个不正确的断点设置,因为即使单步执行到该断点,也总是会变成自由执行:
0:000> bp Address "j (Condition) 'OptionalCommands'; 'g' "
附加信息
相关命令的概述,查看控制调试目标。
gh (Go with Exception Handled)
gh命令将给定线程的异常标识为已处理,并且允许该线程从产生异常的指令继续执行。
语法
用户模式语法
[~Thread] gh[a] [= StartAddress] [BreakAddress ... [; BreakCommands]]
内核模式语法
gh[a] [= StartAddress] [BreakAddress ... [; BreakCommands]]
参数
Thread
(仅用户模式) 指定要执行的线程。该线程必须是因为异常而停止的。详细信息查看线程语法。
a
使得任何用该命令创建的断点成为处理器断点(就像用ba创建的一样) ,而不是软断点(像用bp 和 bm创建的一样)。如果没有指定BreakAddress,则不会创建断点并且a标志无效。
StartAddress
指定要开始执行的地址。如果没有指定,调试器将执行传递给指令计数器的当前值所指向的地址。语法的详细信息,查看地址和地址范围语法。
BreakAddress
指定断点的地址。如果设置了BreakAddres,它必须是一个指令地址(即该地址必须是某条指令第一个字节的地址)。一次可以以任意顺序设置最多10个断点地址。如果BreakAddress 还未能确定,它将被作为未定断点保存起来。语法的详细信息,查看地址和地址范围语法。
BreakCommands
指定当遇到BreakAddress 设置的断点时要自动执行的命令。BreakCommands 参数必须以一个分号开头。如果指定了多个BreakAddress值,BreakCommands 会应用到每一个上。
注意 BreakCommands 参数仅在将它包含在另一个命令的命令字符串中时可用 — 例如,在另一条断点命令或一个异常或事件设置中。在一个命令行中,分号会结束gh命令,并且分号之后的所有附加命令会在gh完成之后立即执行。
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
仅活动调试
|
|
平台
|
所有
|
注释
如果使用BreakAddress 参数来设置断点,该断点只会在当前线程触发。其他线程执行到指定的代码位置时不会停止下来。
如果指定了Thread ,gh 命令将指定线程解冻并冻结其他所有线程然后再执行。例如,如果使用~123gh、~#gh或~*gh命令,指定线程会是解冻的,而其他所有线程都被冻结。
附加信息
关于其他执行该命令的方法和相关命令的概述,查看控制调试目标。
gn, gN (Go with Exception Not Handled)
gn和gN 命令继续给定线程的执行,但是不将异常标记为已处理。这样使得应用程序的异常处理器可以处理该异常。
语法
用户模式语法
[~Thread] gn[a] [= StartAddress] [BreakAddress ... [; BreakCommands]]
[~Thread] gN[a] [= StartAddress] [BreakAddress ... [; BreakCommands]]
内核模式语法
gn[a] [= StartAddress] [BreakAddress ... [; BreakCommands]]
gN[a] [= StartAddress] [BreakAddress ... [; BreakCommands]]
参数
Thread
(仅用户模式) 指定要执行的线程。该线程必须是因为异常而停止下来的。语法的详细信息,查看线程语法。
a
使得任何用该命令创建的断点成为处理器断点(就像用ba创建的一样) ,而不是软断点(像用bp 和 bm创建的一样)。如果没有指定BreakAddress,则不会创建断点并且a标志无效。
StartAddress
指定要开始执行的地址。如果没有指定,调试器将执行传递给指令计数器的当前值所指向的地址。语法的详细信息,查看地址和地址范围语法。
BreakAddress
指定断点的地址。如果设置了BreakAddres,它必须是一个指令地址(即该地址必须是某条指令第一个字节的地址)。一次可以以任意顺序设置最多10个断点地址。如果BreakAddress 还未能确定,它将被作为未定断点保存起来。语法的详细信息,查看地址和地址范围语法。
BreakCommands
指定当遇到BreakAddress 设置的断点时要自动执行的命令。BreakCommands 参数必须以一个分号开头。如果指定了多个BreakAddress值,BreakCommands 会应用到每一个上。
注意 BreakCommands 参数仅在将它包含在另一个命令的命令字符串中时可用 — 例如,在另一条断点命令或一个异常或事件设置中。在一个命令行中,分号会结束该命令,并且分号之后的所有附加命令会在gn 或gN完成之后立即执行。
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
仅活动调试
|
|
平台
|
所有
|
注释
如果调试器不是在一个断点上停下来的,gn 和gN 的作用相同。如果调试器是在断点上停下来的,则gn无效;必须 使用大写的"N"才能执行该命令。这是一个安全性上的预防措施,因为极少会在不处理断点的情况下继续执行的。
如果使用BreakAddress 参数来设置断点,该断点只会在当前线程触发。其他线程执行到指定的代码位置时不会停止下来。
如果指定了Thread ,gn 命令将指定线程解冻并冻结其他所有线程然后再执行。例如,如果使用~123gn、~#gn或~*gn命令,指定线程会是解冻的,而其他所有线程都被冻结。
附加信息
关于其他执行该命令的方法和相关命令的概述,查看控制调试目标。
gu (Go Up)
gu命令使得目标继续执行直到当前函数完成。
语法
用户模式语法
[~Thread] gu
内核模式语法
gu
参数
Thread
(仅用户模式) 指定要执行的线程。该线程必须是因为异常而停止下来的。语法的详细信息,查看线程语法。
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
仅活动调试
|
|
平台
|
所有
|
注释
gu 命令执行目标,直到当前函数调用返回。
如果当前函数是递归调用的,gu 在当前函数的当前实例(current instance)返回之前不会停止目标的执行。这时,gu和g @$ra不同,后者会在每次运行到该函数的返回地址时中断。
注意 gu 命令通过测量调用堆栈的深度来区分不同的函数调用的实例。在汇编模式下,应该在参数入栈之后,任何可能造成这种测量不正确的操作之前执行该命令。函数的返回被编译器优化到其他位置的话,可能也会造成该命令在错误的实例返回时停止。这些错误是很少见的,并且只会在函数的递归调用时出现。
如果指定了Thread ,gu 命令将指定线程解冻并冻结其他所有线程然后再执行。例如,如果使用~123gu、~#gu或~*gu命令,指定线程会是解冻的,而其他所有线程都被冻结。
附加信息
关于其他执行该命令的方法和相关命令的概述,查看控制调试目标。
摘要: cc682/NetRoc
http://netroc682.spaces.live.com/
c (Compare Memory)
c 命令比较两个内存区域中保存的值。
语法
c Range Address
参数
Range
要比较的两个内存区域的第一个。该语法的更多信息,查看地址和地址区域语法。
Address
要比较的第二个...
阅读全文
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 ,命令会失败并提示错误信息。
附加信息
关于如何使用断点、其他断点命令和控制断点的方法、如何在内核调试器下在用户空间设置断点的更多信息,查看使用断点。关于设置条件断点的更多信息,查看设置条件断点。
cc682/NetRoc
http://netroc682.spaces.live.com/
~e (Thread-Specific Command)
~e命令对指定线程或目标进程的所有线程执行一条或多条命令。
不要将该命令和e (Enter Values)命令混淆。
语法
~Thread e CommandString
参数
Thread
指定要执行CommandString 命令的一个或数个线程。关于该语法的更多信息,查看线程语法。
CommandString
指定要执行的一条或多条命令。多条命令之间应该用分号隔开。CommandString 包含该输入行的终止符。字母"e"后面的所有文本都被认为是该字符串的一部分。不要将CommandString 用引号括起来。
环境
|
模式
|
仅用户模式
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
只能在用户模式下指定线程。在内核模式下,波形符(~)用于引用处理器。
当仅对一个线程使用~e 命令时,~e 仅仅是使得输入变短了。例如,下面两条命令效果是一样的。
0:000> ~2e r; k; kd
0:000> ~2r; ~2k; ~2kd
但是,可以使用~e 限定符来重复一条命令或者扩展命令数次。在这种情况下使用该限定符,可以减少大量输入。例如,下面的命令对正在调试的每个线程重复执行!gle扩展命令。
0:000> ~*e !gle
如果某条命令的执行遇到错误,会继续执行下一条。
不能将~e 限定符和执行命令(g, gh, gn, gN, gu, p, pa, pc, t, ta, tb, tc, wt)一起使用。
~e 限定符不能和j (Execute If-Else) 或z (Execute While)条件命令一起使用。
如果正在调试多于一个进程,不能使用~e 命令来访问非激活进程的虚拟内存空间
附加信息
控制线程的其他命令的信息,查看控制进程和线程。
~f (Freeze Thread)
~f 命令冻结给定线程,使得它停止执行直到被解冻。
不要将该命令和f (Fill Memory) 命令混淆。
语法
~Thread f
参数
Thread
指定要冻结的线程。该语法的更多信息,查看线程语法。
环境
|
模式
|
仅用户模式
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
只能在用户模式下指定线程。在内核模式下,波形符(~)用于引用处理器。
~f命令使得指定线程被冻结。当调试器让目标恢复执行时,其他线程继续运行,而该线程会保持停止。
下面的例子说明了如何使用该命令。这个例子显示所有线程的状态。
0:000> ~* k
下例的命令冻结产生当前异常的线程。
0:000> ~# f
下面的命令查看被挂起的线程的状态。
0:000> ~* k
下面的命令解冻号码为123的线程。
0:000> ~123 u
附加信息
如何冻结线程和其他控制线程的冻结和挂起的命令,查看控制进程和线程。
~u (Unfreeze Thread)
~u命令解冻指定的线程。
不要将该命令和U (Unassemble)命令混淆。
语法
~Thread u
参数
Thread
指定要解冻的一个或多个线程。该语法的更多信息,查看线程语法。
环境
|
模式
|
仅用户模式
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
只能在用户模式下指定线程。在内核模式下,波形符(~)用于引用处理器。
下面的示例说明了如何使用 ~ 命令。
这个命令显示所有线程的当前状态。
0:000> ~* k
该命令冻结造成当前异常的线程。
0:000> ~# f
该命令查看被挂起的线程的状态。
0:000> ~* k
下面的命令解冻号码为123的线程。
0:000> ~123 u
附加信息
如何冻结线程和其他控制线程的冻结和挂起的命令,查看控制进程和线程。
~n (Suspend Thread)
~n命令挂起指定线程的执行。
不要将该命令和n (Set Number Base)命令混淆。
语法
~Thread n
参数
Thread
指定要挂起的一个或多个线程。该语法的更多信息,查看线程语法。
环境
注释
只能在用户模式下指定线程。在内核模式下,波形符(~)用于引用处理器。
每执行一次~n 命令,线程的挂起计数都增加1。
使用该命令时会显示线程的开始地址。
附加信息
关于挂起计数和如何挂起线程、以及控制线程的挂起和冻结的命令列表,查看控制进程和线程。
~m (Resume Thread)
~m命令恢复指定线程的执行。
不要将该命令和m (Move Memory)命令混淆。
语法
~Thread m
参数
Thread
指定要恢复的一个或数个线程。该语法的更多信息,查看线程语法。
环境
注释
只能在用户模式下指定线程。在内核模式下,波形符(~)用于引用处理器。
每执行一次~ m 命令,线程的挂起计数都减1。
附加信息
关于挂起计数和如何挂起线程、以及控制线程的挂起和冻结的命令列表,查看控制进程和线程。
~s (Set Current Thread)
~s命令设置或显示当前线程号。
在用户模式下,~s设置当前线程。不要将该命令和~s (Change Current Processor)( 仅在内核模式下工作)、|s (Set Current Process)、||s (Set Current System)、s (Search Memory)命令混淆。
语法
~Thread s
~ s
参数
Thread
指定要设置或显示的线程。该语法的更多信息,查看线程语法。
环境
|
模式
|
仅用户模式
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
只能在用户模式下指定线程。在内核模式下,波形符(~)用于引用处理器。
如果使用了~s 语法,调试器显示当前线程的信息。
该命令也会反汇编当前系统、进程和线程的当前指令。
附加信息
更多信息和控制进程和线程的其他方法,查看控制进程和线程。
~s (Change Current Processor)
~s 命令设置在一个多处理器系统上要调试哪个处理器。
在内核模式下,~s改变当前处理器。不要将该命令和~s (Set Current Thread)(仅工作在用户模式)、|s (Set Current Process)、 ||s (Set Current System) 或s (Search Memory) 命令混淆。
语法
~Processor s
参数
Processor
指定要调试的处理器号。
环境
|
模式
|
仅内核模式
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
只能在内核模式下指定处理器。在用户模式下,波形符(~)用来引用线程。
当调试一个多处理器系统时,通过内核调试提示符的形状可以立刻知道当前处理器。下面例子中,0: 表示正在调试该计算机上的第一个处理器。
0: kd>
使用下面的命令来在处理器之间进行切换:
0: kd> ~1s
1: kd>
现在开始调试机器上的第二个处理器。
参见
多处理器语法
a (Assemble)
a 命令对指令助记符进行汇编,并将指令代码的结果放入内存。
语法
a [Address]
参数
Address
指定用于放置结果代码的内存块的开始位置。该语法的更多信息,查看地址和地址区域语法。
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
如果没有指定地址,汇编会从指令指针的当前值所指向的地址开始。要汇编新的指令,可以输入需要的助记符并按下ENTER。要结束汇编,直接按下ENTER。
由于汇编器需要搜索代码中引用到的所有符号,所以该命令可能需要一些时间才能完成。这时,可以按下CTRL+C来中止a命令。
附加信息
关于汇编调试和相关命令的更多信息,查看汇编模式调试。
ad (Delete Alias)
ad 命令从别名列表中删除一个别名。
语法
ad [/q] Name
ad *
参数
/q
指定使用安静模式。这种模式隐藏当Name指定的别名不存在时显示的错误信息。
Name
指定要删除的别名的名字。如果指定星号(*),所有别名都会被删除(即使存在名字为"*"的别名)。
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
可以使用ad 来删除任何自定义别名。但是不能用它来删除预定义别名($u0 到$u9)。
附加信息
关于如何使用别名的更多信息,查看使用别名。
ah (Assertion Handling)
ah 命令控制指定地址的断言处理状态。
语法
ahb [Address]
ahi [Address]
ahd [Address]
ahc
ah
参数
ahb
如果指定地址的断言失败,中断调试器。
ahi
忽略指定地址的断言失败。
ahd
删除指定地址的任何断言处理信息。这种删除使得调试器对该地址的处理返回到默认状态。
Address
指定要设置断言处理状态的指令地址。如果省略该参数,调试器使用当前程序计数器。
ahc
删除当前进程的所有断言处理信息。
ah
显示当前的断言处理设置。
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
ah*命令控制指定地址的断言处理状态。sx* asrt命令控制全局的断言处理状态。如果使用ah*设置了某个地址,并且之后该地址发生了一次断言,调试器按照ah*的设置进行响应而忽略掉sx* asrt 的设置。
当调试器遇到断言时,它会首先检查是否设置了该地址的断言处理。如果没有设置,调试器使用全局设置。
ah*命令仅作用于当前进程。当前进程结束时,所有状态设置丢失。
断言处理状态仅作用于STATUS_ASSERTION_EXCEPTION异常。该处理并不作用于内核模式的断言例程。
附加信息
关于中断状态和处理状态、事件代码德说明、所有事件的默认状态列表和其他控制该状态的方法的更多信息,查看控制异常和事件。
al (List Aliases)
al命令显示所有自定义别名的列表。
语法
al
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
al命令列出所有自定义别名。但是该命令不会列出预定义别名($u0 到$u9)。
附加信息
关于如何使用别名的更多信息,查看使用别名。
as, aS (Set Alias)
as 和aS 命令定义一个新的别名或重新定义已存在的别名。
语法
as Name EquivalentLine
aS Name EquivalentPhrase
aS Name "EquivalentPhrase"
as /e Name EnvironmentVariable
as /ma Name Address
as /mu Name Address
as /msa Name Address
as /msu Name Address
as /x Name Expression
aS /f Name File
as /c Name CommandString
参数
Name
指定别名的名字。该名字可以是不包含空格、ENTER键并且不以"al"、 "as"、 "aS"或"ad"开头的任何文本字符串。Name 是区分大小写的。
EquivalentLine
指定别名的等价值。EquivalentLine是区分大小写的。在Name 和EquivalentLine 之间必须至少有一个空格。这两个参数之间具体有多少个空格无所谓。别名的等价值不会以空格开头。在这些空格,EquivalentLine 包含该行的结束符。分号、引号和空格都被当作普通字符,并且末尾的空格也会被包含进去。
EquivalentPhrase
指定别名的等价值。EquivalentPhrase 是大小写敏感的。在Name 和EquivalentPhrase之间必须至少有一个空格。这两个参数之间具体有多少个空格无所谓。别名的等价值不会以空格开头。
可以用引号(")将EquivalentPhrase 括起来。不管是否使用了引号,EquivalentPhrase 都可以包含空格、逗号和单引号(')。如果将EquivalentPhrase 括在引号里面,则可以包含分号,但是不能包含其他引号。如果没有将EquivalentPhrase 包含在引号中,则可以在除了第一个字符之外的其他位置包含银号,但是不能包含分号。末尾的空格不管是否使用了引号都会包含进去。
/e
设置别名的值为EnvironmentVariable 指定的环境变量。
EnvironmentVariable
指定用来获得别名的值的环境变量。使用调试器的环境变量而不是目标的。如果从命令提示符窗口启动调试器,环境变量和该窗口使用的一样。
/ma
将别名的等价值设置为从地址Address 开始的null结尾的ASCII字符串。
/mu
将别名的等价值设置为从地址Address 开始的null结尾的Unicode字符串。
/msa
将别名的等价值设置为从地址Address 开始的null结尾的ANSI_STRING结构。
/msu
将别名的等价值设置为从地址Address 开始的null结尾的UNICODE_STRING结构。
Address
指定用来决定别名的等价值的虚拟内存位置。
/x
设置别名的等价值为Expression 的64位值。
Expression
指定用来求值的表达式。求出的值作为别名的等价值。该语法的更多信息,查看数值表达式语法。
/f
设置别名的等价值为File 文件的内容。/f 开关只能和aS一起使用,不能和as一起。
File
指定内容作为别名等价值的文件。File可以包含空格,但是不能将 File用引号括起来。如果指定了非法的文件,会得到一个"Out of memory"的错误信息。
/c
设置别名的等价值是CommandString 指定的命令的输出。如果命令输出中包含回车符,别名的等价值中也会包含回车,并且每条命令输出的末尾也会包含回车符(即使只指定了一条命令)。
CommandString
指定输出作为别名等价值的命令。该字符串可以包含任意多个以分号分隔的命令。
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
如果不使用任何命令参数,as 命令将行的结束符作为别名等价值。
可以用一个分号来结束aS命令。这在需要将所有命令放在单行中的脚本文件中有用。
如果使用了/e、/ma、/mu、/msa、/msu或/x开关,as 和aS 命令都会在遇到分号时结束。
如果Name已经作为别名的名字定义了,则该别名被重定义。
可以使用as 或aS 命令来创建或修改任何自定义别名。但是不能使用该命令来控制预定义别名 ($u0 到$u9)。
可以使用/ma、/mu、/msa、/msu、/f和/c开关来创建包含回车符的别名。但是,不能使用包含回车符的别名来执行一个多命令序列,而必须使用分号。
附加信息
关于如何使用别名的更多信息,查看使用别名。
cc682/NetRoc
http://netroc682.spaces.live.com/
命令
本节中的参考讨论可以在CDB、KD和WinDbg中使用的各种调试器命令。
ENTER (Repeat Last Command)
ENTER 键重复前一次输入的命令。
语法
ENTER
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
在CDB和KD中,在命令提示符下按下ENTER 本身,会执行前一次输入过的命令。
在WinDbg中,ENTER 键可以设置为无效或者重复上一条命令。可以在Options 对话框设置该选项。(点击View菜单上的Options,或者点击工具栏上的Options按钮(
)来打开Options对话框。)
如果将ENTER设置为重复上一条命令,但是又想在调试器命令窗口中产生一些空白,可以使用 * (Comment Line Specifier)关键字并按下ENTER数次。
$<, $><, $$<, $$><, $$>a< (Run Script File)
$<、 $><、$$<、$$><和$$>a< 命令读取指定的脚本文件的内容作为输入的调试器命令。
语法
$<Filename
$><Filename
$$< Filename
$$>< Filename
$$>a< Filename arg1 arg2 arg3 ... argn
参数
Filename
指定包含合法的调试器命令文本的文件。文件名必须符合Microsoft Windows文件命名规范。文件名中可以有空格。
argn
指定传递给脚本文件的参数。这些参数可以是引号括起来的字符串或者空格分隔的字符串。所有参数都是可选的。
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
如果该命令使用$$<或$$><关键字,则关键字 和Filename 之间的空格是可选的。不管Filename是否包含空格,都可以使用引号来把它括起来。可以在该命令后添加一个分号或其他命令。
如果该命令使用$<或$><关键字,则不能在它和Filename之间加入任何空格。 不能使用引号来包含Filename 。该命令之后不能添加分号或其他命令。
$< 和$$<关键字逐个执行脚本文件中的命令。$><和$$><关键字打开脚本文件,将所有回车替换为分号,然后将转换后的文本当作单个命令块来执行。这些关键字在运行包含调试器命令程序的脚本时非常有用。关于这种程序的更多信息,查看使用调试器命令程序。$$>a<关键字允许传递参数给脚本。
下表是如何使用这些命令的摘要信息。
|
关键字
|
文件名前是否允许空格?
|
是否将脚本精简为单个命令块?
|
|
$<
|
否
|
否
|
|
$><
|
否
|
是
|
|
$$<
|
是
|
否
|
|
$$><
|
是
|
是
|
|
$$>a<
|
是
|
是
|
调试器执行脚本文件时,命令和它们的输出都会在调试器命令窗口显示出来。当到达脚本末尾时,控制权返回到调试器。
脚本文件可以嵌套。如果调试器在脚本文件中遇到了这样的关键字,执行会移交给新的脚本文件,并且在它执行完成之后返回到先前的位置。脚本也可以被递归调用。
在WinDbg中,可以将附加的命令文本粘贴到调试器命令窗口中。
示例
下面的例子示范了如何将参数传递给脚本文件Myfile.txt。假设该文件包含如下文本:
.echo The first argument is ${$arg1}.
.echo The second argument is ${$arg2}.
可以通过使用类似这样的命令将参数传递给它:
0:000> $$>a<myfile.txt myFirstArg mySecondArg
命令的结果如下:
The first argument is myFirstArg.
The second argument is mySecondArg.
? (Command Help)
问号(?)字符用来显示所有命令和操作符的列表。
注意 单独的一个问号用来显示命令帮助。? expression语法用来计算给定表达式的值。
语法
?
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
查看标准命令的更多信息,可以使用?。查看元命令的更多信息,使用.help。查看扩展命令的信息,使用 !help。
? (Evaluate Expression)
(?) 命令可用于计算和显示一个表达式的值。
注意 单个问号(?)显示命令帮助。? expression 命令计算给定表达式的值。
语法
? Expression
参数
Expression
指定要计算的表达式。
Environment
|
模式
|
用户模式、内核模式
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
?命令的输入和输出依赖于使用MASM表达式语法还是C++表达式语法。关于这积累表达式语法的更多信息,查看表达式求值和数值表达式语法。
如果使用MASM语法,输入和输出都依赖于当前的基数。要改变基数,使用n (Set Number Base)命令。
?命令在当前线程和进程上下文中计算表达式中符号的值。
See Also
?? (Evaluate C++ Expression), .formats (Show Number Formats)
?? (Evaluate C++ Expression)
双问号(??)命令根据C++表达式规则来计算和显示表达式的值。
语法
?? Expression
参数
Expression
指定要求值的C++表达式。语法的更多信息,查看C++数值和操作符。
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
??命令根据当前线程和进程上下文来对表达式中的符号进行求值。
如果要使用MASM表达式规则来为Expression 表达式的一部分进行求值,可以将这部分用圆括号括起来并在前面添加两个at符号( @@ )。关于MASM和C++表达式的更多信息,查看表达式求值和数值表达式语法
参见
? (Evaluate Expression)、 .formats (Show Number Formats)
# (Search for Disassembly Pattern)
数字号(#)命令在反汇编代码中搜索符合指定模板的数据。
语法
# [Pattern] [Address [ L Size ]]
参数
Pattern
指定用于在反汇编代码中搜索的模板。Pattern可以包含各种通配符和修饰符。关于该语法的更多信息,查看字符串通配符语法。如果在Pattern中包含空格,需要将模板用引号括起来。模板是不区分大小写的。如果之前使用过#命令,并且省略掉Pattern ,该命令会使用上一次的模板。
Address
指定搜索开始的地址。该语法的更多信息,查看地址和地址范围语法。
Size
指定要搜索的指令数量。如果省略掉Size ,会一直搜索直到遇到匹配项。
环境
|
模式
|
用户模式、内核模式
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
如果之前使用过#命令并且省略掉Address ,会从上次搜索结束的地方开始搜索。
该命令通过搜索反汇编文本来查找指定的模板。可以使用该命令来查找寄存器名、常数或其他任何在反汇编输出中出现的字符串。可以反复使用不带Address 参数的命令来顺序查找匹配模板的项。
可以使用u (Unassemble) 命令或在WinDbg反汇编窗口中查看反汇编代码。反汇编的输出包含四个部分:地址偏移、二进制代码、汇编语言助记符合汇编语言详细信息。下面是这种显示的例子。
0040116b 45 inc ebp
0040116c fc cld
0040116d 8945b0 mov eax,[ebp-0x1c]
#命令可以在反汇编输出的任意单独部分中搜索文本。例如,使用# eax 0040116b 来在0040116d 地址查找mov eax,[ebp-0x1c] 指令。下面的命令也能搜索到该指令。
# [ebp?0x 0040116b
# mov 0040116b
# 8945* 0040116b
# 116d 0040116b
但是,不能将mov eax*作为单独的单元来进行搜索,因为mov 和eax 出现在输出的不同部位。
另一个示例,可以使用下面的命令在入口点main 中查找对strlen 的第一个引用。
# strlen main
类似的,可以使用下面两个命令来查找0x779F9FBA 之后的第一个jnz 指令,并再查找之后的下一条jnz 指令。
# jnz 779f9fba#
省略Pattern 或Address 时,他们的值由上一次的#命令决定。如果第一次使用#命令时省略掉它们中的一个,则不会进行搜索。但是即使在这种情况下Pattern 和Address 的值也会被初始化。
如果包含了Pattern 或Address,它的值被设置成输入的值。如果省略Address,它会被设置为程序计数器的当前值。如果省略掉Pattern ,会被设置为任意的空模板。
附加信息
关于汇编调试和相关命令的更多信息,查看汇编模式下的调试。
|| (System Status)
双竖线(||)命令打印指定系统或当前正在调试的所有系统的状态信息。
不要将该命令和| (Process Status)命令混淆。
语法
|| System
参数
System
指定要显示的系统。如果省略掉该参数,所有被调试的系统都会显示出来。该语法的更多信息,查看系统语法。
环境
|
模式
|
多目标调试
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
||仅在调试多个目标时有用。很多,但不是全部的多目标调试会话会使用到多系统。关于这些会话的更多信息,查看调试多个目标。
每个系统的信息包含服务器名字和详细的协议信息。调试器运行的系统被标识为<Local>。
下面是如何使用该命令的示例。下面的命令显示所有系统。
3:2:005> ||
这个命令也显示所有系统。
3:2:005> ||*
下面的命令显示当前的活动系统。
3:2:005> ||.
下面的例子显示最近一次异常或中断发生的系统。
3:2:005> ||#
下面显示编号为2的系统。
3:2:005> ||2
||s (Set Current System)
||s命令设置或显示当前系统号。
不要将该命令和s (Search Memory)、 ~s (Change Current Processor)、 ~s (Set Current Thread)或 |s (Set Current Process) 命令混淆。
语法
||System s
|| s
参数
System
指定要激活的系统。该语法的更多信息,查看系统语法。
环境
|
模式
|
多目标调试
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
||s命令仅在多目标调试时有用。很多,但不是全部的多目标调试会话会使用到多系统。关于这些会话的更多信息,查看调试多个目标。
如果使用||s语法,调试器显示当前系统的信息。
该命令也会反汇编当前系统、当前进程、当前线程的当前指令。
| (Process Status)
管道(|)命令显示指定进程或当前正在调试的所有进程的信息。
不要将该命令和|| (System Status)命令混淆。
语法
| Process
参数
Process
指定要显示的进程。如果省略掉该参输,则显示所有进程。该语法的更多信息,查看进程语法。
环境
|
模式
|
仅用户模式
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
仅能在用户模式下指定进程。
可以在很多命令前添加一个进程符号。关于在命令后接一个管道(|)的意义的信息,查看每个命令本身的说明。
除非在启动调试会话时启用了对子进程的调试,否则仅有一个进程对调试器是可用的。
下例说明了如何使用该命令。例中的命令显示所有进程。
2:005> |
下例也显示所有进程。
2:005> |*
下面的命令显示当前的激活进程。
2:005> |.
下面的命令显示最初产生异常的进程(或者调试器最初附加到的进程)。
2:005> |#
下面的命令显示号码为2的进程。
2:005> |2
前面的命令显示如下输出。
0:002> |
# 0 id: 224 name: myprog.exe
1 id: 228 name: onechild.exe
. 2 id: 22c name: anotherchild.exe
在输出的第一行,0是一个十进制进程号,224是16进制进程ID,Myprog.exe 是进程的程序名。进程2前面的点号(.) 表示该进程为当前进程。进程0前面的数字号(#)表示该进程是最初产生异常或调试器附加到的进程。
附加信息
关于显示或控制进程和线程的其他方法和更多信息,查看控制进程和线程。
|s (Set Current Process)
|s命令设置或显示当前进程号。
不要将该命令和s (Search Memory)、~s (Change Current Processor)、 ~s (Set Current Thread)或 ||s (Set Current System)命令混淆。
语法
|Process s
| s
参数
Process
指定要显示或设置的进程。关于该语法的更多信息,查看进程语法。
环境
|
模式
|
仅用户模式
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
只能在用户模式下指定进程。
如果使用|s语法,调试器现实当前进程的信息。
该命令也会反汇编当前系统、当前进程、当前线程的当前指令。
附加信息
关于显示或控制进程和线程的其他方法和更多信息,查看控制进程和线程。
~ (Thread Status)
波形符(~) 命令显示指定线程或当前进程中的所有线程的信息。
语法
~ Thread
参数
Thread
指定要显示的线程。如果省略该参数,则显示所有线程。该语法的更多信息,查看线程语法。
环境
|
模式
|
仅用户模式
|
|
目标
|
活动目标、崩溃转储
|
|
平台
|
所有
|
注释
只有在用户模式下才能显示线程。在内核模式下,波形符 (~)用于引用处理器。
可以在很多命令中添加线程符号。关于在这些命令中使用的波形符的意义的更多信息,查看这些命令本身的说明。
下面这些示例说明了该命令的使用方法。这条命令显示所有线程。
0:001> ~
该命令也显示所有线程。
0:001> ~*
下面的命令显示当前活动线程。
0:001> ~.
下面的命令显示原始的产生异常的线程(或调试器附加到进程时活动的线程)。
0:001> ~#
下面显示号码为2的线程。
0:001> ~2
上面的命令会产生如下输出。
0:001> ~
0 id: 4dc.470 Suspend: 0 Teb 7ffde000 Unfrozen
. 1 id: 4dc.534 Suspend: 0 Teb 7ffdd000 Unfrozen
# 2 id: 4dc.5a8 Suspend: 0 Teb 7ffdc000 Unfrozen
输出的第一行上,0是10进制线程号,4DC是16进制进程ID,470是16进制线程ID,0x7FFDE000是TEB 地址,Unfrozen 是线程状态。线程1前面的点号(.)表示它是当前线程。线程2前面的数字号(#)表示它是产生异常或调试器附加到进程时活动的线程。
附加信息
关于显示或控制进程和线程的其他方法和更多信息,查看控制进程和线程。
cc682/NetRoc/小喂
http://netroc682.spaces.live.com/
命令关键字部分也直接使用了小喂翻译的文档。新版本WinDbg文档中更新过的部分作了一些修改,另外有部分语句也有少量更改。非常感谢小喂的共享。他的主页在
http://www.ztssoft.com/
命令关键字
本节论述在调试命令和元命令中使用的各种关键字。
这些记号包括:
; (命令分隔符)
{ } (块分隔符)
${ } (别名解释器)
$$ (注释说明符)
* (注释行说明符)
.block
.break
.catch
.continue
.do
.else
.elsif
.for
.foreach
.if
.leave
.printf
.while
; (命令分隔符)
分号( ; )字符常被用来分隔单行上多个命令。
语法
Command1 ; Command2 [; Command3 ...]
参数
Command1, Command2, ...
被执行的命令。
注释
命令从左往右顺序执行。除非另有说明,一行上的所有命令都和当前线程有关。如果某个命令导致线程恢复执行,该行剩下的命令都将推迟执行,直到线程停在一个调试事件上。
少部分命令后不能跟分号,因为它们会把行中剩下的全部内容都当成参数。包括as (Set Alias)、 $< (Run Script File)、$>< (Run Script File),以及任何以* (Comment Line Specifier)关键字打头的命令。
这有一个例子。执行当前程序到源码行 123 处,打印 counter 的值,然后继续执行:
0:000> g `:123`; ? poi(counter); g
{ } (块分隔符)
一对大括号( { } )常被用来括住调试器命令程序中的一段语句。
语法
Statements { Statements } Statements
注释
进入每个语句块时,会计算该语句块中的所有别名值。如果你在语句块中某个位置修改了别名的值,接下来的命令不会使用别名的新值,除非它们处在下级语句块中。
每个块都必须跟在流程控制记号后面。如果你只是为了计算别名想建立一个块,应该带上.block关键字前缀。
附加信息
对于调试器命令程序和流程控制记号,请看使用调试器命令程序。
${ } (别名解释器)
一个美元符号带一对大括号( ${ } )计算和指定的用户命名别名相关的各类值。
语法
Text ${Alias} Text
Text ${/d:Alias} Text
Text ${/f:Alias} Text
Text ${/n:Alias} Text
Text ${/v:Alias} Text
参数
Alias
指定要展开和求值的别名名称。Alias 必须是用户命名的别名或者 .foreach关键字中使用的变量值。
/d
根据别名当前是否已经定义计算出1或者0。如果别名已经定义,${/d:Alias} (译注:原文这里是 ${/v:Alias})被替换为 1;如果别名没有定义,${/d:Alias} (译注:原文这里是 ${/v:Alias})被替换为 0。
/f
如果别名当前已定义则等同于计算别名。如果别名已经定义,${/f:Alias} 被替换为等价的别名;如果别名没有定义,${/f:Alias} 被替换为空字符串。
/n
如果别名当前已定义则计算别名的名称。如果别名已经定义,${/n:Alias} 被替换为别名名称;如果别名没有定义,${/n:Alias} 保留它字面上的值不替换。
/v
禁止对任何别名求值。不论别名是否已经定义,${/v:Alias} 总是保持它字面上的值。
注释
如果没有使用开关选项且别名当前已定义,${Alias} 被替换为等价的别名。如果没有使用开关选项且别名没有定义,${Alias}总是保持它字面上的值。
使用 ${ } 记号的一个优点是,如果和其它字符紧挨着也会对别名求值。没有这个记号,调试器只对那些和其它关键字隔开的别名求值。
和说明一样,有一些情况下 ${ } 记号不会被替换为任何值而保持它字面上的值。这会发生在没有使用开关选项且别名没有定义时,以及使用了 /n 开关选项且别名没有定义时,以及使用了 /v 开关选项时。在这些情况下,该记号保持它字面上的值,包括美元符号和大括号。所以,如果作为命令参数,将导致语法错误,除非这个参数接受任意文本串。
但是这有一个例外。如果你使用 ${/v:Alias}作为 as (Set Alias)或者aS (Set Alias)命令的第一个参数,该关键字被当成单独的 Alias 字符串,而不是 ${/v:Alias}字符串。这只是对 as、aS 和 ad 命令起作用,也仅当使用了 /v 开关选项时 - 使用 ${/n:Alias}或者${Alias}当它们保持字面上的值时不起作用。
别名必须是用户命名的别名或者 .foreach 记号中使用的变量值 - 不是一个固定名称的别名。如果在字符串 Alias 中有一个固定名称的别名,会在计算 ${ } 记号前被替换掉。
附加信息
关于如果使用别名的说明,请看使用别名。
$$ (注释说明符)
如果命令开头出现两个美元符号( $$ ),则该行剩下的部分被当成注释,除非碰到分号。
语法
$$ [any text]
注释
$$ 和其他任何调试器命令一样被解析。因此,如果要在其它命令后创建一条注释,必须在$$之前添加一个分号。
$$ 关键字使得后面的文本被忽略掉,直到行末或者碰到分号。分号结束注释;分号后的文本被解析为标准的命令。这和* (Comment Line Specifier)不同,它会把行中剩下的部分都当成注释,即使里面有分号。
例如,下例将显示 eax 和 ebx,但不显示 ecx:
0:000> r eax; $$ some text; r ebx; * more text; r ecx
以 * 或者 $$ 记号为前缀的文本不能通过任何方式处理。如果你正进行远程调试,调试服务器上输入的注释在调试客户端上看不到,反过来则不一样。如果你希望通过一个对所有方都可见的方法使得注释文本显示在调试命令窗口,你应该使用.echo (Echo Comment)。
* (注释行说明符)
如果命令开头带星号( * )字符,则行中剩下的部分被当成注释,即使中间有分号。
语法
* [any text]
注释
*关键字像其它所有命令一样被解析。因此如果要在其它命令之后创建注释,必须在*关键字前加上一个分号。
*关键字将导致行中剩余部分被忽略掉,即使出现分号。这和$$ (Comment Specifier)不同,它所创建的注释会被分号截断。
例如,下面的命令将显示 eax 和 ebx,但不会显示 ecx:
0:000> r eax; $$ some text; r ebx; * more text; r ecx
以 * 或者 $$ 记号为前缀的文本不能通过任何方式处理。如果你正进行远程调试,调试服务器上输入的注释在调试客户端上看不到,反过来则不一样。如果你希望通过一个对所有方都可见的方法使得注释文本显示在调试命令窗口,你应该使用.echo (Echo Comment)。
.block
.block 关键字不执行任何动作;只是用来引入一个语句块。
语法
Commands ; .block { Commands } ; Commands
注释
由大括号括住每个语句块。当进入每个语句块时,所有块中的别名都被重新计算。如果你在块中某个命令处修改了别名的值,往下的命令不会使用新的别名值,除非它们处在一个下属子语句块中。
每个语句块应该以一个流程控制关键字打头。如果你希望创建一个语句块只是为了计算别名,你应该带上 .block 关键字作为该语句块的前缀,因为这个关键字除了引入一个语句块之外不会有什么影响。
附加信息
需要其它流程控制记号的信息以及它们在调试器命令程序中的用法,请看使用调试器命令程序。
.break
.break 关键字的行为和 C 语言中 break 关键字一样。
语法
.for (...) { ... ; .if (Condition) .break ; ... }
.while (...) { ... ; .if (Condition) .break ; ... }
.do { ... ; .if (Condition) .break ; ... } (...)
注释
.break 记号可以被用在任何 .for、.while或者.do循环中。
因为没有和 C 语言中 goto 语句等效的流程控制关键字,你将会在 .if条件中经常用到 .break 关键字,就像上面的语法例子显示的形式。但是,.break 关键字也不是必须的。
附加信息
需要其它流程控制记号的信息以及它们在调试器命令程序中的用法,请看使用调试器命令程序。
.catch
.catch 关键字通常用来避免错误发生时程序被中止。
它和 C++ 中的 catch 关键字的行为不一样。
语法
Commands ; .catch { Commands } ; Commands
注释
.catch 关键字后面跟由大括号括住的一条或多条命令。
如果 .catch 块中某条命令发生错误,则显示错误消息,忽略该块中剩下的命令,从大括号后面的第一条命令恢复执行。
如果没有使用 .catch,一个错误将会中止整个调试器命令程序的执行。
你可以使用.leave从一个 .catch 块中跳出来。
附加信息
需要其它流程控制记号的信息以及它们在调试器命令程序中的用法,请看使用调试器命令程序。
.continue
.continue 关键字的行为和 C 语言中的 continue 关键字一样。
语法
.for (...) { ... ; .if (Condition) .continue ; ... }
.while (...) { ... ; .if (Condition) .continue ; ... }
.do { ... ; .if (Condition) .continue ; ... } (...)
注释
.continue 记号可以被用在任何.for、.while或者.do循环中。
因为没有和 C 语言中 goto 语句等效的流程控制符,你将会在 .if条件中经常用到 .continue 记号,就像上面的语法例子显示的形式。但是,.continue 记号也不是必须的。
附加信息
需要其它流程控制记号的信息以及它们在调试器命令程序中的用法,请看使用调试器命令程序。
.do
除了在条件前没有使用 "while" 关键字之外,.do 记号的行为和 C 语言中的 do 关键字一样。
语法
.do { Commands } (Condition)
语法项
Commands
指定一条或多条命令,当条件为真时会被重复执行 - 但至少会执行一次。即使只包含一条命令,该命令块都需要用花括号括住。多个命令间用分号隔开,结束花括号前的最后一条命令不需要带分号。
Condition
指定条件。如果计算后结果为零,则被当成假,否则为真。把 Condition 用圆括号括住是可选的。Condition 必须是一个表达式,而不是一个调试器命令。将使用缺省的表达式求解器(MASM or C++)对其求值。详细请看数值表达式语法。
注释
.break和 .continue关键字可被用来退出或者重头开始 Commands 语句块。
附加信息
需要其它流程控制记号的信息以及它们在调试器命令程序中的用法,请看使用调试器命令程序。
.else
.else 关键字的行为和 C 语言中的 else 关键字一样。
语法
.if (Condition) { Commands } .else { Commands }
.if (Condition) { Commands } .elsif (Condition) { Commands } .else { Commands }
语法项
Commands
指定一条或多条命令,将被有条件的执行。即使只包含一条命令,该命令块都需要用花括号括住。多个命令间用分号隔开,结束花括号前的最后一条命令不需要带分号。
附加信息
需要其它流程控制记号的信息以及它们在调试器命令程序中的用法,请看使用调试器命令程序。
.elsif
.elsif 关键字和 C 语言中的 else if 组合关键字的行为一样。
语法
.if (Condition) { Commands } .elsif (Condition) { Commands }
.if (Condition) { Commands } .elsif (Condition) { Commands } .else { Commands }
语法项
Condition
指定条件。如果计算后结果为零,则被当成假,否则为真。把 Condition 用圆括号括住是可选的。Condition 必须是一个表达式,而不是一个调试器命令。将使用缺省的表达式求解器(MASM or C++)对其求值。详细数值表达式语法。
Commands
指定一条或多条命令,将被有条件地执行。即使只包含一条命令,该命令块都需要用花括号括住。多个命令间用分号隔开,结束花括号前的最后一条命令不需要带分号。
附加信息
需要其它流程控制符的信息以及它们在调试器命令程序中的用法,请看使用调试器命令程序。
.for
.for 关键字的行为和 C 语言中的 for 关键字一样,只有一点不同,多个增量命令之间必须用分号隔开,而不是用逗号。
语法
.for (InitialCommand ; Condition ; IncrementCommands) { Commands }
语法项
InitialCommand
指定循环开始前执行的命令。只允许单个的初始化命令 。
Condition
指定条件。如果计算后结果为零,则被当成假,否则为真。把 Condition 用圆括号括住是可选的。Condition 必须是一个表达式,而不是一个调试器命令。将使用缺省的表达式求解器(MASM or C++)对其求值。详细请看数值表达式语法。
IncrementCommands
指定一条或多条命令,在单次循环结束时执行。如果想要执行多条增量命令,需要用分号把它们隔开,不需要用花括号括住。
Commands
指定一条或多条命令,当条件为真时会被重复执行。即使只包含一条命令,该命令块都需要用花括号括住。多个命令间用分号隔开,结束花括号前的最后一条命令不需要带分号。
注释
如果在增量命令中就可以做完所有工作,你完全可以忽略 Commands 部分,简单的使用一对花括号就行。
这有一个带多条增量命令的 .for 语句的例子:
0:000> .for (r eax=0; @eax < 7; reax=eax+1; rebx=ebx+1) { .... }
.break和.continue关键字可用来退出或者重头开始 Commands 语句块。
附加信息
需要其它流程控制符的信息以及它们在调试器命令程序中的用法,请看使用调试器命令程序。
.foreach
.foreach 关键字分析一个或多个命令的输出并将该输出中每一个值作为另一个或多个命令的输入。
语法
.foreach [Options] ( Variable { InCommands } ) { OutCommands }
.foreach [Options] /s ( Variable "InString" ) { OutCommands }
.foreach [Options] /f ( Variable "InFile" ) { OutCommands }
语法项
Options
可以是下面选项的任意组合:
/pS InitialSkipNumber
使得开头的一些符号被调过。InitialSkipNumber 指定不传递给OutCommands 的输出关键字的数量。
/ps SkipNumber
每次执行命令时都会跳过一些符号。每次将符号传递给OutCommands 之后,SkipNumber 个数的符号都会被忽略。
Variable
指定一个变量名。该变量用来保存InCommands 字符串中的每次输出,因此传递给OutCommands 的参数中可以通过名字引用Variable 。可以使用任何字母数字的字符串,但是并不建议使用可以当作有效的16进制数字或调试器命令的字符串。如果Variable 使用的名字碰巧和已存在的全局变量、局部变量或别名相同,它们的值不会受.foreach 命令的影响。
InCommands
指定要解析输出的一个或多个命令;结果会传递给OutCommands 。InCommands 的输出不会显示出来。
InString
和/s 一起使用。指定一个要解析的字符串;结果会传递给OutCommands 。
InFile
和/f 一起使用。指定要解析的文本文件;结果会传递给OutCommands 。文件名InFile 必须用引号括起来。
OutCommands
指定每条标记(token)要执行的一个或多个命令。任何时候Variable 都会被替换为当前标记。
注意 当Variable出现在OutCommands 中时,必须前后带有空格。如果有其它任何文本相邻 — 即使是一个圆括号 — 就不会被当前标记替换,除非使用${ } (Alias Interpreter)关键字。
注释
当InCommands 的输出、InString 字符串或InFile 被解析时,任何数量的空格、tab符或回车都将会被当作单个分隔符。文本被分隔成的小片段被用来替换OutCommands 中的Variable 。
这里有一个使用.foreach 语句的示例,对文件myfile.txt 中找到的每条标记都会使用dds 命令:
0:000> .foreach /f ( place "g:\myfile.txt") { dds place }
/pS 和/ps标志用来仅将特定的标记传递给指定的OutCommands。例如,下面的语句将跳过myfile.txt 文件中的前两个标记并将第三个传递给dds。传递了每个标记之后,都会跳过四个标记。所以结果就是dds使用的标记是第3、8、13、18和23,等等:
0:000> .foreach /pS 2 /ps 4 /f ( place "g:\myfile.txt") { dds place }
使用.foreach 关键字的更多示例,查看调试器命令程序示例。
附加信息
其它流程控制符的信息以及它们在调试器命令程序中的用法,查看使用调试器命令程序。
.if
.if关键字的行为和C中的if类似。
语法
.if (Condition) { Commands }
.if (Condition) { Commands } .else { Commands }
.if (Condition) { Commands } .elsif (Condition) { Commands }
.if (Condition) { Commands } .elsif (Condition) { Commands } .else { Commands }
语法项
Condition
指定一个条件。如果求值为0,则作为假;否则为真。把Condition用圆括号括起来是可选的。Condition必须是一个表达式而不是调试器命令。它将会使用默认的表达式求值器(MASM或C++)来计算。详细信息,查看数值表达式语法。
Commands
指定用于条件执行的一条或多条命令。该命令块必须用大括号括起来,即使只有一条命令。多条命令需要用分号分隔,但是反的大括号前面的最后一条指令后面必须要跟分号。
附加信息
其它流程控制符的信息以及它们在调试器命令程序中的用法,查看使用调试器命令程序。
.leave
.leave关键字用来退出一个.catch块。
语法
.catch { ... ; .if (Condition) .leave ; ... }
注释
当.leave关键字在.catch块中时,程序从该块中退出,并继续执行反大括号后的第一条命令。
由于没有C中的goto 语句这样的控制流符号,通常像上面的语法示例中一样在.if中使用.leave 关键字。但是这并不是必须的。
附加信息
其它流程控制符的信息以及它们在调试器命令程序中的用法,查看使用调试器命令程序。
.printf
.printf 关键字和C中的printf 语句类似。
语法
.printf "FormatString" [Arguments ...]
语法项
FormatString
指定printf中的格式化字符串。一般来说,转义字符和C中完全一样。对于浮点转义字符,如果没有使用l 修饰符,64位参数会被当作32位浮点数。
支持%p 转义字符,但是它表示目标虚拟地址空间中的一个指针。它不能包含任何修饰符并且使用调试器的内部地址格式。支持下面这些转义字符:
|
字符
|
参数类型
|
参数
|
打印出的文本
|
|
%p
|
ULONG64
|
目标的虚拟地址空间中的指针
|
指针的值
|
|
%N
|
DWORD_PTR (32位或64位,由主控机的架构决定。
|
目标的虚拟地址空间中的指针
|
指针的值。(和标准C的%p字符一样。)
|
|
%I
|
ULONG64
|
任何64位值
|
指定的值。如果大于0xFFFFFFFF作为64位地址显示,否则作为32位地址显示。
|
|
%ma
|
ULONG64
|
目标虚拟地址空间中以NULL结尾的ASCII字符串地址。
|
指定的字符串。
|
|
%mu
|
ULONG64
|
目标虚拟地址空间中以NULL结尾的Unicode字符串地址。
|
指定的字符串。
|
|
%msa
|
ULONG64
|
目标虚拟地址空间中的ANSI_STRING结构地址。
|
指定的字符串。
|
|
%msu
|
ULONG64
|
目标虚拟地址空间中的UNICODE_STRING结构地址。
|
指定的字符串。
|
|
%y
|
ULONG64
|
目标虚拟地址空间中的调试器符号的地址。
|
包含指定符号的名字的字符串(和偏移量(displacement),如果有的话)。
|
|
%ly
|
ULONG64
|
目标虚拟地址空间中的调试器符号的地址。
|
包含指定符号的名字的字符串(和偏移量(displacement),如果有的话),和任何可用的源码行信息。
|
Arguments
指定printf的格式化字符串的参数。参数的个数应该和FormatString 中的转义字符数量匹配。每个参数都是一个使用默认表达式求值器(MASM 或C++)进行计算的表达式。详细信息,查看数值表达式语法。
附加信息
其它流程控制符的信息以及它们在调试器命令程序中的用法,查看使用调试器命令程序。
.while
.while关键字的行为和C中的while关键字类似。
语法
.while (Condition) { Commands }
语法项
Condition
指定一个条件。如果它的值为0则作为真;否则为假。把Condition用圆括号括起来是可选的。Condition 必须是一个表达式而不是调试器命令。它将会使用默认的表达式求值器(MASM 或C++)进行求值。详细信息,查看数值表达式语法。
Commands
指定当条件为真时会重复执行的一条或多条命令。该命令块必须使用大括号括起来,即使只有一条命令。多个命令之间用分号分隔,但是反的大括号之前的最后一条命令之后不用跟分号。
注释
.break 和.continue 关键字可以退出或从头执行Commands 语句块。
附加信息
其它流程控制符的信息以及它们在调试器命令程序中的用法,查看使用调试器命令程序。
摘要: cc682/NetRoc/小喂
http://netroc682.spaces.live.com/
各种语法形式直接使用了小喂翻译的文档。新版本WinDbg文档中更新过的部分作了一些修改。非常感谢小喂的共享。他的主页在
http://www.ztssoft.com/
字符串通配符语法
某些调试器命令带有接受多种通配符的字符串参数。这些参数在各自的参考页中解释。 ...
阅读全文