一直执行到出现指定的状态为止
有多种方法可导致目标执行,直到达到指定状态。
使用断点控制执行
一种方法是使用断点。 当程序计数器到达指定地址时,最简单的断点将停止执行。 更复杂的断点可以:
仅在特定线程执行此地址时触发,
在触发之前,允许指定数量的传递通过此地址,
触发时自动发出指定的命令,或者
watch非可执行内存中的指定地址,在读取或写入该内存时触发。
有关如何设置和控制断点的详细信息,请参阅 使用断点。
在达到指定状态之前,一种更复杂的执行方法是使用 条件断点。 此类断点在某个地址设置,但仅当指定条件成立时才会触发。 有关详细信息,请参阅 设置条件断点。
断点和 Pseudo-Registers
在指定所需状态时,使用 自动伪寄存器通常很有帮助。 这些变量由调试器控制,可用于引用与目标状态相关的各种值。
例如,以下断点使用 伪寄存器$thread ,该寄存器始终等于当前线程的值。 在命令中使用时,它解析为当前线程的值。 通过将 $thread 用作 bp (set Breakpoint) 命令的 /t 参数的参数,可以创建每次由发出 bp 命令时处于活动状态的线程调用 NtOpenFile 时触发的断点:
kd> bp /t @$thread nt!ntopenfile
当任何其他线程调用 NtOpenFile 时,不会触发此断点。
有关自动伪寄存器的列表,请参阅 伪寄存器语法。
使用脚本文件控制执行
在达到指定状态之前执行的另一种方法是创建一个以递归方式调用自身的脚本文件,并在每次迭代中测试所需状态。
通常,此脚本文件将包含 .if 和 .else 标记。 可以使用 t (Trace) 等命令执行单个步骤,然后测试有问题的条件。
例如,如果要在 eax 寄存器包含值0x1234之前执行,则可以创建包含以下行的名为 eaxstep 的脚本文件:
.if (@eax == 1234) { .echo 1234 } .else { t "$<eaxstep" }
然后从“调试器命令”窗口发出以下命令:
t "$<eaxstep"
此 t 命令将执行单个步骤,然后执行带引号的命令。 此命令恰好是 $< (运行脚本文件) 运行 eaxstep 文件。 脚本文件测试 eax 的值,运行 t 命令,然后以递归方式调用自身。 这会一直持续到 eax 寄存器等于0x1234,此时 .echo (Echo Comment) 命令将消息输出到调试器命令窗口,并停止执行。
有关脚本文件的详细信息,请参阅使用脚本文件和使用调试器命令程序。
不明确的断点解析
在版本 10.0.25310.1001 及更高版本的调试器引擎中,现在支持不明确的断点解析。 不明确的断点允许调试器在某些断点表达式解析到多个位置的情况下设置断点。 有关详细信息,请参阅 不明确的断点解析。