五、源文件行语法

可以将源文件行号指定为MASM表达式的全部或部分。这些数字计算出与该源代码行对应的可执行代码的偏移量。不能使用源代码行作为C++表达式的一部分。必须用重音符(`)将源文件和行号表达式括起来。以下示例显示源文件行号的完整格式。

`[[Module!]Filename][:LineNumber]`

如果有多个文件具有相同的文件名,则文件名应包括整个目录路径和文件名。此目录路径应该是编译时使用的路径。如果只提供文件名或路径的一部分,并且存在多个匹配项,则调试器将使用找到的第一个匹配项。如果省略了文件名,调试器将使用与当前程序计数器对应的源文件。除非在行号前面加上0x,否则行号将作为十进制数读取,而不考虑当前的默认基数。如果省略了linenumber,表达式将计算出与源文件对应的可执行文件的初始地址。除非发出.lines(切换源行支持)命令或在启动windbg时包含-lines命令行选项,否则不会在cdb中计算源行表达式。

六、地址和地址范围语法

在调试器中有几种指定地址的方法。地址始终是虚拟地址,除非文档专门指明另一种地址。在用户模式下,调试器根据当前进程的页目录解释虚拟地址。在内核模式下,调试器根据进程上下文指定的进程页目录解释虚拟地址。还可以直接设置用户模式地址上下文。

6.1、地址模式和段支持

在基于x86的平台上,CDB和KD支持以下寻址模式。这些模式通过前缀来区分。

前缀 名称 地址类型

%

平坦

32 位地址 (也 16 位选择器,指向 32 位段) 和 64 位系统上的 64 位地址。

&

virtual 86

实模式地址。 基于 x86 的仅。

#

实模式地址。 基于 x86 的仅。

普通模式和虚拟模式86的区别在于普通16位地址使用段值作为选择器,并查找段描述符。但一个虚拟的86地址不使用选择器,而是直接映射到较低的1 MB中。如果通过不是当前默认模式的寻址模式访问内存,则可以使用地址模式前缀覆盖当前地址模式。
6.2、地址参数
地址参数指定变量和函数的位置。下表说明了可以在CDB和KD中使用的各种地址的语法和含义。

语法 含义

offset

虚拟内存空间,含对应于当前的执行模式的类型中的绝对地址。 例如,如果当前的执行模式是 16 位,偏移量为 16 位。 如果执行模式是 32 位分段,偏移量为 32 位分段。

&[[段:]] 偏移量

实际地址。 基于 x86 和基于 x64 的。

%segment:[[ offset]]

分段的 32 位或 64 位地址。 基于 x86 和基于 x64 的。

%[[偏移量]]

一个绝对地址 (32 位或 64 位) 的虚拟内存空间中。 基于 x86 和基于 x64 的。

name[[ +| ]] offset

一个平面 32 位或 64 位地址。 名称可以是任何符号。 偏移量指定的偏移量。 此偏移量可以是任何其前缀表示的地址模式。 无前缀指定默认模式地址。 您可以指定偏移量为正 (+) 或负值 (−)。

使用dg (Display Selector)命令查看段描述符信息。在MASM表达式中,还可以使用POI运算符取消对任何指针的引用。例如,如果地址0x00123456处的指针指向地址位置0x004200,则以下两个命令是等效的。

:> dd
:> dd poi()

在C++表达式中,指针就像C++中的指针一样。然而,数字被解释为整数。如果必须遵从实际数字,则必须首先对其进行强制转换,如下例所示

:> dd *( (long*) 0x123456 ) 

一些伪寄存器还保存着公共地址,例如当前程序计数器位置。还可以通过指定原始源文件名和行号来指示应用程序中的地址。

6.3、地址范围

您可以通过一对地址或一个地址和对象计数来指定地址范围。要通过一对地址指定范围,请指定起始地址和结束地址。例如,下面的示例是一个8字节的范围,从地址0x0001000开始。
0x00001000  0x00001007

要通过地址和对象计数指定地址范围,请指定地址参数、字母L(大写或小写)和值参数。地址指定起始地址。该值指定要检查或显示的对象数。对象的大小取决于命令。例如,如果对象大小为1字节,下面的示例是8字节的范围,从地址0x0001000开始。

0x00001000  L8

但是,如果对象大小是一个双字(32位或4字节),则以下两个范围分别给出一个8字节的范围。

0x00001000  0x00001007
0x00001000 L2

指定值还有两种其他方法(lsize范围说明符):

  • L?大小(带问号)表示与l size相同,除了l?大小删除了调试器的自动范围限制。通常,范围限制为256 MB,因为较大的范围是印刷错误。如果要指定大于256 MB的范围,必须使用L?大小语法。
  • L-size(带连字符)指定以给定地址结尾的长度大小范围。例如,8000000 L20指定从0x8000000到0x800001F的范围,8000000 L-20指定从0x7fffffffe0到0x7fffffffff的范围。

一些要求地址范围的命令接受一个地址作为参数。在这种情况下,命令使用一些默认的对象计数来计算范围的大小。通常,地址范围是最终参数的命令允许使用这种语法。

七、线程操作语法

许多调试器命令的参数都是线程标识符。波浪线(~)出现在线程标识符之前。
线程标识符可以是以下值之一:

线程标识符 描述

~.

当前线程。

~#

导致当前异常或调试事件的线程。

~*

此进程中的所有线程。

~数量

其索引的线程

~~[TID]

其线程 ID 是在线程TID。 (括号是必需的和不能添加第二个波形符和左大括号之间有空格)。

~[表达式]

线程的线程 ID 是到整数数值表达式解析。

线程在创建时被分配索引。请注意,此数字与Microsoft Windows操作系统使用的线程ID不同。调试开始时,当前线程是导致当前异常或调试事件(或调试器附加到进程时的活动线程)的线程。在使用~s(设置当前线程)命令或使用windbg中的“进程和线程”窗口指定新线程之前,该线程一直是当前线程。线程标识符通常作为命令前缀出现。请注意,并非所有通配符都在使用线程标识符的所有命令中可用。~[expression]语法的一个例子是~[@$t0]。在本例中,线程根据用户定义的伪寄存器的值进行更改。此语法允许调试器脚本以编程方式选择线程。

在内核模式下控制线程

在内核模式下,不能使用线程标识符控制线程。在用户模式调试期间,可以使用波浪线字符(~)指定线程。在内核模式调试中,可以使用tilde指定处理器。

八、进程操作语法

许多调试器命令的参数都是进程标识符。一个竖条(|)出现在进程标识符之前。进程标识符可以是以下值之一。

进程标识符 描述

|.

当前进程。

|#

引起当前异常或调试事件的进程。

|*

所有进程。

|数量

进程的第几

|~[PID]

进程的进程 ID PID。 (括号是必需的和不能添加颚化符 (~) 和左大括号之间有空格)。

|[Expression]

其进程 ID 的整数进程数值表达式解析。

进程在创建时被分配序号。请注意,此数字与Microsoft Windows操作系统使用的进程ID(PID)不同。当前进程定义内存空间和使用的线程集。调试开始时,当前进程是导致当前异常或调试事件(或调试器附加到的进程)的进程。在使用(设置当前进程)命令或使用windbg中的“进程和线程”窗口指定新进程之前,该进程一直是当前进程。进程标识符在多个命令中用作参数,通常用作命令前缀。注意,windbg和cdb可以调试原始进程创建的子进程。windbg和cdb也可以附加到多个不相关的进程。|[表达式]语法的一个例子是[|@$t0]。在本例中,进程根据用户定义的伪寄存器的值而变化。此语法允许调试器脚本以编程方式选择进程。在内核模式下,不能使用进程标识符来控制进程。
九、系统操作语法
许多调试器命令的参数都是进程标识符。系统标识符前会出现两个竖线(||)。系统标识符可以是以下值之一。
系统标识符 描述

||.

当前系统

||#

导致当前异常或调试事件系统。

||*

所有系统。

||ddd

系统其序号ddd

系统按照调试器附加到它们的顺序分配序号。调试开始时,当前系统是导致当前异常或调试事件的系统(或是调试器最近附加到的系统)。在使用(||s (Set Current System))命令或使用windbg中的“进程和线程”窗口指定新系统之前,该系统将保持当前系统。
 
示例
此示例演示三个转储文件已加载。 系统 1 处于活动状态,并且系统 2 导致调试事件。
||1:1:017> ||
0 User mini dump: c:\notepad.dmp
. 1 User mini dump: c:\paint.dmp
# 2 User mini dump: c:\calc.dmp
要使用多个系统,可以同时使用.opendump调试多个崩溃转储。

注意,在一起调试活动目标和转储目标时会有一些复杂的情况,因为对于每种调试类型,命令的行为都不同。例如,如果在当前系统是转储文件时使用g(go)命令,则调试器将开始执行,但不能重新进入调试器,因为break命令不被识别为对转储文件调试有效。

十、多处理器操作语法
 kd和内核模式windbg支持多处理器调试。您可以在任何多处理器平台上执行这种调试。处理器编号为0到N。如果当前处理器是处理器0(即,如果是当前导致调试器处于活动状态的处理器),则可以检查其他非当前处理器(从一个处理器到n个处理器)。但是,您不能更改非当前处理器中的任何内容。您只能查看它们的状态。
10.1、选择处理器
可以使用.echocpnum(show cpu number)命令显示当前处理器的处理器号。此命令的输出使您能够通过内核调试提示中的文本立即判断您在多处理器系统上工作的时间。
在下面的示例中,0:在kd>提示前表示正在调试计算机中的第一个处理器。
0: kd>

使用~s(更改当前处理器)命令在处理器之间切换,如下例所示。

0: kd> ~1s
1: kd>

现在正在调试的计算机中的第二个处理器。

如果遇到中断而无法理解堆栈跟踪,则可能需要更改多处理器系统上的处理器。中断可能发生在其他处理器上。

10.2、在其他命令中指定处理器
您可以在多个命令之前添加处理器编号。除了在~s命令中,此数字前面没有波浪号(~)。在用户模式调试中,tilde用于指定线程。有关此语法的详细信息,请参阅线程语法。不必显式引用处理器ID。相反,可以使用解析为与处理器ID对应的整数的数值表达式。若要指示应将表达式解释为处理器,请使用以下语法。
||[Expression]

在这种语法中,方括号是必需的,表达式表示任何解析为与处理器ID对应的整数的数值表达式。在下面的示例中,处理器根据用户定义的伪寄存器的值进行更改。

||[@$t0]

示例

下面的示例使用k(显示堆栈回溯)命令显示来自处理器2的堆栈跟踪。
1: kd> 2k

下面的示例使用r(registers)命令显示处理器3的EAX寄存器。

1: kd> 3r eax
但是,以下命令给出了一个语法错误,因为您不能更改当前处理器以外的处理器的状态。
1: kd> 3r eax=808080

10.3、断点

在内核调试期间,bp、bu、bm(设置断点)和ba(访问中断)命令适用于多处理器计算机的所有处理器。例如,如果当前处理器是三个,则可以输入以下命令在someaddress处放置断点。

1: kd> bp SomeAddress

然后,在该地址执行的任何处理器(不仅是处理器一个)都会导致断点陷阱。

10.4、显示处理器信息

您可以使用!运行扩展以显示目标计算机上每个处理器的状态。对于每个处理器,!running还可以显示进程控制块(prcb)中的当前和下一个线程字段、16个内置排队spinlocks的状态以及堆栈跟踪。 您可以使用!cpuinfo和!cpuid扩展以显示有关处理器本身的信息。

Windbg命令的语法规则系列(三)的更多相关文章

  1. Windbg命令的语法规则系列(二)

    二.字符串通配符语法 一些调试器命令具有接受各种通配符的字符串参数.这些类型的参数支持以下语法功能: 星号(*)表示零个或多个字符. 问号(?)表示任何单个字符. 包含字符列表的括号([])表示列表中 ...

  2. Windbg命令的语法规则系列(一)

    本文介绍使用调试器命令必须遵循的语法规则.使用Windbg调试时,应遵守以下一般语法规则: 您可以在命令和参数中使用大小写字母的任意组合,除非在本节的主题中特别指出. 可以用一个或多个空格或逗号(,) ...

  3. 常见bat(批处理)命令的语法规则

    最近由于在做cocos2d的项目,需要用到一些bat命令,在此做些记录. bat命令用txt文本编辑就行,编辑完之后将后缀名改为bat即可运行.先来一个最简单的例子: @echo off echo \ ...

  4. Windbg命令脚本

    命令脚本,就是将完成某个特定任务的相关命令组合在一起,保存在脚本文件里,加载到Windbg里执行,达到我们的目的.你可以理解为脚本就是一种语言,就像c或者汇编,但是他不需要编译器将其编译为可执行文件, ...

  5. WinDbg 命令三部曲:(三)WinDbg SOSEX 扩展命令手册

    本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载. 系列博文 <WinDbg 命令三部曲:(一)WinDbg 命令手册> <WinDb ...

  6. Python学习系列(四)Python 入门语法规则2

    Python学习系列(四)Python 入门语法规则2 2017-4-3 09:18:04 编码和解码 Unicode.gbk,utf8之间的关系 2.对于py2.7, 如果utf8>gbk, ...

  7. docker常用命令、镜像命令、容器命令、数据卷,使用dockerFile创建镜像,dockefile的语法规则。

    一.docker常用命令? 1. 常用帮助命令 1.1 docker的信息以及版本号 /* docker info 查看docker的信息 images2 docker本身就是一个镜像. docker ...

  8. Hexo系列(三) 常用命令详解

    Hexo 框架可以帮助我们快速创建一个属于自己的博客网站,熟悉 Hexo 框架提供的命令有利于我们管理博客 1.hexo init hexo init 命令用于初始化本地文件夹为网站的根目录 $ he ...

  9. iptables系列教程(二)| iptables语法规则

    一个执着于技术的公众号 iptables 命令基本语法 " iptables [-t table] command [链名] [条件匹配] [-j 目标动作] 以下是对 iptables 命 ...

随机推荐

  1. xorm-删除和软删除实例

    删除数据Delete方法,参数为struct的指针并且成为查询条件.注意:当删除时,如果user中包含有bool,float64或者float32类型,有可能会使删除失败 package main i ...

  2. python 递归-汉诺塔

    # 汉诺塔 a = "A" b = "B" c = "C" def hano(a, b, c, n): if n == 1: print(& ...

  3. Harbor 开机自启遇到的问题

    Harbor 是一个企业级的 Docker 私有仓库项目,它本身由多个 Docker Containers 组成,通过 docker-compose 管理 containers 之间的依赖关系. 安装 ...

  4. 通过重新上传修改后的docker镜像来在kubeapps上实现k8s上部署的nginx版本更新,回退等

    docker操作:制作自定义镜像 # docker下载官方nginx镜像 docker pull nginx # 基于该镜像运行一个容器 docker run -it -d --name nginx_ ...

  5. Java之路---Day10(抽象)

    2019-10-24-23:21:17 目录 1.抽象的方法 2.抽象类 3.抽象类和抽象方法的使用 4.抽象类的注意事项 5.案例代码 1.抽象的方法 What:如果父类当中的方法不确定如何进行{} ...

  6. iOS - 架构模式 - 解密 MVC、MVP、MVVM、VIPER架构

    在 iOS 中使用 MVC 架构感觉很奇怪? 迁移到MVVM架构又怀有疑虑?听说过 VIPER 又不确定是否真的值得切换? 相信你会找到以上问题的答案,如果没找到请在评论中指出. 你将要整理出你在 i ...

  7. vim插件(vim-emmet)安装步骤

    vim安装插件  vim-emmetvim-emmet网址  https://www.vim.org/scripts/script.php?script_id=2981pathogen.vim网址  ...

  8. Xcode 10 Archive 时电脑卡死

    Xcode 10 Archive Unity5.x 导出工程时电脑卡死.解决办法:Targets - Build Settings - Debug Information Format 设置成DWAR ...

  9. Git管理修正(取消跟踪、合并commit)

    本文总结了最近使用Git时候遇到的两个问题: 1. 当将不必要跟踪的文件加入到仓库后如何处理? 2. 提交了多个功能相同的commit后如何处理? 总结经验 在创建仓库的一开始,就要设置号.gitig ...

  10. 用navicat操作oracle新建表空间、用户名、密码

    转载从:https://www.cnblogs.com/franson-2016/p/5925593.html 首先.我们来新建一个表空间.打开Navicat for Oracle,输入相关的的连接信 ...