如何使用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条机器指令,起始地址为0x080012c4x/4xb $pc: 从$pc当前指向的位置开始打印4字节内存
disassemble $locationdisassemble /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处描述帧,忽略当前选定帧的$addressinfo args: 打印所选帧的参数info registers $r: 打印选定帧中寄存器$r的值,忽略所有寄存器$rinfo registers $sp: 打印当前帧中堆栈指针寄存器$sp的值
cargo-embed远程控制
monitor reset: 重置CPU,重新开始执行