SuperAPI AI 工具集

gdb

编程与开发

查看项目

更新于 10-15 15:14

技能介绍

用途

本技能引导智能体完成 GDB 调试会话,从首次启动到高级工作流,涵盖崩溃诊断、反向调试、远程调试和多线程检查。

触发场景

  • 程序发生段错误或崩溃,需要调试
  • 需要在条件 X 上设置断点
  • 需要在 GDB 中检查内存或变量
  • 需要调试远程嵌入式目标
  • GDB 显示 ?? 帧或无源码
  • 需要确定性地重放 bug(记录/回放)

工作流

1. 前提:编译时带调试信息

始终使用 -g 编译(GCC/Clang)。大多数可调试代码使用 -Og 或 -O0。

gcc -g -Og -o prog main.c

发布构建:使用 -g -O2 并保留带符号的二进制文件(用 objcopy 单独剥离符号)。

2. 启动 GDB

gdb ./prog                          # 加载二进制文件
gdb ./prog core                     # 加载核心转储
gdb -p 12345                        # 附加到运行中的进程
gdb --args ./prog arg1 arg2         # 传递参数
gdb -batch -ex 'run' -ex 'bt' ./prog  # 非交互式(CI)

3. 基本命令

命令 快捷方式 效果
run [args] r 启动程序
continue c 断点后继续
next n 单步跳过(源码行)
step s 单步进入
nexti ni 单步跳过(指令)
stepi si 单步进入(指令)
finish 运行到当前函数结束
until N 运行到第 N 行
return [val] 强制从函数返回
quit q 退出 GDB

4. 断点和观察点

break main                          # 在函数处断点
break file.c:42                     # 在行处断点
break *0x400abc                     # 在地址处断点
break foo if x > 10                 # 条件断点
tbreak foo                          # 临时断点(触发一次)
rbreak ^mylib_.*                    # 对所有匹配函数使用正则断点

watch x                             # 观察点:x 变化时中断
watch *(int*)0x601060               # 观察内存地址
rwatch x                            # x 被读取时中断
awatch x                            # 读取或写入时中断

info breakpoints                    # 列出所有断点
delete 3                            # 删除断点 3
disable 3                           # 禁用而不删除
enable 3

5. 检查状态

print x                             # 打印变量
print/x x                           # 以十六进制打印
print *ptr                          # 解引用指针
print arr[0]@10                     # 打印数组的 10 个元素
display x                           # 每次停止时自动打印 x
undisplay 1

info locals                         # 所有局部变量
info args                           # 函数参数
info registers                      # 所有 CPU 寄存器
info registers rip rsp rbp          # 特定寄存器
x/10wx 0x7fff0000                   # 检查地址处的 10 个字
x/s 0x400abc                        # 以字符串形式检查
x/i $rip                            # 检查当前指令

backtrace                           # 调用栈(bt)
bt full                             # bt + 局部变量
frame 2                             # 切换到帧 2
up / down                           # 在栈中上移/下移

6. 多线程调试

info threads                        # 列出线程
thread 3                            # 切换到线程 3
thread apply all bt                 # 所有线程的回溯
thread apply all bt full            # 所有线程的完整回溯
set scheduler-locking on            # 单步时暂停其他线程

7. 反向调试(记录/回放)

记录需要 target record-full 或 target record-btrace(Intel PT):

# 软件记录(慢但通用)
record                              # 开始记录
run
# ... 触发 bug ...
reverse-continue                    # 回到上一个断点
reverse-next                        # 向后单步
reverse-step
reverse-finish

# Intel Processor Trace(快速,硬件)
target record-btrace pt
run
# 查看指令历史
record instruction-history

8. 使用 gdbserver 进行远程调试

在目标机上:

gdbserver :1234 ./prog
# 或附加:
gdbserver :1234 --attach 5678

在主机上:

gdb ./prog
(gdb) target remote 192.168.1.10:1234
(gdb) break main
(gdb) continue

交叉编译时:在主机上使用 aarch64-linux-gnu-gdb。

9. 常见问题

症状 原因 修复
无符号表 二进制文件未使用 -g 编译 使用 -g 重新编译
回溯中出现 ?? 帧 缺少调试信息或栈损坏 安装 debuginfo 包;检查栈溢出
无法访问地址处的内存 空指针解引用/已释放内存 解引用前检查指针;使用 ASan
回溯中出现 SIGABRT abort() 或断言失败 向上查看帧以找到断言
GDB 在运行时挂起 二进制文件等待输入 重定向 stdin:run < /dev/null
断点位置错误 优化器移动了代码 使用 -Og 编译;或使用 nexti

10. GDB 初始化文件(~/.gdbinit)

set history save on
set history size 1000
set print pretty on
set print array on
set print array-indexes on
set pagination off
set confirm off

命令速查表参见 references/cheatsheet.md。美化打印器和 Python 脚本参见 references/scripting.md。

相关技能

  • 使用 skills/debuggers/core-dumps 加载核心文件
  • 使用 skills/debuggers/lldb 进行基于 LLDB 的工作流
  • 使用 skills/runtimes/sanitizers 在需要调试器之前捕获 bug
  • 使用 skills/compilers/gcc 了解 -g 标志详情