windbg 调试器简明手册——第 7 章——调试器命令——第 3 节——命令

说明:

此基本命令除了少数几个命令基本上以字母组合为主。有些命令取单词首字母,而另一些命令看不出按什么缩写,没有缩写规律,因此不具备可记忆性,需要使用的时候要现查询。

    需要注意的是,基本命令中一些命令以 $ 或 $$ 命令开头;一些命令以 ?或 ?? 开头;一些命令以 # 号或 | , || 开头;而线程相关的命令以 ~ 号开头;这些都显得有没有规律,给命令的理解带来困难。

    参数说明比较繁杂,使用时请参阅微软相文档(注意,文档网址可能改变):

https://learn.microsoft.com/en-us/windows-hardware/drivers/debuggercmds/commands

目录

1.  回车命令(重复执行最后一条命令)

1.1  格式

1.2  环境(若后述命令均相同则不再列出本项)

1.3  评注

2.  命令 $<, $><, $$<, $$><, $$ >a<(运行脚本文件)

2.1  格式

2.2  参数

2.3  评注

2.4  示例

3.  ?(帮助命令)

3.1  格式

3.2  评注

4.  ? (求值表达式)

4.1  格式

4.2  参数

4.3  评注

5.  ?? (C++ 求值表达式)

5.1  格式

5.2  参数

5.3  评注

6.  # (汇编搜索模式)

6.1  格式

6.2  参数

6.3  评注

7.  || (系统状态)

7.1  格式

7.2  评注

8.  ||s (设置当前系统)

7.1  参数

7.2  评注

9.  |(处理状态)

9.1  格式

9.2  参数

9.3  评注

10.  |s(设置当前进程)

10.1  格式

10.2  参数

10.3  评注

11.  ~(线程状态)

11.1  格式

11.2  评注

12.  ~e(具体线程命令)

12.1  格式

12.2  参数

12.3  评注

13.  ~f(冻止线程)(Freeze Thread)

13.1  格式

13.2  评注

14.  线程其它操作指令

14.1  解冻线程

14.2  挂起线程

14.3  恢复线程

14.4  设置当前线程

14.5  改变当前处理器

15.  a (汇编)

15.1  格式

15.2  评注

16.  ad (删除别名)

16.1  格式

17.  ah (断言处理)

17.1  格式

17.2   评注

18.  al (列出别名)

19.  as,aS (设置别名)

19.1  格式与参数说明

19.2  评注

20.  ba (访问中断)

20.1  参数说明

20.2  评注

21.  断点相关操作

21.1  bc(清除断点)

21.2  bc(禁用设定的断点)

21.3  bl(列出断点)

21.4  bp,bu,bm(设置断点)

21.5  br(断点重编号)

21.6  bs(更新断点命令)

21.7  bsc(更新条件断点)

22.  c(比较内存)

23.  d, da, db, dc, dd, dD, df, dp, dq, du, dw (显示内存)

24.  dda, ddp, ddu, dpa, dpp, dpu, dqa, dqp, dqu (显示引用内存)

25.  dds, dps, dqs  (显示字与符号)

26.  dg  (显示选择子)

27.  dl  (显示链表)

28.  ds ,dS  (显示串)

29.  dt  (显示类型)

30.  dtx  (显示类型——扩展调试器对象模型信息)

31.  dv  (显示局部变量)

32.  e, ea, eb, ed, eD, ef, ep, eq, eu, ew, eza  (键入值)

33.  f,fp  (填充内存)

34.  g  (继续调试)

35.  gh  (异常处理完毕继续调试)

36.  gn,gN  (异常未处理完毕继续调试)

37.  gu(Go Up) (运行到当前函数执行完毕)

38.  ib, iw, id  (从端口输入)

39.  ib, iw, id  (从端口输入)

40.  j  (执行 If-Else 语句)

41.  k, kb, kc, kd, kp, kP, kv  (显示栈回溯)

42.  l+,l- (设置源选项)

43.  ld (加载调试符号文件)

44.  lm (列出加载模块)

45.  ln (列出最近的调试符号)

46.  ls,lsa (列出源行)

47.  lsc (列出当前源行)

48.  lsc (列出当前源行)

49.  lse (启动源编辑器)

50.  lsf,lsf- (加载或卸载源文件)

51.  lsp (设置源行数)

52.  m (移动内存)

53.  n (设置数基)

54.  ob, ow, od (输出至端口)

55.  步进命令

55.1  p(步进)

55.2  pa(步进到地址)

55.3  pc(步进到下一个调用)

55.4  pct(步进到下一个调用或返回)

55.5  ph(步进到下一个分支指令)

55.6  pt(步进到下一个返回)

56.  停止命令

56.1  q,qq(停止)

56.2  qd(停止并分离)

57.  寄存器相关操作

57.1  r(register)(寄存器操作)

57.2  rdmsr(Read MSR)(读MSR寄存器)

57.3  rm(Register Mask)(寄存器掩码)

58.  s(搜索内存)

59.  so(设置内核调试选项)

60.  sq(设置停止模式)

61.  sq(设置符号后缀)

62.  sx, sxd, sxe, sxi, sxn, sxr, sx- (设置异常)

63.  跟踪相关命令

63.1  t(trace)(跟踪)

63.2  ta (跟踪到地址)

63.3  tb (跟踪到下一个分支(Branch))

63.4  tc (跟踪到下一个调用)

63.5  tct (跟踪到下一个调用或返回)

63.6  th (跟踪到下一个分支指令)

63.7  tt (跟踪到下一个返回)

64.  反汇编相关命令

64.1  u, ub, uu (反汇编)

64.2  uf (反汇编函数)

64.3  up(unassemble physical) (从物理内存反汇编)

64.4  ur(unassemble real mode BIOS) (反汇编实模式BIOS)

64.5  ux(unassemble x86 BIOS) (反汇编x86 BIOS)

65.  vercommand(显示调试器命令行)

66.  version(显示调试器版本)

67.  vertarget(显示目标计算机版本)

68.  vertarget(显示目标计算机版本)

69.  wrmsr(写MSR)

70.  wt(Trace and Watch Data)(跟踪并观察数据)

71.  x(Examine Symbols)(检查符号)

72.  z(Execution While)(条件执行)


1.  回车命令(重复执行最后一条命令)

         按回车键会重复你输入的最后一条命令。

1.1  格式

         回车

1.2  环境(若后述命令均相同则不再列出本项)

 说明

模式

用户模式,内核模式

目标

实时调试(live), 崩溃转储(crash dump)

平台

所有

1.3  评注

    在 CDB、KD 和 WinDbg 中,在调试器命令提示符下单独按下 Enter 键会重新执行之前输入的命令。有关详细信息,请参阅“使用调试器命令”。

    如果要在调试器命令窗口中创建空白,请使用 * (注释行说明符)标记,然后按 ENTER 键几次。

2.  命令 $<, $><, $$<, $$><, $$ >a<(运行脚本文件)

$< , $>< ,$$< ,$$>< 和 $$>a< 命令读取指定脚本文件的内容,并将其内容用作调试器命令输入。

2.1  格式

$<Filename

$><Filename

$$<Filename

$$><Filename

$$>a<Filename [arg1 arg2 arg3 ...]

2.2  参数

Filename指定一个包含有效调试器命令文本的文件。文件名必须遵循 Microsoft Windows 文件名命名约定。文件名可以包含空格

argn 指定调试器要传递给脚本的任意数量的字符串参数。调试器会在执行脚本之前,将脚本文件中所有形如 ${$argn} 的字符串替换为相应的 argn。参数不能包含引号或分号多个参数之间必须用空格分隔如果参数包含空格,则必须用引号将其括起来。所有参数均为可选参数

2.3  评注

      $$< 和 $< 标记会按字面意思执行脚本文件中的命令。但是,使用 $< 时,你可以指定任何文件名,包括包含分号的文件名。由于 $< 允许在文件名中使用分号,因此你不能将 $< 与其他调试器命令连接起来,因为分号不能同时用作命令分隔符和文件名的一部分。

    $$>< 和 $>< 标记也会按字面意思执行脚本文件中的命令,这意味着它们会打开脚本文件,将所有回车符替换为分号,并将生成的文本作为单个命令块执行。与前面讨论的 $< 类似,$>< 也允许文件名包含分号,这意味着你不能将 $>< 与其他调试器命令连接起来。

    如果你正在运行包含调试器命令程序的脚本,则 $$>< 和 $>< 标记非常有用。有关这些程序的更多信息,请参阅“使用调试器命令程序”。

除非文件名包含分号,否则无需使用 $< 或 $><。

$$>a< 标记允许调试器向脚本传递参数。如果文件名包含空格,则必须用引号括起来。如果提供的参数过多,多余的参数将被忽略。如果提供的参数过少,源文件中任何形如 ${$argn}(其中 n 大于提供的参数数量)的标记都将保持其字面形式,不会被替换。你可以在此命令后跟分号和其他命令;分号的存在表示参数列表结束。

当调试器执行脚本文件时,命令及其输出将显示在“调试器命令”窗口中。脚本文件执行完毕后,控制权将返回给调试器。

    这些标记的使用概括如下:

标记

允许文件名包含分号

允许连接多个以分号分隔的命令

简化为单个命令方块

允许脚本参数

$<

$><

$$<

$$><

$$>a<

$< ,$>< ,$$<  和 $$>< 命令会回显脚本文件中的命令并显示这些命令的输出。$$>a< 命令不会回显脚本文件中的命令,而只是显示它们的输出。

    脚本文件可以嵌套。如果调试器在脚本文件中遇到这些标记之一,执行将跳转到新的脚本文件,并在新的脚本文件执行完毕后返回到之前的位置。脚本也可以递归调用。

    WinDbg 中,你可以将附加命令文本粘贴到“调试器命令”窗口中。

2.4  示例

    以下示例演示如何将参数传递给脚本文件 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.

以下示例展示了当提供的参数数量错误时会发生什么情况。假设文件 My Script.txt 包含以下文本:

.echo The first argument is ${$arg1}.

.echo The fifth argument is ${$arg5}.

.echo The fourth argument is ${$arg4}.

然后,以下以分号分隔的命令行会产生如下输出:

0:000> $$>a< "c:\binl\my script.txt" "First one" Two "Three More" Four; recx

The first argument is First one.

The fifth argument is ${$arg5}.

The fourth argument is Four.

ecx=0021f4ac

在前面的例子中,文件名用引号括起来是因为它包含空格,包含空格的参数也用引号括起来。虽然脚本似乎需要第五个参数,但分号在第四个参数之后就终止了 $$>a< 命令。

3.  (帮助命令)

问号 (?) 字符会显示所有命令和运算符的列表。注意:单独一个问号会显示命令帮助。问号表达式语法会计算给定表达式的值。

3.1  格式

?

3.2  评注

    要了解有关标准命令的更多信息,请使用 ?。要了解有关元命令的更多信息,请使用 .help。要了解有关扩展命令的更多信息,请使用 !help。

4.  ? (求值表达式)

问号 (?) 命令用于计算并显示表达式的值。

    单独的问号 (?) 用于显示命令帮助。问号表达式 (? expression) 命令用于计算给定表达式的值。

4.1  格式

? Expression

4.2  参数

Expression:指定需计算的表达式。

4.3  评注

? 命令的输入和输出取决于你使用的是 MASM 表达式语法还是 C++ 表达式语法。有关这些表达式语法的更多信息,请参阅“表达式求值”和“数值表达式语法”。

    如果你使用的是 MASM 语法,则输入和输出取决于当前基数。要更改基数,请使用 n (设置数字基数)命令。

    ? 命令在当前线程和进程的上下文中计算表达式中的符号。

    某些字符串可能包含转义字符,例如 \n、\r 和 \b,这些转义字符应按字面意思读取,而不是由求值器解释。如果字符串中的转义字符被求值器解释,则可能会出现求值错误。例如:

0:000> as AliasName c:\dir\name.txt

0:000> al

  Alias            Value

 -------          -------

 AliasName        c:\dir\name.txt

0:001> ? $spat( "c:\dir\name.txt", "*name*" )

Evaluate expression: 0 = 00000000

0:001> ? $spat( "${AliasName}", "*name*" )

Evaluate expression: 0 = 00000000

0:001> ? $spat( "c:\dir\", "*filename*" )

Syntax error at '( "c:\dir\", "*filename*" )

在前两个示例中,即使字符串与模式匹配,求值器也返回 FALSE 值。在第三个示例中,由于字符串以反斜杠 (\) 结尾,求值器无法进行比较,因此反斜杠 (\) 会被求值器转换。

    要使求值器按字面意思解释字符串,必须使用 @"String" 语法。以下代码示例显示了正确的结果:

0:000> ? $spat( @"c:\dir\name.txt", "*name*" )

Evaluate expression: 1 = 00000000`00000001

0:000> ? $spat( @"${AliasName}", "*name*" )

Evaluate expression: 1 = 00000000`00000001

0:001> ? $spat( @"c:\dir\", "*filename*" )

Evaluate expression: 0 = 00000000

在前面的示例中,$spat MASM 运算符检查第一个字符串,以确定它是否(不区分大小写)与第二个字符串的模式匹配。有关 MASM 运算符的更多信息,请参阅“MASM 数字和运算符”主题。

5.  ?? (C++ 求值表达式)

    双问号 (??) 命令根据 C++ 表达式规则计算并显示表达式的值。

5.1  格式

?? Expression

5.2  参数

Expression:指定要计算的 C++ 表达式。有关语法的更多信息,请参阅 C++ 数字和运算符。

5.3  评注

?? 命令会在当前线程和进程的上下文中计算表达式中的符号。

    如果要根据 MA​​SM 表达式规则计算表达式的一部分,请将该部分用括号括起来,并在其前面添加两个 @ 符号。有关 MASM 表达式和 C++ 表达式的更多信息,请参阅“计算表达式”和“数值表达式语法”。

6.  # (汇编搜索模式)

井号 (#) 命令在反汇编代码中搜索指定的模式。有关汇编调试和相关命令的更多信息,请参阅“汇编模式下的调试”。

6.1  格式

# [Pattern] [Address [ L Size ]]

6.2  参数

(1) Pattern:指定要在反汇编代码中搜索的模式。模式可以包含各种通配符和说明符。有关语法的更多信息,请参阅字符串通配符语法。如果要在模式中包含空格,则必须将模式用引号括起来。模式不区分大小写。如果之前使用过 # 命令,并且省略了模式,则该命令将重用最近一次使用的模式。

(2) Address:指定搜索的起始地址。有关语法的更多信息,请参阅“地址和地址范围语法”。

(3) Size:指定要搜索的指令数量。如果省略“大小”,搜索将持续进行,直到找到第一个匹配项为止。

6.3  评注

    若你之前使用过 # 命令,并且省略了 Address 参数,则搜索将从上次搜索结束的位置开始。

    此命令通过在反汇编文本中搜索指定的模式来工作。你可以使用此命令查找寄存器名称、常量或反汇编输出中出现的任何其他字符串。你可以重复执行此命令,但不使用 Address 参数,以查找模式的连续出现。

    你可以使用 u(反汇编)命令或使用 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 出现在显示的不同位置。请改用 mov*eax。

    例如,你可以执行以下命令来搜索 main 入口点之后对 strlen 函数的第一个引用。

# strlen main

    同样地,你可以发出以下两个命令来查找地址 0x779F9FBA 之后的第一个 jnz 指令,然后再查找其后的下一个 jnz 指令。

    # jnz 779f9fba#

如果省略 Pattern 或 Address 参数,它们的值将基于上次使用 # 命令的情况。如果首次执行 # 命令时省略任一参数,则不会执行搜索。但是,即使在这种情况下,Pattern 和 Address 的值也会被初始化。

    如果包含 Pattern 或 Address 参数,则其值将设置为输入的值。如果省略 Address 参数,则其值将初始化为程序计数器的当前值。如果省略 Pattern 参数,则其值将初始化为空模式。

7.  || (系统状态)

双竖线(||)命令用于打印指定系统的状态,或当前正在调试的所有系统的状态。注意,不要将此命令与单竖线(|)(系统状态)命令混淆。

7.1  格式

|| System

指定要显示的系统。如果省略此参数,将显示你正在调试的所有系统。

7.2  评注

    || 命令仅在调试多个目标时才有用。许多(但并非全部)多目标调试会话都涉及多个系统。

    每个系统列表均包含服务器名称和协议详细信息。调试器当前运行所在的系统标识为 <Local>。

(1) 例如:

0:000>||

显示如下:

.  0 Live user mode: <Local>

(2) 下列命令同样显示所有系统:

0:000>||*

显示如下:

.  0 Live user mode: <Local>

(3) 下列命令显示当前活动系统:

0:000>||.

显示如下:

.  0 Live user mode: <Local>

(4)   下列命令显示最近异常或中断的系统:

0:000>||#

显示如下:

.  0 Live user mode: <Local>

(5)   下列命令显示系统号为2的系统:

0:000>||2

显示如下:

.  2 Live user mode: <Local>

8.  ||s (设置当前系统)

    ||s 命令设置或显示当前系统号。

||System s

|| s

不要将此命令与 s(搜索内存)、~s(改变当前处理器)、~s(设置当前线程)、或 |s(设置当前进程)命令混淆。

7.1  参数

System 为指定要激活的系统号。

7.2  评注

当你调试多个目标或处理多个转储文件时,||s 命令非常有用。如果你使用 ||s 语法,调试器将显示有关当前系统的信息。

此命令也对当前系统、进程和线程的当前指令进行反汇编。

注意:

    当你同时对实时目标和转储目标进行调试时,会遇到一些复杂情况,因为针对不同类型的调试,命令的行为各不相同。例如,如果当前系统环境为转储文件,此时你使用 g (Go) 命令,调试器便会开始执行;但随后你将无法中断并重新回到调试器中,因为在转储文件调试模式下,break 命令不视为有效命令

9.  |(处理状态)

    管道(|)命令显示指定进程,或当前正在调试的所有进程的状态。匆将此命令与 ||(系统状态命令)混淆。

9.1  格式

   

| Process

例如:

0:000> | 0

输出:

.  0   id: 2630      create name: TestVC++.exe

9.2  参数

    指定要显示的进程。如果省略此参数,将显示所有正在调试的进程。

9.3  评注

    只有在用户模式下才能指定进程。你可以在许多命令前添加进程符号。有关竖线 (|) 后跟命令的含义,请参阅该命令本身的条目。除非你在启动调试会话时启用了子进程调试,否则调试器只能调试一个进程。

    以下示例演示了如何使用此命令。

(1) 以下命令显示所有进程。

0:000> |

输出:

.  0   id: 2630      create name: TestVC++.exe

(2) 以下命令显示所有进程。

0:000> |*

输出:

.  0   id: 2630      create name: TestVC++.exe

(3) 下面命令显示当前活动进程

|.

(4)  以下命令显示了最初引发异常(或调试器最初附加)的进程。

|#

(5)  以下命令显示进程号为 2 的调试进程。

|2

10.  |s(设置当前进程)

    |s 命令用于设置或显示当前进程号。请勿将此命令与 s (搜索内存)、~s (更改当前处理器)、~s (设置当前线程) 或 ||s (设置当前系统) 命令混淆。

10.1  格式

|Process s

|s

10.2  参数

    进程号

指定要设置或显示的进程号。

10.3  评注

    只有在用户模式下才能指定进程。如果使用 |s 语法,调试器会显示有关当前进程的信息。此命令还会反汇编当前系统、进程和线程的当前指令。

11.  ~(线程状态)

    波浪号( ~ )命令显示指定线程或当前进程中所有线程的状态。

11.1  格式

~ Thread(线程号)

指定要显示的线程之线程号。如果省略此参数,将显示所有线程。

11.2  评注

    只有在用户模式下才能指定线程。在内核模式下,波浪号 (~) 指的是处理器。你可以在许多命令前添加线程符号。

    以下示例演示了如何使用此命令。

(1) 以下命令显示所有线程。

0:000> ~

输出:

.  0  Id: 2630.1ce4 Suspend: 1 Teb: 000000a8`d30c8000 Unfrozen

   1  Id: 2630.5468 Suspend: 1 Teb: 000000a8`d30ca000 Unfrozen

   2  Id: 2630.4cdc Suspend: 1 Teb: 000000a8`d30cc000 Unfrozen

   3  Id: 2630.2ba4 Suspend: 1 Teb: 000000a8`d30ce000 Unfrozen

(2) 以下命令同样显示所有线程。

0:000> ~*

输出(格式略有差异):

.  0  Id: 2630.1ce4 Suspend: 1 Teb: 000000a8`d30c8000 Unfrozen

      Start: TestVC__!ILT+23780(wmainCRTStartup) (00007ff6`e4c66ce9)

      Priority: 0  Priority class: 32  Affinity: ff

   1  Id: 2630.5468 Suspend: 1 Teb: 000000a8`d30ca000 Unfrozen

      Start: ntdll!TppWorkerThread (00007ffb`d5345550)

      Priority: 0  Priority class: 32  Affinity: ff

   2  Id: 2630.4cdc Suspend: 1 Teb: 000000a8`d30cc000 Unfrozen

      Start: ntdll!TppWorkerThread (00007ffb`d5345550)

      Priority: 0  Priority class: 32  Affinity: ff

   3  Id: 2630.2ba4 Suspend: 1 Teb: 000000a8`d30ce000 Unfrozen

      Start: ntdll!TppWorkerThread (00007ffb`d5345550)

      Priority: 0  Priority class: 32  Affinity: ff

(3) 以下显示当前活动线程。

0:000> ~.

输出:

.  0  Id: 2630.1ce4 Suspend: 1 Teb: 000000a8`d30c8000 Unfrozen

      Start: TestVC__!ILT+23780(wmainCRTStartup) (00007ff6`e4c66ce9)

      Priority: 0  Priority class: 32  Affinity: ff

(4)  以下命令显示最初引发异常的线程(或调试器附加到进程时处于活动状态的线程)。

0:000> ~#

输出:

.  0  Id: 2630.1ce4 Suspend: 1 Teb: 000000a8`d30c8000 Unfrozen

      Start: TestVC__!ILT+23780(wmainCRTStartup) (00007ff6`e4c66ce9)

      Priority: 0  Priority class: 32  Affinity: ff

(5)  以下命令显示线程 2 (按线程号显示)

0:000> ~2

输出:

2  Id: 2630.4cdc Suspend: 1 Teb: 000000a8`d30cc000 Unfrozen

    Start: ntdll!TppWorkerThread (00007ffb`d5345550)

    Priority: 0  Priority class: 32  Affinity: ff

12.  ~e(具体线程命令)

         ~e 命令针对目标进程中的特定线程或所有线程,执行一条或多条命令。

12.1  格式

    ~e  threadid  命令串

12.2  参数

(1)  threadid 

指定调试器将为其执行命令串的线程或多个线程。

(2) 命令串

         指定要执行的一条或多条命令。多条命令之间应使用分号隔开。命令串包含输入行的其余部分。紧随字母 “e” 之后的所有文本均解析为该字符串的一部分。

12.3  评注

    只有在用户模式下才能指定线程。在内核模式下,波浪号 (~) 指的是处理器。当使用 ~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` 命令访问非活动进程的虚拟内存空间。

13.  ~f(冻止线程)(Freeze Thread)

    ~f 命令会冻止指定的线程,使其停止运行并等待解冻。请勿将此命令与 f(填充内存)命令混淆。

13.1  格式

~Thread f

Thread 用于指定需要冻此的线程号。

13.2  评注

    只有在用户模式下才能指定线程。在内核模式下,波浪号 (~) 指的是处理器。~f 命令会使指定的线程冻止。当调试器使目标应用程序恢复执行时,其他线程会按预期执行,而该线程则保持停止状态。

    以下示例演示了如何使用此命令。

(1) 以下命令显示所有线程的当前状态。

0:000> ~* k

输出:

.  0  Id: 2630.1ce4 Suspend: 1 Teb: 000000a8`d30c8000 Unfrozen

 # Child-SP          RetAddr               Call Site

00 000000a8`d32ff160 00007ffb`d53eec5a     ntdll!LdrpDoDebuggerBreak+0x30

01 000000a8`d32ff1a0 00007ffb`d53da99a     ntdll!LdrpInitializeProcess+0x1cfa

02 000000a8`d32ff570 00007ffb`d53843a3     ntdll!_LdrpInitialize+0x565be

03 000000a8`d32ff5f0 00007ffb`d53842ce     ntdll!LdrpInitializeInternal+0x6b

04 000000a8`d32ff870 00000000`00000000     ntdll!LdrInitializeThunk+0xe

   1  Id: 2630.5468 Suspend: 1 Teb: 000000a8`d30ca000 Unfrozen

 # Child-SP          RetAddr               Call Site

00 000000a8`d33ff678 00007ffb`d534583e     ntdll!NtWaitForWorkViaWorkerFactory+0x14

01 000000a8`d33ff680 00007ffb`d4a6257d     ntdll!TppWorkerThread+0x2ee

02 000000a8`d33ff960 00007ffb`d536af08     KERNEL32!BaseThreadInitThunk+0x1d

03 000000a8`d33ff990 00000000`00000000     ntdll!RtlUserThreadStart+0x28

   2  Id: 2630.4cdc Suspend: 1 Teb: 000000a8`d30cc000 Unfrozen

 # Child-SP          RetAddr               Call Site

00 000000a8`d34ff988 00007ffb`d534583e     ntdll!NtWaitForWorkViaWorkerFactory+0x14

01 000000a8`d34ff990 00007ffb`d4a6257d     ntdll!TppWorkerThread+0x2ee

02 000000a8`d34ffc70 00007ffb`d536af08     KERNEL32!BaseThreadInitThunk+0x1d

03 000000a8`d34ffca0 00000000`00000000     ntdll!RtlUserThreadStart+0x28

   3  Id: 2630.2ba4 Suspend: 1 Teb: 000000a8`d30ce000 Unfrozen

 # Child-SP          RetAddr               Call Site

00 000000a8`d35ff738 00007ffb`d534583e     ntdll!NtWaitForWorkViaWorkerFactory+0x14

01 000000a8`d35ff740 00007ffb`d4a6257d     ntdll!TppWorkerThread+0x2ee

02 000000a8`d35ffa20 00007ffb`d536af08     KERNEL32!BaseThreadInitThunk+0x1d

03 000000a8`d35ffa50 00000000`00000000     ntdll!RtlUserThreadStart+0x28

(2)  以下命令将冻止导致当前异常的线程。

0:000> ~# f

(3)  以下命令用于检查此线程的状态是否为挂起。

0:000> ~* k

(4)  以下命令解冻线程

0:000> ~123 u

14.  线程其它操作指令

14.1  解冻线程

 ~Thread u

(1)  以下命令显示所有线程的当前状态。

0:000> ~* k

(2)  以下命令将冻结导致当前异常的线程。

0:000> ~# f

(3)  以下命令用于检查此线程的状态是否为挂起。

0:000> ~* k

(4)  以下命令解冻线程 123。

0:000> ~123 u

14.2  挂起线程

~Thread n

14.3  恢复线程

~Thread m

14.4  设置当前线程

~Thread s

~ s

14.5  改变当前处理器

~Processor s

仅在内核模式下,你才可以指定处理器。在用户模式下,波浪号(~)代表一个线程。通过观察内核调试提示符的格式,你可以立即判断当前是否正在多处理器系统上进行调试。

(1) 在下例中,“0:”表示你当前正在调试计算机中的第一个处理器。

0: kd>

(2)  使用以下命令在处理器之间切换:

0: kd> ~1s

1: kd>

15.  a (汇编)

15.1  格式

a 命令汇编 32 位 x86 指令助记符,并将生成的指令代码存入内存。

a [Address]

15.2  评注

a 命令不支持 64 位指令助记符。但是,无论你调试的是 32 位目标还是 64 位目标,a  命令都可用。由于 x86 和 x64 指令的相似性,有时在调试 64 位目标时也可以成功使用 a 命令。

如果你未指定地址,汇编程序将从指令指针当前值所指定的地址开始。要汇编一条新指令,请键入所需的助记符并按 Enter 键。要结束汇编,只需按 Enter 键即可。

    由于汇编器会搜索代码中引用的所有符号,因此该命令可能需要一些时间才能完成。在此期间,你无法按 Ctrl+C 结束 a 命令。

16.  ad (删除别名)

16.1  格式

ad [/q] Name

ad *

/q——指定静默模式。如果由 Name 指定的别名不存在,此模式将隐藏错误消息。

Name——指定要删除的别名名称。如果指定星号 (*),则删除所有别名(即使存在名称为 "*" 的别名)。

17.  ah (断言处理)

17.1  格式

    ah 命令用于控制特定地址的断言处理状态。

ahb [Address]

ahi [Address]

ahd [Address]

ahc

ah

参数说明:

ahb——如果指定地址处的断言失败,则进入调试器。

ahi——忽略指定地址处的断言失败。

ahd——删除指定地址处的所有断言处理信息。此删除操作将使调试器在该地址处恢复到默认状态。

Address——指定要设置其断言处理状态的指令的地址。如果省略此参数,调试器将使用当前程序计数器。

ahc——删除当前进程的所有断言处理信息。

ah——显示当前的断言处理设置。

17.2   评注

    ah* 命令用于控制特定地址处的断言处理状态。sx* asrt 命令用于控制全局断言处理状态。如果你针对某个地址使用了 ah* 命令进行设置,随后该地址处发生了断言,调试器将依据 ah*  的设置进行响应,并忽略 sx* asrt 的设置。

    当调试器遇到断言时,它首先会检查是否已针对该特定地址配置了断言处理方式。如果你未对该地址配置具体的处理方式,调试器将采用全局设置。

    ah* 命令仅对当前进程生效。当当前进程终止时,所有的状态设置均将失效。

    断言处理状态仅影响 STATUS_ASSERTION_EXCEPTION 类型的异常。此项处理机制不影响内核模式下的 ASSERT 例程。

18.  al (列出别名)

    al 命令显示当前定义的所有用户命名别名的列表。

19.  as,aS (设置别名)

19.1  格式与参数说明

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 处的 ANSI_STRING 结构体。

/msu——将别名等效值设置为位于 Address 处的 UNICODE_STRING 结构体。

Address——指定用于确定别名等效值的虚拟内存位置。

/x——将别名等效值设置为 Expression 的 64 位数值。

Expression——指定要进行求值的表达式。该数值将成为别名等效值。

/f——将别名等效值设置为 File 文件中的内容。你应当始终将 /f 开关与 aS 配合使用,而不要与 as 配合使用。

File——指定其内容将作为别名等效值的文件。File 可以包含空格,但你绝不应将 File 括在双引号中。如果你指定了无效的文件,将会收到“内存不足”(Out of memory)的错误消息。

/c——将别名等效值设置为 CommandString 所指定的命令的输出结果。如果命令显示内容中包含回车符,则别名等效值中也会包含这些回车符;此外,在每个命令的显示内容末尾也会自动添加一个回车符(即使你仅指定了一个命令)。

CommandString——指定要执行的命令。其输出将成为别名的等效内容。该字符串可包含任意数量的命令,各命令之间以分号分隔。

19.2  评注

如果不使用任何开关参数,as 命令会将该行余下的内容直接用作别名的等效定义。

    你可以使用分号来结束 as 命令。当你需要在脚本中将所有命令置于同一行时,这一技巧非常有用。请注意,如果分号后的那部分内容需要对别名进行展开(即引用该别名),你必须将该部分的命令置于一个新的代码块中。

(1) 以下示例将产生预期的输出:0x6。

0:001> aS /x myAlias 5 + 1; .block{.echo myAlias}

0x6

如果省略该新代码块,将无法获得预期的输出。这是因为,新设置的别名只有在进入新的代码块时才会进行展开。在下面的示例中,由于省略了新代码块,输出结果显示的是文本“myAlias”,而非预期的数值 0x6。

0:001> aS /x myAlias 5 + 1; .echo myAlias

myAlias

如果你使用了 /e、/ma、/mu、/msa、/msu 或 /x 开关,则 as 和 aS 命令的功能完全相同;若遇到分号,命令即终止执行。

如果指定的 Name 已是现有别名的名称,则该别名将被重新定义。

    你可以使用 as 或 aS 命令来创建或修改任何由用户命名的别名。但你无法使用此命令来控制固定名称的别名(即 $u0 到 $u9)。

你可以使用 /ma、/mu、/msa、/msu、/f 和 /c 开关来创建包含回车符的别名。然而,你无法利用包含回车符的别名来按顺序执行多条命令;若需实现此功能,你必须改用分号作为分隔符。

20.  ba (访问中断)

    ba 命令用于设置处理器断点(通常(尽管不太准确)称为数据断点)。当指定的内存位置被访问时,该断点即会触发。

(1) 用户模式

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

(2) 内核模式

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

20.1  参数说明

Thread——指定断点所适用的线程。有关语法的详细信息,请参阅“线程语法”。仅在用户模式下才能指定线程。

ID——指定用于标识断点的可选编号。如果未指定 ID,系统将使用第一个可用的断点编号。在 ba 与 ID 编号之间不能包含空格。每个处理器仅支持有限数量的处理器断点,但对 ID 编号的取值没有限制。如果将 ID 括在方括号([])中,则 ID 可以包含任意表达式。有关语法的详细信息,请参阅“数值表达式语法”。

Access——指定满足断点触发条件的访问类型。此参数可取以下值之一。

e(execute)——当 CPU 从指定地址获取指令时,进入调试器。

r(read/write)——当 CPU 读写指定地址时,进入调试器。

w(write)——当 CPU 向指定地址写入数据时,进入调试器。

i (i/o)——(仅限内核模式,仅限基于 x86 的系统)当访问指定地址处的 I/O 端口时,中断进入调试器。

Size——指定要监视其访问操作的内存位置的大小(以字节为单位)。在基于 x86 的处理器上,此参数可以是 1、2 或 4。但是,如果 Access 参数的值为 e,则 Size 必须为 1。

在基于 x64 的处理器上,此参数可以是 1、2、4 或 8。但是,如果 Access 参数的值为 e,则 Size 必须为 1。

Options—— 指定断点选项。你可以组合使用以下任意数量的选项,但另有说明者除外:

/1——创建一个“一次性”断点。此断点被触发后,将从断点列表中永久移除。

/p EProcess——(仅限内核模式)指定与此断点关联的进程。EProcess 应为 EPROCESS 结构的实际地址,而非 PID。仅当在指定进程的上下文环境中遇到此断点时,断点才会触发。

/t EThread——(仅限内核模式)指定与此断点关联的线程。EThread 应为 ETHREAD 结构的实际地址,而非线程 ID。仅当在指定线程的上下文环境中遇到此断点时,断点才会触发。如果同时使用 /p EProcess 和 /t EThread 选项,你可以按任意顺序输入它们。

/c MaxCallStackDepth——使断点仅在调用堆栈深度小于 MaxCallStackDepth 时处于活动状态。此选项不能与 /C 选项组合使用。

/C MinCallStackDepth——使断点仅在调用堆栈深度大于 MinCallStackDepth 时处于活动状态。此选项不能与 /c 选项组合使用。

/w dx object expression——根据由 dx object expression 返回的布尔值设置条件断点。该参数是一个数据模型 (dx) 表达式,其求值结果为 true(符合条件——触发断点)或 false(不符合条件——不触发断点)。

    本示例基于 globalVariable 的值设置了一个条件断点。这使得访问断点(例如)能够检查被写入的值,从而判定调试器是否应当中断执行。

ba w 4 /w "mymodule!globalVariable == 4" mymodule!globalVariable

本示例展示了如何使用 JavaScript 设置断点。

ba w 4 /w "@$scriptContents.myFunc(mymodule!globalVariable)" mymodule!globalVariable

Address——指定任意有效的地址。如果应用程序访问该地址处的内存,调试器将停止执行,并显示所有寄存器和标志的当前值。该地址必须是一个偏移量,且必须经过适当对齐以与 Size 参数相匹配。(例如,如果 Size 为 4,则 Address 必须是 4 的倍数。)如果省略 Address,将使用当前的指令指针。有关语法的更多信息,请参阅“地址与地址范围语法”。

Passes——指定断点在激活前将被跳过(忽略)的次数。该数值可以是任意 16 位值。程序计数器在不触发中断的情况下通过此点的次数,比该数值小 1。因此,省略该数值等同于将其设置为 1。另请注意,该数值仅统计应用程序“执行”通过此点的次数;通过单步执行(Stepping)或跟踪(Tracing)方式通过此点不计入其中。一旦达到预设的完整计数,你只能通过清除并重新设置断点的方式来重置该数值。

CommandString——指定一组命令列表,每当断点被命中达到指定的次数时,即执行这些命令。这些命令仅在你发出 g (Go) 命令后命中断点时才会执行,而在发出 t (Trace) 或 p (Step) 命令后命中断点时则不执行。CommandString 中的调试器命令可以包含参数。

你必须将该命令字符串用引号括起来,且应使用分号来分隔多个命令。你可以使用标准的 C 语言控制字符(例如 \n 和 \")。包含在二级引号(\")内的分号将被解释为嵌入式带引号字符串的一部分。

该参数是可选的。

20.2  评注

    调试器使用 ID 号码来引用断点,以便在后续的 bc(清除断点)、bd(禁用断点)和 be(启用断点)命令中使用。

    使用 bl(列出断点)命令可以列出所有现有的断点、它们的 ID 号码以及它们的状态。

    使用 .bpcmds(显示断点命令)命令可以列出所有现有的断点、它们的 ID 号码,以及用于创建这些断点的具体命令。

    每个处理器断点都关联着一个特定的“大小”(size)属性。例如,可以在地址 0x70001008 处设置一个 w(写入)类型的处理器断点,并将其大小指定为 4 字节。这样设置后,调试器将监视从地址 0x70001008 到 0x7000100B(含两端)的这一段地址区域。一旦该内存区域发生写入操作,该断点即会被触发。

    有时可能会出现这样一种情况:处理器对某段内存区域执行操作,而该区域与用户指定的断点区域存在重叠,但两者并不完全一致。在上述示例中,如果执行一次包含 0x70001000 至 0x7000100F 这一范围的单次写入操作,或者执行一次仅涉及 0x70001009 处单个字节的写入操作,均属于此类“重叠操作”。在这种情况下,断点是否会被触发,取决于具体的处理器架构。有关具体细节,请查阅相应的处理器手册。举一个具体的例子:在 x86 架构的处理器上,只要访问的内存范围与断点所覆盖的范围存在重叠,无论是读取操作还是写入操作,都会触发相应的断点。

    同理,如果在地址 0x00401003 处设置了一个 e(执行)类型的断点,随后执行了一条跨越地址 0x00401002 和 0x00401003 的双字节指令,那么断点是否触发的结果同样取决于具体的处理器架构。关于此类细节,请再次查阅相应的处理器架构手册。

    处理器能够区分由用户模式调试器设置的断点与由内核模式调试器设置的断点。用户模式下的处理器断点不会对任何内核模式进程产生影响。内核模式处理器断点可能会影响用户模式进程,也可能不会,这取决于用户模式代码是否正在使用调试寄存器状态,以及是否有用户模式调试器处于附加状态。

    若要将当前进程中已有的数据断点应用到另一个寄存器上下文,请使用 .apply_dbp(将数据断点应用到上下文)命令。

在多处理器计算机上,每一个处理器断点都适用于所有的处理器。例如,如果当前处理器为 3,且你使用命令 ba e1 MyAddress 在 MyAddress 处设置了一个断点,那么任何执行到该地址的处理器——而不仅仅是处理器 3——都会触发该断点。(这一规则同样适用于软件断点。)

你无法在同一地址处创建多个处理器断点,如果这些断点之间唯一的区别仅在于其 CommandString(命令字符串)的值不同。不过,你可以在同一地址处创建多个具有不同限制条件的断点(例如,/p、/t、/c 和 /C 选项具有不同的取值)。

21.  断点相关操作

21.1  bc(清除断点)

    bc 命令将从系统中永久移除此前设置的断点。

bc Breakpoints

Breakpoints——指定要移除的断点 ID 号。你可以指定任意数量的断点。多个 ID 之间必须用空格或逗号分隔。你可以使用连字符(-)来指定一段断点 ID 范围。你可以使用星号(*)来代表所有断点。如果希望使用数值表达式作为 ID,请将其括在方括号([])内。如果希望使用包含通配符的字符串来匹配断点的符号名称,请将其括在双引号(" ")内。

21.2  bc(禁用设定的断点)

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

bd Breakpoints

Breakpoints——指定要禁用的断点 ID。你可以指定任意数量的断点。多个 ID 之间必须用空格或逗号分隔。你可以使用连字符(-)指定一段断点 ID 范围。您可以使用星号(*)来表示所有断点。如果希望使用数值表达式作为 ID,请将其括在方括号([])中。如果希望使用包含通配符的字符串来匹配断点的符号名称,请将其括在双引号("")中。

21.3  bl(列出断点)

bl 命令列出有关现有断点的信息。

bl [/L] [Breakpoints]

/L——强制 bl 始终显示断点地址,而非显示源文件和行号。

Breakpoints——指定要列出的断点 ID 号。如果省略 Breakpoints 参数,调试器将列出所有断点。你可以指定任意数量的断点。多个 ID 之间必须用空格或逗号分隔。你可以使用连字符(-)来指定一段断点 ID 范围。您可以使用星号(*)来表示所有断点。如果你希望使用数值表达式作为 ID,请将其括在方括号([])内。如果你希望使用包含通配符的字符串来匹配断点的符号名称,请将其括在双引号("")内。

21.4  bp,bu,bm(设置断点)

    bp、bu 和 bm 命令用于设置一个或多个软件断点。你可以组合位置、条件和选项来设置不同类型的软件断点。

用户模式:

[~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"]

21.5  br(断点重编号)

21.6  bs(更新断点命令)

21.7  bsc(更新条件断点)

22.  c(比较内存)

23.  d, da, db, dc, dd, dD, df, dp, dq, du, dw (显示内存)

d* 命令显示给定范围内的内存内容。

d{a|b|c|d|D|f|p|q|u|w|W} [Options] [Range]

dy{b|d} [Options] [Range]

d [Options] [Range]

24.  dda, ddp, ddu, dpa, dpp, dpu, dqa, dqp, dqu (显示引用内存)

    dda、ddp、ddu、dpa、dpp、dpu、dqa、dqp 和 dqu 命令显示指定位置的指针,解引用该指针,然后以各种格式显示结果位置的内存。

ddp [Options] [Range]

dqp [Options] [Range]

dpp [Options] [Range]

dda [Options] [Range]

dqa [Options] [Range]

dpa [Options] [Range]

ddu [Options] [Range]

dqu [Options] [Range]

dpu [Options] [Range]

25.  dds, dps, dqs  (显示字与符号)

dds、dps 和 dqs 命令显示给定范围内的内存内容。该内存被视为符号表中的一系列地址。相应的符号也会同时显示。

dds [Options] [Range]

dqs [Options] [Range]

dps [Options] [Range]

26.  dg  (显示选择子)

27.  dl  (显示链表)

28.  ds ,dS  (显示串)

29.  dt  (显示类型)

30.  dtx  (显示类型——扩展调试器对象模型信息)

31.  dv  (显示局部变量)

32.  e, ea, eb, ed, eD, ef, ep, eq, eu, ew, eza  (键入值)

*e* 命令会将你指定的值输入到内存中。

e{b|d|D|f|p|q|w} Address [Values]

e{a|u|za|zu} Address "String"

e Address [Values]

仅限内核模式——物理地址

/p {[c]|[uc]|[wc]}

33.  f,fp  (填充内存)

34.  g  (继续调试)

    g 命令会启动指定的进程或线程。程序执行会在程序结束时、遇到 BreakAddress 中断时或因其他事件导致调试器停止时停止。

35.  gh  (异常处理完毕继续调试)

    gh 命令将给定线程的异常标记为已处理,并允许线程从导致异常的指令处重新开始执行。

36.  gn,gN  (异常未处理完毕继续调试)

37.  gu(Go Up) (运行到当前函数执行完毕)

    gu 命令使目标程序执行,直到当前函数执行完毕。

38.  ib, iw, id  (从端口输入)

ib、iw 和 id 命令从选定的端口读取并显示一个字节(byte)、一个字(word)或双字(double word)。

39.  ib, iw, id  (从端口输入)

ib、iw 和 id 命令从选定的端口读取并显示一个字节、一个字或双字。

ib Address

iw Address

id Address

40.  j  (执行 If-Else 语句)

j 命令根据给定表达式的计算结果,有条件地执行指定的命令之一。

j Expression Command1 ; Command2

j Expression 'Command1' ; 'Command2'

41.  k, kb, kc, kd, kp, kP, kv  (显示栈回溯)

k* 命令显示给定线程的栈帧及其相关信息。

(1) 用户模式,X86 处理器

[~Thread] k[b|p|P|v] [c] [n] [f] [L] [M] [FrameCount]

[~Thread] k[b|p|P|v] [c] [n] [f] [L] [M] = BasePtr [FrameCount]

[~Thread] k[b|p|P|v] [c] [n] [f] [L] [M] = BasePtr StackPtr InstructionPtr

[~Thread] kd [WordCount]

(2) 内核模式,X86 处理器

[Processor] k[b|p|P|v] [c] [n] [f] [L] [M] [FrameCount]

[Processor] k[b|p|P|v] [c] [n] [f] [L] [M] = StackPtr FrameCount

[Processor] k[b|p|P|v] [c] [n] [f] [L] [M] = BasePtr StackPtr InstructionPtr

[Processor] kd [WordCount]

(3) 用户模式,X64 处理器

[~Thread] k[b|p|P|v] [c] [n] [f] [L] [M] [FrameCount]

[~Thread] k[b|p|P|v] [c] [n] [f] [L] [M] = StackPtr FrameCount

[~Thread] k[b|p|P|v] [c] [n] [f] [L] [M] = StackPtr InstructionPtr FrameCount

[~Thread] kd [WordCount]

(4) 内核模式,X64 处理器

[Processor] k[b|p|P|v] [c] [n] [f] [L] [M] [FrameCount]

[Processor] k[b|p|P|v] [c] [n] [f] [L] [M] = StackPtr FrameCount

[Processor] k[b|p|P|v] [c] [n] [f] [L] [M] = StackPtr InstructionPtr FrameCount

[Processor] kd [WordCount]

(5) 用户模式,ARM 处理器

[~Thread] k[b|p|P|v] [c] [n] [f] [L] [M] [FrameCount]

[~Thread] k[b|p|P|v] [c] [n] [f] [L] [M] = StackPtr FrameCount

[~Thread] k[b|p|P|v] [c] [n] [f] [L] [M] = StackPtr InstructionPtr FrameCount

[~Thread] kd [WordCount]

(6) 内核模式,ARM 处理器

[Processor] k[b|p|P|v] [c] [n] [f] [L] [M] [FrameCount]

[Processor] k[b|p|P|v] [c] [n] [f] [L] [M] = StackPtr FrameCount

[Processor] k[b|p|P|v] [c] [n] [f] [L] [M] = StackPtr InstructionPtr FrameCount

[Processor] kd [WordCount]

42.  l+,l- (设置源选项)

l+ 和 l- 命令设置源行选项,用于控制源显示和程序步进选项。

l+Option

l-Option

l{+|-}

43.  ld (加载调试符号文件)

ld 命令加载指定模块的符号并更新所有模块信息。

ld ModuleName [/f FileName]

44.  lm (列出加载模块)

lm 命令显示已加载的指定模块。输出结果包括模块的状态和路径。

lm Options [a Address] [m Pattern | M Pattern]

45.  ln (列出最近的调试符号)

ln 命令显示给定地址或附近地址的符号。

ln Address

ln /D Address

46.  ls,lsa (列出源行)

ls 和 lsa 命令显示当前源文件中的一系列行并前进当前源行号。

47.  lsc (列出当前源行)

lsc 命令显示当前源文件名和行号。

48.  lsc (列出当前源行)

lsc 命令显示当前源文件名和行号。

49.  lse (启动源编辑器)

lse 命令会打开当前源文件的编辑器。

50.  lsf,lsf- (加载或卸载源文件)

lsf  和  lsf-  命令用于加载或卸载源文件。

lsf Filename

lsf- Filename

51.  lsp (设置源行数)

lsp 命令控制在单步执行代码或使用 ls 和 lsa 命令时显示的源代码行数。

lsp [-a] LeadingLines TrailingLines

lsp [-a] TotalLines

lsp [-a]

52.  m (移动内存)

m 命令用于将内存中的内容从一个位置复制到另一个位置。请勿将此命令与 ~m(恢复线程)命令混淆。

m  Range  Address

53.  n (设置数基)

n 命令将默认进制(基数)设置为指定的值,或者显示当前的进制。不要将此命令与 ~n(暂停线程)命令混淆。

n [Radix]

54.  ob, ow, od (输出至端口)

ob、ow 和 od 命令分别向选定的端口发送一个字节、一个字或双字。

ob   Address Value

ow Address    Value

od   Address    Value

55.  步进命令

55.1  p(步进)

p 命令执行单条指令或单行代码,并可选择性地显示所有寄存器和标志位的执行结果值。当发生子程序调用或中断时,它们被视为一个单独的步骤。

(1)  用户模式

[~Thread] p[r] [= StartAddress] [Count] ["Command"]

(2)  内核模式

p[r] [= StartAddress] [Count] ["Command"]

55.2  pa(步进到地址)

         pa 命令执行程序,直到到达指定的地址,并显示每一个步骤。

(1)  用户模式

[~Thread] pa [r] [= StartAddress] StopAddress ["Command"]

(2)  内核模式

pa [r] [= StartAddress] StopAddress ["Command"]

55.3  pc(步进到下一个调用)

         pc 命令会执行程序,直到遇到调用指令为止。

(1)  用户模式

[~Thread] pc [r] [= StartAddress] [Count]

(2)  内核模式

pc [r] [= StartAddress] [Count]

55.4  pct(步进到下一个调用或返回)

pct 命令执行程序,直到到达调用指令或返回指令。

(1)  用户模式

[~Thread] pct [r] [= StartAddress] [Count]

(2)  内核模式

pct [r] [= StartAddress] [Count]

55.5  ph(步进到下一个分支指令)

ph 命令执行程序,直到遇到任何类型的分支指令,包括条件分支或无条件分支、调用、返回和系统调用。

(1)  用户模式

[~Thread] ph [r] [= StartAddress] [Count]

(2)  内核模式

ph [r] [= StartAddress] [Count]

55.6  pt(步进到下一个返回)

         pt 命令会执行程序,直到遇到返回指令为止。

(1)  用户模式

[~Thread] pt [r] [= StartAddress] [Count] ["Command"]

(2)  内核模式

pt [r] [= StartAddress] [Count] ["Command"]

56.  停止命令

56.1  q,qq(停止)

         q 和 qq 命令用于结束调试会话。(在 CDB 和 KD 中,此命令还会退出调试器本身。在 WinDbg 中,此命令会将调试器返回到休眠模式。)

q

qq

56.2  qd(停止并分离)

qd 命令会结束调试会话,但不会终止任何用户模式下的目标应用程序。(在 CDB 和 KD 中,此命令还会退出调试器本身。在 WinDbg 中,此命令会将调试器返回到休眠模式。)

57.  寄存器相关操作

57.1  r(register)(寄存器操作)

    r 命令显示或修改寄存器、浮点寄存器、标志、伪寄存器和固定名称别名。

(1)  用户模式

[~Thread] r[M Mask|F|X|?] [ Register[:[Num]Type] [= [Value]] ]

r.

(2)  内核模式

[Processor] r[M Mask|F|X|Y|YI|?] [ Register[:[Num]Type] [= [Value]] ]

r.

57.2  rdmsr(Read MSR)(读MSR寄存器)

    rdmsr 命令从指定的地址读取具体模型寄存器 (MSR——Model-Specific Register) 值。

rdmsr Address

57.3  rm(Register Mask)(寄存器掩码)

    rm 命令用于修改或显示寄存器显示掩码。该掩码控制 r(寄存器)命令如何显示寄存器。

rm

rm ?

rm Mask

58.  s(搜索内存)

s 命令会在内存中搜索特定的字节模式。请勿将此命令与 ~s(更改当前处理器)、~s(设置当前线程)、|s(设置当前进程)或 ||s(设置当前系统)命令混淆。

s [-[[Flags]Type]] Range Pattern

s -[[Flags]]v Range Object

s -[[Flags]]sa Range

s -[[Flags]]su Range

59.  so(设置内核调试选项)

    so 命令用于设置或显示内核调试选项。

so [Options]

选项可以是下一个或多个选项:

NOEXTWARNING——当调试器找不到扩展命令时,不发出警告。

NOVERSIONCHECK——不检查调试器扩展 DLL 的版本。

如果省略选项,则会显示当前选项。

60.  sq(设置停止模式)

    sq 命令用于开启或关闭停止模式。

sq

sq{e|d}

61.  sq(设置符号后缀)

    ss 命令设置或显示用于数值表达式中符号匹配的当前后缀值。

ss [a|w|n]

62.  sx, sxd, sxe, sxi, sxn, sxr, sx- (设置异常)

sx 命令控制调试器在被调试的应用程序中发生异常或发生某些事件时所采取的操作。

sx

sx{e|d|i|n} [-c "Cmd1"] [-c2 "Cmd2"] [-h] {Exception|Event|*}

sx- [-c "Cmd1"] [-c2 "Cmd2"] {Exception|Event|*}

sxr

63.  跟踪相关命令

63.1  t(trace)(跟踪)

t 命令执行单条指令或一行源代码,并可选择显示所有寄存器和标志位的执行结果值。当发生子程序调用或中断时,还会跟踪其每一步的执行过程。

(1)  用户模式

[~Thread] t [r] [= StartAddress] [Count] ["Command"]

(2)  内核模式

t [r] [= StartAddress] [Count] ["Command"]

63.2  ta (跟踪到地址)

         ta 命令执行程序直到到达指定地址,并显示每个步骤(包括调用函数内的步骤)。

(1)  用户模式

[~Thread] ta [r] [= StartAddress] StopAddress

(2)  内核模式

ta [r] [= StartAddress] StopAddress

63.3  tb (跟踪到下一个分支(Branch))

         tb 命令会执行程序,直到遇到分支指令为止。

tb [r] [= StartAddress] [Count]

63.4  tc (跟踪到下一个调用)

         tc 命令会执行程序,直到遇到调用指令为止。

(1)  用户模式

[~Thread] tc [r] [= StartAddress] [Count]

(2)  内核模式

tc [r] [= StartAddress] [Count]

63.5  tct (跟踪到下一个调用或返回)

         tct 命令会执行程序,直到遇到 call 指令或 return 指令为止。

(1)  用户模式

[~Thread] tct [r] [= StartAddress] [Count]

(2)  内核模式

tct [r] [= StartAddress] [Count]

63.6  th (跟踪到下一个分支指令)

th 命令执行程序,直到遇到任何类型的分支指令,包括条件分支或无条件分支、调用、返回和系统调用。

(1)  用户模式

[~Thread] th [r] [= StartAddress] [Count]

(2)  内核模式

th [r] [= StartAddress] [Count]

63.7  tt (跟踪到下一个返回)

(1)  用户模式

[~Thread] tt [r] [= StartAddress] [Count]

(2)  内核模式

tt [r] [= StartAddress] [Count]

64.  反汇编相关命令

64.1  u, ub, uu (反汇编)

u* 命令会显示内存中指定程序二进制的反汇编结果。请勿将此命令与 ~u(解冻线程)命令混淆。

u[u|b] Range

u[u|b] Address

u[u|b]

64.2  uf (反汇编函数)

         uf 命令显示内存中指定函数的反汇编代码。

uf [Options] Address

选项可能是下列一个或多个选项:

/c ——仅显示例程中的调用指令,而非完整的反汇编代码。调用指令有助于从反汇编代码中确定调用者和被调用者之间的关系。

/D —— 创建链接的被调用者名称,以便浏览调用图。

/m —— 放宽阻塞要求,允许多个退出点。

/o —— 按地址而非函数偏移量对显示内容进行排序。此选项以内存布局视图呈现完整函数。

/O —— 创建链接的调用行,以便访问调用信息和创建断点。

/i —— 显示例程中的指令数。

64.3  up(unassemble physical) (从物理内存反汇编)

         up 命令显示物理内存中指定程序二进制代码的汇编翻译。

up Range

up Address

up

64.4  ur(unassemble real mode BIOS) (反汇编实模式BIOS)

    ur 命令显示指定的 16 位实模式代码的汇编翻译。

ur Range

ur Address

ur

64.5  ux(unassemble x86 BIOS) (反汇编x86 BIOS)

         ux 命令显示基于 x86 的 BIOS 代码的指令集。

ux [Address]

65.  vercommand(显示调试器命令行)

         vercommand 命令显示打开调试器的命令

vercommand

66.  version(显示调试器版本)

version 命令显示调试器和所有已加载的扩展 DLL 的版本信息。此命令还会显示目标计算机的当前操作系统版本。

         请勿将此命令与 !version(显示 DLL 版本)扩展命令混淆。

67.  vertarget(显示目标计算机版本)

         vertarget 命令显示目标计算机当前 Microsoft Windows 操作系统的版本。

68.  vertarget(显示目标计算机版本)

vertarget

69.  wrmsr(写MSR)

         wrmsr  命令将一个值写入指定地址的模型特定寄存器(MSR)。

wrmsr Address Value

70.  wt(Trace and Watch Data)(跟踪并观察数据)

wt 命令会在函数调用开始时执行,它会遍历整个函数并显示统计信息。

wt [WatchOptions] [= StartAddress] [EndAddress]

71.  x(Examine Symbols)(检查符号)

         x 命令显示与指定模式匹配的所有上下文中的调试符号。

x [Options] Module!Symbol

x [Options] *

72.  z(Execution While)(条件执行)

         z 命令会在给定条件为真时执行命令。

(1)  用户模式

Command ; z( Expression )

(2)  内核模式

Command ; [Processor] z( Expression )

内容概要:本文提出了一种基于神经网络的数据驱动迭代学习控制(ILC)算法,专门用于解决具有未知动态模型和重复任务特征的非线性单输入单输出(SISO)离散时间系统在无人车路径跟踪中的应用问题,并通过Matlab代码实现了算法的仿真验证。该方法充分利用神经网络强大的非线性逼近能力和自适应学习特性,结合迭代学习控制在周期性任务中逐步优化控制输入的优势,即使在缺乏精确系统数学模型的前提下,也能有效提升无人车在复杂环境下的路径跟踪精度与系统稳定性。算法的核心在于通过多次运行过程中不断修正控制律,实现对期望轨迹的渐近跟踪。; 适合人群:具备一定现代控制理论基础知识、熟悉迭代学习控制基本概念,并拥有Matlab编程与仿真实践经验的研究生、科研人员及自动化、机器人领域的相关工程师。; 使用场景及目标:① 解决无人车在模型未知或难以精确建模的复杂动态环境中的高精度路径跟踪控制问题;② 为一类具有重复运行特性的非线性系统提供一种不依赖精确模型的先进控制策略;③ 推动数据驱动与人工智能方法在自动化控制领域的工程应用与学术研究发展。; 阅读建议:读者应重点理解神经网络在控制律中的设计与集成方式、迭代学习机制的具体实现流程,以及两者融合的创新点。务必结合所提供的Matlab代码进行详细的阅读、调试与仿真分析,通过改变参数和工况来观察控制效果,以深化对算法内在机理和性能特点的掌握。
内容概要:本文档是一份面向参与大学生创新创业训练计划(大创项目)的在校学生的系统性指导资源,全面覆盖国家级与省级项目的申报、执行、中期检查、结题全流程。内容包括大创项目的政策解读、分类与级别说明、申报流程与时间点、评审标准解析,并提供创新训练、创业训练、创业实践三类项目的申报书撰写指南与范文。文档重点围绕物联网、数据分析、Web应用三大技术方向,提供可运行的完整项目实现案例,如基于ESP32的智慧农场系统、基于Python与Tableau的公交数据可视化平台、基于Spring Boot的校园协作平台,涵盖技术架构、代码实现、系统部署等细。此外,还包括答辩PPT制作技巧、中期检查与结题报告的撰写模板,以及各类工具与学习资源推荐,助力学生从项目构思到成果落地的全过程。; 适合人群:参与大创项目的在校本科生,尤其是计算机、数据科学、物联网等相关专业,具备一定编程基础和科研兴趣的学生。; 使用场景及目标:①指导学生高效撰写符合评审要求的申报书、答辩材料、中期报告与结题报告;②提供三大主流技术方向的完整项目范例,帮助学生快速搭建原型系统,提升技术实践能力;③辅助团队进行项目规划、进度管理与成果总结,确保项目顺利立项与结题。; 阅读建议:建议根据项目所处阶段选择性阅读对应,申报阶段重点学习第1-4,执行阶段参考第5-9的技术实现案例,结题阶段使用第6模板。应结合自身项目特点灵活应用范文与代码,避免照搬,注重原创性与可行性,并积极与指导教师沟通完善方案。
内容概要:本文围绕基于超局部模型的无模型预测电流控制(MFPCC)与自抗扰扩张状态观测器(ESO)相结合的改进型模型预测控制策略展开研究,提出了一种摆脱传统依赖精确电机数学模型限制的高性能控制方法。该方法通过构建超局部模型简化永磁同步电机(PMSM)的动态特性描述,并引入ESO实时估计系统内部参数扰动及外部负载干扰,实现对扰动的前馈补偿,从而显著提升控制系统的鲁棒性和动态性能。研究详细阐述了MFPCC的预测机制、ESO的设计原理及其在电流环中的集成方案,并借助Simulink搭建完整的仿真模型,对所提控制策略在动态响应速度、抗负载扰动能力及稳态控制精度等方面进行了全面的仿真验证,结果表明其相较于传统方法具有更优的综合性能。; 适合人群:具备自动控制理论基础、熟悉永磁同步电机驱动系统原理及Simulink/MATLAB仿真实践的电气工程、自动化、机电一体化等领域的研究生、科研人员和工程技术人员。; 使用场景及目标:①应用于对鲁棒性要求高的永磁同步电机高性能驱动系统设计;②为无模型控制、自抗扰控制(ADRC)等先进控制理论的教学与科研提供一个完整的、可复现的案例参考;③解决实际工程中因电机参数摄动、温度变化、负载突变等因素导致的模型失配与控制性能下降问题。; 阅读建议:读者应结合提供的Simulink仿真模型,深入剖析MFPCC与ESO协同工作的内在机理,重点关注ESO带宽整定、预测步长选择等关键参数对系统性能的影响,并通过对比不同工况下的仿真结果,深刻理解该先进控制策略的设计思想与实际应用技巧。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值