GDB使用说明

GDB-常用命令

打开GDB调试开关命令:set debug remote 1

GDB-远程序列化协议

简介

所有GDB命令和响应都是以包(packet)形式进行送。一个包的基本结构:$包数据#2字节校验和

1
$packet-data#checksum

2字节校验和是计算$#之间的所有字符数值和,并取模256后的两位十六进制数。

GDB 5.0之前的协议需要包含两字节序列编号

1
$sequence-id:packet-data#checksum

当主机或目标机接收到第一个包,预期的一个响应是确认:可以是+(表明包接收正确)或-(请求重传)

1
2
-> $packet-data#checksum
<- +

连接一旦建立,可以禁用+/-确认。

主机(GDB)发送命令,而目标机(调试目标)发送响应。

包数据不能包含非法字符#$

若包数据中可以使用, ;:作为分隔符。除特别说明,所有数字均使用十六进制表示。

GDB 5.0之前的协议不能使用:作为分隔符(与sequence-id的分隔符冲突)。

在许多包中二进制数据都以两位十六进制字符表示。

二进制数据7d(ASCII字符})作为转义字符。任何转义字符传输时需要跟一个与0x20异或后的结果。例如,单字节0x7d在传输时会转为两个字节0x7d 0x5d。常见的转义字符有0x23 # 0x24 $ 0x7d } 0x2a *

响应数据可以使用运行长度编号来节省空间。例如:编号后'0* ' 表示编码字符串'0000'*后面的空格表示重复0字符32-29=3次。

对于可打印字符#$或数值超过126的都不可使用。对于7次重复(字符$)可以使用5次(字符")来分开表示。例如,'00000000'编码后为'0*"00'

对于不支持的命令,会返回空响应$#00

在最小场景中,目标机必须支持?命令来告诉GDB停止的原因,gG命令用于寄存器访问,mM命令用于内存访问。对于单线程目标要实现c命令,并支持单步调试命令s。多线程目标需要支持vCont命令。其他所有命令都是可选的。

下表中,命令中的空格表示语义分隔,但实际数据包不需要发送。

命令说明
!使能扩展模式
?当连接第一次建立后,会被询问目标机停止的原因。回复与step和continue一样。
A arglen,argnum,arg,…初始化argv[]参数数组传递给程序。其中arglen是十六进制编码后的字节流参数arg的长度。
b baud(不推荐使用)改变串行通信速率
B addr,mode(不推荐使用,使用Z和z包替代)设置(mode是S)或清除(mode是C)在addr处的断点。
bc向后继续执行。目标系统反向执行。
bs向后单步执行。反向执行一条执行。
c [addr]从addr处继续执行;addr省略时,从当前地址继续。
C sig[;addr]与c命令一样,额外可携带一个信号量sig(十六进制数)
d(不推荐使用)其他调试标志
D
D;pid
通知远端目标机GDB断开连接。第二种包含进程编号,只对特定的进程生效。
F RC,EE,CF;XX文件I/O扩展协议命令
g读取通用寄存器
回复:‘XX…’
寄存器每个字节由两个十六进制表示。当目标寄存器不可用时,会使用字符x进行占位。
G XX…写通用寄存器
z0,addr,kind
Z0,addr,kind
[;con_list…]
[;cmds:persis,cmd_list]
插入(Z0)或移除(z0)在addr处kind类型的一个软件断点
z1,addr,kind
Z1,addr,kind
[;con_list…]
[;cmds:persis,cmd_list]
插入(Z1)或移除(z1)在addr处kind类型的一个硬件断点
z2,addr,kind
Z2,addr,kind
插入(Z2)或移除(z2)在addr处的一个写监控点。监控的字节数由kind指定
z3,addr,kind
Z3,addr,kind
插入(Z3)或移除(z3)在addr处的一个读监控点。监控的字节数由kind指定
z4,addr,kind
Z4,addr,kind
插入(Z4)或移除(z4)在addr处的一个访问监控点。监控的字节数由kind指定

停止回复包

通用包

q开头的是通用询问包;以Q开头的是通用设置包;

参考

详见官方文档 Appendix E gdb Remote Serial Protocol章节