控制程序执行
此部分说明在准备调试程序;执行程序;设置、显示以及删除断点;继续程序;单步执行程序;停止程序;以及杀掉程序时所需的命令和子命令。
准备程序以使用 adb 程序进行调试
使用 cc 命令将程序编译为诸如 adbsamp2 之类的文件(通过输入以下命令):
cc adbsamp2.c -o adbsamp2要启动调试会话,请输入:
adb adbsamp2C 语言不为程序生成语句标号。 因此,在使用调试程序时无法参阅各个 C 语言语句。 要有效地使用执行命令,必须熟悉 C 编译器生成的指令以及这些指令是如何与各个 C 语言语句关联的。 其中一项很有用的技术就是在使用 adb 程序前创建 C 程序的汇编语言列表。 然后,在使用调试程序时请参阅该列表。 要创建汇编语言列表,请使用 cc 命令的 -S 或 -qList 标志。
例如,要创建示例程序 adbsamp2.c 的汇编语言列表,请使用以下命令:
cc -S adbsamp2.c -o adbsamp2此命令创建包含程序的汇编语言列表的 adbsamp2.s 文件,并将该程序编译为可执行文件 adbsamp2。
运行程序
可使用 :r 或 :R 子命令执行程序。 命令格式为:
[ Address ] [,Count ] :r [Arguments ]
或
[ Address ] [,Count ] :R [Arguments ]
在此格式中,Address 参数给出开始运行程序的地址;Count 参数为停在断点处前将要跳过的断点数;而 Arguments 参数提供了命令行参数(如文件名和选项)以传递给程序。
如果不提供 Address 值,那么 adb 程序使用该程序的开始部分。 要从开始运行程序,请输入:
:r如果提供 Count 值,那么 adb 程序将忽略所有断点,直至遇到给定数。 例如:要跳过前 5 个命名断点,请使用命令:
,5:r如果提供了参数,请在每个参数之间至少使用一个空格进行分隔。 参数传递给程序的方法与系统 shell 将命令行参数传递给程序的方法相同。 可使用 shell 重定向符号。
:R 子命令在启动程序操作前通过 shell 传递命令参数。 可在参数中使用 shell 模式匹配字符引用多个文件或其他输入值。 shell 在将它们传递给程序前扩展了包含模式匹配字符的参数。 如果程序期望多个文件名,此功能是很有用的。 例如:以下命令在将参数 [a-z]* 传递给程序前先将它传递给 shell(在该 shell 中将其扩展为对应文件名的列表):
:R [a-z]*.s:r 和 :R 子命令在启动程序前除去所有寄存器的内容,并破坏当前堆栈。 此操作停止了程序(程序可能正在运行)的先前的任何副本。
设置断点
要在程序中设置断点,请使用 :b 子命令。 当程序到达指定地址时,断点停止操作。 然后将控制权返回给 adb 调试程序。 命令格式为:
[Address] [,Count ] :b [命令]
在此格式中,Address 参数必须为有效指令地址;Count 参数为断点导致程序停止前跳过断点的次数计数;Command 参数为在每次执行指令(无需考虑断点是否停止了该程序)时要执行的 adb 命令。 如果指定的命令集。 (句点) 到值 0 ,断点将导致停止。
设置断点以在程序中的特定位置(如函数的开头)停止程序执行,从而可查看寄存器和内存的内容。 例如:调试示例 adbsamp2 程序时,以下命令在名为 f 函数的开头设置断点:
.f :b断点设定在函数入口,且在创建函数的堆栈帧之前。
在被数次调用的函数内(在程序运作期间)或在对应于 for 或 while 语句的指令内使用带有计数的断点。 这种断点允许程序继续运行,直至给定函数或指令执行了指定的次数为止。 例如,以下命令在 f 函数在 adbsamp2 程序中被第二次调用时设置断点:
.f,2 :b在函数第二次运行前,断点不停止该函数。
显示断点
使用 $b 子命令显示每个当前定义断点的位置和计数。 此命令按地址以及指定给这些断点的所有计数或命令显示断点列表。 例如,以下命令在 adbsamp2 文件中设置 2 个断点,然后使用 $b 子命令显示那些断点:
.f+4:b
.f+8:b$v
$b
breakpoints
count brkpt command
1 .f+8 $v
1 .f+4当程序运行时,它会在它找到的第一个断点处停止,例如.f+4. 如果使用 :c 子命令继续执行,那么程序在下一个断点处再次停止并启动 $v 子命令。 命令和响应序列看似以下示例:
:r
adbsamp2:running
breakpoint .f+4: st r3,32(r1)
:c
adbsamp2:running
variables
b = 268435456
d = 236
e = 268435512
m = 264
breakpoint .f+8 l r15,32(r1)删除断点
要使用 :d 子命令从程序删除断点,请输入:
地址 :d
在此格式中,Address 参数给出将要删除的断点的地址。
例如,调试示例 adbsamp2 程序时,输入以下命令将在 f 函数开始处的断点删除:
.f:d继续程序执行
要使用 :c 子命令在程序被断点停止后继续执行该程序,请输入:
[地址 ] [,计数 ] :c [信号 ]
在此格式中,Address 参数给出指令(从此处开始继续运行)的地址;Count 参数给出要忽略的断点数;Signal 参数为将要发送到程序的信号数。
如果不提供 Address 参数,那么该程序在断点后的下一个指令处启动。 如果提供 Count 参数,那么 adb 调试程序忽略第一个 Count 断点。
如果使用“Interrupt”或“Quit”键停止该程序,那么会在重新启动时自动将此信号传递给该程序。 为了防止传递此信号,请按以下格式输入命令:
[地址] [,Count] :c 0
命令参数 0 防止信号被发送到子进程。
单步执行程序
使用 :s 子命令单步执行程序,或一次运行一个指令。 此命令发出指令,并将控制权返回给 adb 调试程序。 命令格式为:
[Aaddress ] [,Count ] :s [信号]
在此格式中,Address 参数给出想要执行的指令的地址,Count 参数为想要重复命令的次数。 如果当前没有子进程,那么将 ObjectFile 参数作为子进程运行。 在这种情况下,无法发送任何信号,并且将行的剩余部分作为子进程的参数对待。 如果不提供 Address 参数的值,那么 adb 程序使用当前地址。 如果提供 Count 参数,那么 adb 程序继续依次发出每个指令,直至运行 Count 参数指令。 单步执行时忽略了断点。 例如,以下命令发出了 main 函数中的前 5 个指令:
.main,5:s使用中断键和退出键来停止程序
使用中断键或退出键来随时停止运行程序。 按下这两个键中的任意一个停止当前程序,并将控制权返回给 adb 程序。 这些键对存在无限循环或其他程序错误的程序是有用的。
当按下“Interrupt”或“Quit”键停止程序时,adb 程序将自动保存信号。 如果使用 :c 命令再次启动程序,那么 adb 程序自动将信号发送到程序。 当测试将这些信号作为其处理的一部分使用的程序时,此功能很有用。 要想在不发送信号的情况下继续运行,请使用命令:
:c 0命令参数 0(零)防止信号被发送到程序。
停止程序
要停止正在调试的程序,请使用 :k 子命令。 此命令停止为程序创建的进程,并将控制权返回给 adb 调试程序。 此命令清除系统部件寄存器和堆栈的当前内容,并再次开始该程序。 以下示例显示了 :k 子命令的用法以从 adb 程序清除当前进程:
:k 560: killed