gdb 是一个强大的调试器,让我详细介绍如何使用它调试你的程序:
基本调试步骤
1. 编译时启用调试信息
# 编译时添加 -g 参数
gcc -g -o exec source.c
# 或者
g++ -g -o exec source.cpp
# 如果使用 CMake,确保是 Debug 模式
cmake -DCMAKE_BUILD_TYPE=Debug -S . -B build
make -C build2. 启动 gdb 调试你的程序
# 方法1:启动 gdb 后设置参数
gdb ./exec
(gdb) set args -p p1 -p p2
(gdb) run
# 方法2:直接带参数启动
gdb --args ./exec -p p1 -p p2
(gdb) run
# 方法3:使用 run 命令时直接传参数
gdb ./exec
(gdb) run -p p1 -p p2常用 gdb 命令
括号内为命令缩写,日常调试中通常使用缩写形式。
基本控制命令
(gdb) run # 运行程序 (r)
(gdb) continue # 继续执行 (c)
(gdb) step # 单步执行(进入函数) (s)
(gdb) next # 单步执行(不进入函数) (n)
(gdb) finish # 执行到当前函数结束
(gdb) quit # 退出 gdb (q)断点相关
(gdb) break main # 在 main 函数设置断点 (b main)
(gdb) break 25 # 在第 25 行设置断点
(gdb) break file.c:100 # 在 file.c 的第 100 行设置断点
(gdb) break func_name # 在函数 func_name 设置断点
(gdb) info breakpoints # 查看所有断点 (info b)
(gdb) delete 1 # 删除断点 1 (d 1)
(gdb) disable 1 # 禁用断点 1
(gdb) enable 1 # 启用断点 1
(gdb) clear # 清除当前行的断点查看变量和内存
(gdb) print variable_name # 打印变量值 (p variable_name)
(gdb) print *pointer # 打印指针指向的值
(gdb) print array[0] # 打印数组元素
(gdb) display variable # 每次停止时都显示变量值
(gdb) info locals # 显示当前函数的局部变量
(gdb) info args # 显示当前函数的参数
(gdb) backtrace # 显示调用栈 (bt)
(gdb) frame 0 # 切换到栈帧 0 (f 0)
(gdb) list # 显示当前源代码 (l)
(gdb) list 20 # 显示第 20 行附近的代码实际调试示例
假设你要调试 ./exec -p p1 -p p2:
# 启动调试
gdb --args ./exec -p p1 -p p2
# 在 gdb 中执行
(gdb) break main # 在 main 函数设断点
(gdb) run # 开始运行
# 程序停在 main 函数
(gdb) list # 查看源代码
(gdb) print argc # 查看参数个数
(gdb) print argv[0] # 查看程序名
(gdb) print argv[1] # 查看第一个参数 "-p"
(gdb) print argv[2] # 查看第二个参数 "p1"
# 设置更多断点并继续
(gdb) break process_args # 假设有参数处理函数
(gdb) continue # 继续执行到下个断点
# 单步调试
(gdb) step # 单步执行
(gdb) next # 下一行
(gdb) print some_variable # 查看变量值高级用法
条件断点
在满足特定条件时才触发断点,可大幅减少不必要的中断。
(gdb) break 50 if x == 10 # 只有当 x==10 时才停下
(gdb) condition 1 y > 100 # 为断点 1 添加条件监视点
自动监控变量的读写操作,变量值发生变化时程序自动中断。
(gdb) watch variable_name # 当变量值改变时停下
(gdb) rwatch variable_name # 当变量被读取时停下
(gdb) awatch variable_name # 当变量被读取或写入时停下查看内存
使用 x 命令直接检查内存内容,支持十六进制、指令和字符串等多种显示格式。
(gdb) x/10i $pc # 查看当前指令
(gdb) x/10x address # 以十六进制查看内存
(gdb) x/s string_pointer # 查看字符串多线程调试
(gdb) info threads # 查看所有线程
(gdb) thread 2 # 切换到线程 2
(gdb) break function thread 2 # 在特定线程设断点调试技巧
1. 处理段错误
gdb ./exec
(gdb) run -p p1 -p p2
# 程序崩溃后
(gdb) backtrace # 查看崩溃位置
(gdb) frame 1 # 切换栈帧查看详细信息
(gdb) print *pointer # 查看可能的空指针2. 调试已运行的程序
# 获取进程 ID
ps aux | grep exec
# 附加到运行中的进程
gdb -p <process_id>3. 批量命令
创建 .gdbinit 文件或使用 -x 参数:
# 创建命令文件 debug.gdb
echo "break main" > debug.gdb
echo "run -p p1 -p p2" >> debug.gdb
echo "continue" >> debug.gdb
# 使用命令文件
gdb -x debug.gdb ./exec常见问题解决
没有调试信息
(gdb) info sources # 检查是否有源代码信息
# 如果没有,重新编译时加上 -g 参数优化影响调试
# 编译时禁用优化
gcc -g -O0 -o exec source.cTUI 模式(文本用户界面)
gdb -tui ./exec # 启动时开启 TUI
# 或在 gdb 中
(gdb) tui enable # 启用 TUI
(gdb) layout src # 显示源代码窗口
(gdb) layout asm # 显示汇编窗口