Debugging Tools for Windows

读写内存

三个调试器都可以直接读写内存。这些内存可以用地址或变量名来引用。

使用虚拟地址访问内存

可以使用各种命令访问内存或内存区域。

下面的这些命令可以以各种格式读写内存。这些格式包括16进制字节、字(字、双字和4字)、整数(short, long, quad integers 和unsigned integers)、浮点数(10字节、16字节、32字节和64字节实数)、以及ASCII字符。

使用下面一些命令来处理更特殊的数据类型:

使用如下一些命令来操作内存块:

大多数情况下,这些命令都按照当前的基数来解释参数。因此,当前基数不是16时,要在16进制数前加上0x 。但是,这些命令的显示输出不管当前基数是什么,一般是16进制格式。(关于输出的更多信息,查看各个命令的主题。) 内存窗口(Memory window)使用10进制显示整数和实数,用16进制显示其他格式的数据。

使用n (Set Number Base)命令改变当前基数。用 ? (Evaluate Expression).formats (Show Number Formats) 命令来快速的将数字从一种基数转变为另一种。

进行用户模式调试时,虚拟地址的意义由当前进程决定。进行内核模式调试时,虚拟地址的意义可以由调试器控制。更多信息,查看进程上下文

使用物理地址访问内存

!db, !dc, !dd, !dp, !du, 和!dw扩展命令读取物理内存的内容。

使用!eb!ed 扩展命令写入物理内存。

fp (Fill Physical Memory)命令在物理内存范围内写入一个模板,并重复直到内存块被填充满。

内核模式下使用WinDbg时,也可以直接使用Memory 窗口读写物理内存。

在物理内存中搜索一块数据或一个范围内的数据,使用!search扩展命令。

同样,关于物理地址的更多信息,查看将虚拟地址转换为物理地址

访问全局变量

全局变量的名字保存在应用程序编译时创建的符号文件中。调试器将全局变量名转换成虚拟地址。因此,任何接受地址作为参数的命令也可以适用变量名作为参数。

因此,可以使用本主题前面提到的所有命令来读写全局变量。

另外,可以使用? (Evaluate Expression)命令来显示和任何符号关联的地址。

下面例子中,假设需要查看一个32位整数MyCounter 全局变量的值。假设当前的基数为10。

可以用下面的方法得到它的地址并显示它。

0:000> ? MyCounter 
Evaluate expression: 1244892 = 0012fedc
0:000> dd 0x0012fedc L1 
0012fedc  00000052

第一个命令的输出表明MyCounter 的地址为0x0012FEDC。然后可以使用 D* 命令来显示该地址的一个双字。 (也可以使用1244892,这个地址的10进制值。但是,大多数C程序员会选择使用0x0012FEDC。) 第二条命令表明MyCounter 的值为0x52 (10进制82)。

可以用下面一条命令实现上面这些步骤。

0:000> dd MyCounter L1 
0012fedc  00000052

要将MyCounter 修改为10进制的83,使用下面的命令。

0:000> ed MyCounter 83 

这个例子使用10进制输入,因为这样对于整数来说要自然一些。但是,D* 命令的输出仍然是16进制格式。

0:000> dd MyCounter L1 0012fedc  00000053

访问局部变量

局部变量和全局变量类似,也在符号文件中保存了信息。调试器同样会将它们的名字转换为地址。它们可以使用和全局变量一样的方式来读写。但是,如果某个命令需要指明某个符号是局部的,可以对符号使用单个美元符号( $ )和感叹号( ! )前缀,如$!var

也可以使用下面这些方法来显示、修改和使用局部变量:

但是,局部变量和全局变量有一个主要的不同。当程序运行时,局部变量的意义由程序计数器的位置决定,因为这些变量的作用范围仅在定义它们的函数内部。

调试器根据局部上下文来解释局部变量。默认情况下这个上下文和程序计数器位置匹配。但是调试器可以改变上下文。关于局部上下文的更多信息,查看局部上下文

当局部上下文被改变时,局部窗口会立即更新以显示新的局部变量集合。DV 命令也显示新的变量。所有这些新的变量都能够被上述的内存命令正确解释,之后就可以读写这些变量了。

调试优化后的代码时,有些局部变量可能被合并(collapsed?)、使用寄存器替代或可能只是临时存放到堆栈中。如果要在调试中使用源码文件或局部变量,最好不要优化代码。

通过监视窗口控制变量

在WinDbg中,也可以使用监视窗口(Watch window)来显示、修改全局和局部变量。

监视窗口可以显示任何需要的变量列表。可以包含全局变量和任何函数的局部变量。任何时候,监视窗口都显示这些变量中和当前函数作用范围匹配的那部分变量。同样可以通过监视窗口修改变量的值。

和局部窗口不同,监视窗口不会受到局部上下文的影响。只有当前的程序计数器作用范围内定义的变量能够被显示和修改。

关于该窗口的更多信息,查看监视窗口

Build machine: CAPEBUILD