如何使用GDB
下面是一些有用的GDB命令,可以帮助我们调试程序。这假设您已将程序闪存
到微控制器上,并将GDB连接到cargo-embed
会话。
常规调试
注意:您在下面看到的许多命令可以使用简短的形式执行。例如,
continue
可以简单地用作c
, 或break $location
可以用作b $location
。一旦你对下面的命令有了经验,试着看看在GDB无法识别它们之前你可以让这些命令运行多短!
处理断点
break $location
:在代码中的某个位置设置断点。$location
的值可以包括:break *main
- 函数main
的确切地址上的breakbreak *0x080012f2
- 在准确的内存位置0x080012f2
上中断break 123
- 在当前显示文件的第123行中断break main.rs:123
- 在文件main.rs
的第123行中断
info break
: 显示当前断点delete
: 删除所有断点delete $n
: 删除断点$n
(n
是一个数字。例如:delete $2
)
clear
: 删除下一条指令的断点clear main.rs:$function
: 删除main.rs
中$function
条目处的断点clear main.rs:123
: 删除main.rs
第123行上的断点
enable
: 启用所有设置的断点enable $n
: 启用断点$n
disable
: 禁用所有设置的断点disable $n
: 禁用断点$n
控制执行
continue
: 开始或继续执行程序next
: 执行程序的下一行next $n
: 重复next
$n
多次
nexti
: 与next
相同,但使用机器指令step
: 执行下一行,如果下一行包含对另一个函数的调用,则进入该代码step $n
: 重复step
$n
多次
stepi
: 与step
相同,但使用机器指令jump $location
: 在指定位置继续执行:jump 123
: 在第123行继续执行jump 0x080012f2
: 在地址0x08001f2恢复执行
打印信息
print /$f $data
- 打印变量$data
包含的值。可选地,使用$f
格式化输出,包括:x: 十六进制 d: 有符号十进制 u: 无符号十进制 o: 八进制 t: 二进制 a: 地址 c: 字符 f: 浮点
print /t 0xA
: 将十六进制值0xA
打印为二进制(0b1010)
x /$n$u$f $address
: 检查$address
处的内存。可选,$n
定义要显示的单位数,$u
单位大小(字节、半字、字等),$f
以上定义任何的print
格式x /5i 0x080012c4
: 打印5条机器指令,起始地址为0x080012c4
x/4xb $pc
: 从$pc
当前指向的位置开始打印4字节内存
disassemble $location
disassemble /r main
: 反汇编函数main
,使用/r
显示组成每个指令的字节
查看符号表
info functions $regex
: 打印与$regex
匹配的函数的名称和数据类型,省略$regex
以打印所有函数info functions main
: 打印包含单词main
的已定义函数的名称和类型
info address $symbol
: 打印$symbol
存储在内存中的位置info address GPIOC
: 打印变量GPIOC
的内存地址
info variables $regex
: 打印与$regex
匹配的全局变量的名称和类型,省略$regex
打印所有全局变量ptype $data
: 打印有关$data
的更多详细信息ptype cp
: 打印变量cp
的详细类型信息
浏览程序堆栈
backtrace $n
: 打印$n
帧的跟踪,或省略$n
以打印所有帧backtrace 2
: 前2帧的打印跟踪
frame $n
: 选择编号或地址为$n
的帧,忽略$n
以显示当前帧up $n
: 选择帧$n
帧向上down $n
: S选择帧$n
帧向下info frame $address
: 在$address
处描述帧,忽略当前选定帧的$address
info args
: 打印所选帧的参数info registers $r
: 打印选定帧中寄存器$r
的值,忽略所有寄存器$r
info registers $sp
: 打印当前帧中堆栈指针寄存器$sp
的值
cargo-embed
远程控制
monitor reset
: 重置CPU,重新开始执行