GDB调试工具

GDB调试工具

GDB(GNU Debugger)是Linux平台上最强大的调试工具。掌握GDB,能够大幅提高调试效率,快速定位程序bug。本文将系统讲解GDB的使用方法和实战技巧。

一、GDB基础

1.1 编译调试版本

使用-g选项编译程序:

bash 复制代码
gcc -g -O0 program.c -o program
  • -g:生成调试信息
  • -O0:关闭优化(O是字母O,数字0)

1.2 启动GDB

方式1:直接启动

bash 复制代码
gdb ./program

方式2:附加到运行中的进程

bash 复制代码
gdb attach <pid>

方式3:分析core文件

bash 复制代码
gdb ./program core

1.3 GDB基本命令

命令 简写 说明
run r 运行程序
break b 设置断点
next n 单步执行(不进入函数)
step s 单步执行(进入函数)
continue c 继续执行
print p 打印变量值
list l 显示源代码
quit q 退出GDB

二、断点管理

2.1 设置断点

bash 复制代码
# 在函数处设置断点
(gdb) break main
(gdb) b my_function

# 在指定行设置断点
(gdb) break 20
(gdb) break file.c:20

# 条件断点
(gdb) break 20 if i == 5
(gdb) b main.c:30 if x > 10

# 查看断点信息
(gdb) info break
(gdb) i b

# 删除断点
(gdb) delete 1       # 删除1号断点
(gdb) d 1-5          # 删除1到5号断点

# 禁用/启用断点
(gdb) disable 1
(gdb) enable 1

2.2 观察点(Watchpoint)

bash 复制代码
# 监视变量变化
(gdb) watch x        # x值改变时停止
(gdb) rwatch x       # x被读取时停止
(gdb) awatch x       # x被读取或写入时停止

# 查看观察点
(gdb) info watch

三、程序控制

3.1 执行控制

bash 复制代码
# 运行程序
(gdb) run
(gdb) r arg1 arg2    # 带参数运行

# 单步执行
(gdb) next           # 下一步(不进入函数)
(gdb) n
(gdb) step           # 下一步(进入函数)
(gdb) s

# 继续执行
(gdb) continue       # 运行到下一个断点
(gdb) c

# 执行到指定位置
(gdb) until 30       # 执行到第30行
(gdb) u 30

# 跳出当前函数
(gdb) finish

# 执行到函数末尾
(gdb) return         # 立即返回
(gdb) return 100     # 返回指定值

3.2 查看源代码

bash 复制代码
# 显示源代码
(gdb) list
(gdb) l

# 显示指定范围
(gdb) list 10,20

# 显示指定函数
(gdb) list main

# 显示其他文件
(gdb) list file.c:main

四、变量检查

4.1 打印变量

bash 复制代码
# 打印变量值
(gdb) print x
(gdb) p/x x          # 十六进制
(gdb) p/d x          # 十进制
(gdb) p/c x          # 字符

# 打印数组
(gdb) print arr[0]@10   # 打印arr的前10个元素
(gdb) p *arr@10

# 打印结构体
(gdb) print *ptr
(gdb) p ptr->member

# 打印字符串
(gdb) print str
(gdb) p/s str

# 打印内存
(gdb) x/10xw &var    # 查看var开始的10个字

4.2 显示类型

bash 复制代码
# 查看变量类型
(gdb) whatis x

# 查看详细类型
(gdb) ptype struct_name

4.3 自动显示

bash 复制代码
# 每次停止时自动显示
(gdb) display x
(gdb) display/i $pc    # 显示当前指令

# 查看display列表
(gdb) info display

# 删除display
(gdb) undisplay 1

五、栈帧管理

5.1 查看调用栈

bash 复制代码
# 显示调用栈
(gdb) backtrace
(gdb) bt
(gdb) bt 5            # 只显示5层

# 切换栈帧
(gdb) frame 2         # 切换到第2帧
(gdb) f 2

# 查看当前帧信息
(gdb) info frame
(gdb) info locals     # 查看局部变量
(gdb) info args       # 查看函数参数

六、高级调试

6.1 多线程调试

bash 复制代码
# 查看所有线程
(gdb) info threads

# 切换线程
(gdb) thread 2

# 在所有线程设置断点
(gdb) set scheduler-locking on    # 只让当前线程运行
(gdb) set scheduler-locking off   # 所有线程运行

6.2 内存检查

bash 复制代码
# 检查内存泄漏(需要valgrind)
valgrind --leak-check=full ./program

# GDB内存检查
(gdb) x/20xw 0x7fffffffdc00    # 查看内存

6.3 Core文件分析

bash 复制代码
# 开启core文件生成
ulimit -c unlimited

# 程序崩溃后生成core文件
./program

# 分析core文件
gdb ./program core

# 在GDB中查看崩溃位置
(gdb) bt
(gdb) frame 0
(gdb) info locals

七、实用技巧

7.1 命令历史

bash 复制代码
# 查看历史命令
(gdb) show commands

# 使用历史命令
(gdb) !10             # 执行第10条历史命令

7.2 日志记录

bash 复制代码
# 开启日志
(gdb) set logging on
(gdb) set logging file gdb.log

7.3 自定义命令

gdb 复制代码
# 定义快捷命令
define plist
    set $node = $arg0
    while $node
        print *$node
        set $node = $node->next
    end
end

八、常见调试场景

8.1 段错误调试

bash 复制代码
# 方法1:使用core文件
ulimit -c unlimited
./program
gdb ./program core
(gdb) bt

# 方法2:直接运行
gdb ./program
(gdb) run
# 程序崩溃后
(gdb) bt
(gdb) frame 0

8.2 死循环定位

bash 复制代码
gdb ./program
(gdb) run
# 程序卡住时按Ctrl+C
(gdb) bt
(gdb) info locals

8.3 变量值异常

bash 复制代码
# 使用条件断点
(gdb) break 30 if x < 0
(gdb) run
# 触发断点后检查相关变量
(gdb) print x
(gdb) bt

九、总结

GDB是Linux调试的利器:

  1. 基本操作:run、break、next、step、continue
  2. 变量检查:print、display、whatis
  3. 栈管理:backtrace、frame
  4. 高级功能:多线程、core分析

调试技巧

  • 善用条件断点
  • 使用watch监视变量
  • 配合core文件定位崩溃
  • 多线程调试使用scheduler-locking
相关推荐
枳实-叶14 小时前
【Linux驱动开发】第一天:用户态与内核态通俗讲解+最简字符设备驱动实战
linux·驱动开发·学习
计算机安禾14 小时前
【Linux从入门到精通】第23篇:条件判断——让脚本拥有“大脑”
linux·运维·服务器
feng_you_ying_li14 小时前
linu之进程的程序替换与shell基本实现的基本版本
linux
念恒1230614 小时前
进程控制---进程程序替换
linux·c语言
小夏子_riotous15 小时前
Docker学习路径——10、Docker Compose 一站式编排:从入门到生产级部署
linux·运维·服务器·docker·容器·centos·云计算
zhangrelay15 小时前
三分钟云课实践速通--概率统计--python版
linux·开发语言·笔记·python·学习·ubuntu
云栖梦泽15 小时前
Linux内核与驱动:GPIO设备树与SPI设备树的区别
linux·运维·c++·嵌入式硬件
HalvmånEver15 小时前
MySQL表的查询(二)
linux·数据库·学习·mysql
断问天15 小时前
Faq:Fedora44 Kernel升级后WIFI和声卡都不能使用了
linux·运维·服务器
旧故新长15 小时前
部署自动发卡网站的问题和解决方案
linux·docker