GDB简介

GDB(GNU Debugger)是 Linux/Unix 环境下最强大的调试工具之一,支持 本地调试 和 远程调试(如嵌入式设备、网络服务)。以下是 GDB 调试的完整指南,涵盖基础命令、调试场景和常见问题解决。


一、GDB 基础调试流程

1. 编译时生成调试信息

使用 -g 选项编译程序,保留符号表和调试信息:

gcc -g main.c -o program

2. 启动 GDB

gdb ./program # 调试本地程序
gdb -q ./program # 静默模式(不显示版本信息)

3. 常用基础命令

命令作用示例
break <行号/函数>设置断点break 10 或 break main
run [args]启动程序(可带参数)run --input=test.txt
next / n单步执行(不进入函数)n
step / s单步执行(进入函数)s
continue / c继续运行到下一个断点c
print <变量>打印变量值print x
backtrace / bt查看函数调用栈bt
quit / q退出 GDBq

二、高级调试技巧

1. 条件断点

在特定条件下触发断点:



break 10 if x == 5 # 当 x=5 时在第 10 行暂停

2. 观察点(Watchpoint)

监控变量变化时暂停:

watch x # 当 x 的值被修改时暂停
rwatch x # 当 x 被读取时暂停

3. 调用栈操作

  • 查看调用栈:
    
    
    bt # 显示完整调用栈
    frame <编号> # 切换到指定栈帧(如 `frame 1`)
  • 返回上一帧:
    
    

    bash

    up # 向上移动栈帧
    down # 向下移动栈帧

4. 修改运行时的值

直接修改内存或变量值:

set var x = 10 # 修改变量 x 的值为 10
set {int}0x12345678 = 5 # 修改内存地址 0x12345678 的值为 5

5. 跳过代码执行

  • 跳转到指定行:
    
    
    jump 20 # 直接跳转到第 20 行(可能引发未定义行为)
  • 强制函数返回:
    finish # 执行完当前函数并返回
    return <值> # 提前返回并设置返回值(如 `return 0`)

三、GDB 远程调试

1. 网络调试(TCP/IP)

步骤 1:启动 gdbserver

在远程主机上运行:

gdbserver :2345 ./program # 监听所有网络接口的 2345 端口
# 或仅本地监听
gdbserver localhost:2345 ./program
步骤 2:本地 GDB 连接
gdb ./program
(gdb) target remote 192.168.1.100:2345 # 连接远程主机
常见问题
  • Connection refused:检查 gdbserver 是否运行,防火墙是否放行端口。
  • 路径映射错误:在 CLion 或 GDB 中设置本地/远程路径映射:
    (gdb) set sysroot /remote/path # 指定远程系统根目录

2. 串口调试(嵌入式设备)

步骤 1:连接串口

确认设备串口路径(如 /dev/ttyUSB0 或 COM3)。

步骤 2:启动 GDB 串口调试
gdb ./program
(gdb) target remote /dev/ttyUSB0 # Linux/macOS
(gdb) target remote COM3 # Windows
(gdb) set remotebaud 115200 # 设置波特率(必须匹配设备)
常见问题
  • 无权限访问串口
    sudo chmod 666 /dev/ttyUSB0 # Linux 临时授权
    sudo usermod -aG dialout $USER # 永久授权
  • 波特率不匹配:确保设备端和 GDB 的波特率一致(如 115200)。

四、GDB 脚本与自动化

1. 录制调试会话

(gdb) record # 开始录制
(gdb) reverse-next # 反向单步执行(需硬件支持)
(gdb) record stop # 停止录制

2. 使用 GDB 脚本

将命令保存到文件(如 debug.gdb):

break main
run
next 3
print x
quit

执行脚本:

gdb -x debug.gdb ./program

3. TUI 模式(文本用户界面)

启用分屏显示源代码和汇编:

gdb -tui ./program
# 或动态切换
(gdb) layout src # 显示源代码
(gdb) layout asm # 显示汇编

五、常见问题解决

Q1: 报错 No symbols loaded

  • 原因:程序未编译带调试信息(-g 选项缺失)。
  • 解决:重新编译并添加 -g
    gcc -g main.c -o program

Q2: 断点不生效

  • 原因:代码优化导致断点位置无效。
  • 解决:编译时关闭优化:
    gcc -g -O0 main.c -o program # -O0 禁用优化

Q3: 调试多线程程序

  • 查看所有线程:
    (gdb) info threads
  • 切换线程:
    (gdb) thread <ID> # 如 `thread 2`

Q4: 调试核心转储文件(Core Dump)

  1. 生成核心转储文件:
    ulimit -c unlimited # 允许生成核心文件
    ./program # 触发崩溃
  2. 用 GDB 分析:
    gdb ./program core
    (gdb) bt # 查看崩溃时的调用栈

六、总结

场景关键命令/操作
本地调试gdb ./program + break/run/print
网络远程调试gdbserver + target remote <IP:port>
串口调试target remote /dev/ttyUSB0 + set remotebaud
多线程调试info threads + thread <ID>
核心转储分析gdb ./program core + bt

掌握这些技巧后,你可以高效调试 C/C++ 程序、嵌入式设备或网络服务。遇到复杂问题时,结合 btinfo registers 和 x/10xw <地址>(查看内存)等命令进一步分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值