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停止的原因,g和G命令用于寄存器访问,m和M命令用于内存访问。对于单线程目标要实现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章节