Linux GDB 调试实战指南:从编译到断点调试

1. 引言

GDB 是 Linux 下最常用的调试工具,用于在程序运行时查看内部状态、定位崩溃原因、跟踪变量变化。

2. 准备工作:安装 GDB 与 CGDB

在开始调试前,需要先安装 GDB。如果希望获得更友好的交互界面,可以同时安装 CGDB(基于 GDB 的文本界面封装)。

bash 复制代码
sudo yum install -y gdb
sudo yum install -y cgdb

安装完成后,在终端输入 gdb --version 验证是否安装成功。

3. 编译调试版本:-g 选项

要让程序可以被 GDB 调试,编译时必须加上 -g 选项,否则无法进行源码级调试。该选项会在生成的可执行文件中加入调试信息,便于 GDB 定位源码行号和变量。

bash 复制代码
gcc mycode.c -o mycode -std=c99 -g

其中 -std=c99 指定使用 C99 标准,-g 表示生成调试信息。编译完成后,用 file mycode 可以查看可执行文件是否包含调试信息。

4. 启动 GDB 并查看代码

启动 GDB 并加载可执行文件:

bash 复制代码
gdb mycode

进入 GDB 交互界面后,常用命令如下:

  • list(或 l) :从第一行开始显示源码,默认每次显示 10 行。连续输入 l 会继续向下翻页。
  • run(或 r):运行当前程序,直到遇到断点或程序结束。
gdb 复制代码
(gdb) l
(gdb) r

5. 断点管理:打断点、查看、删除

断点是调试的核心,可以让程序在指定行暂停,方便观察变量状态。

  • b 行号 :在指定行设置断点,例如 b 12 在第 12 行打断点。
  • info b:查看当前所有断点,会显示断点编号、位置和状态。
  • d 断点编号 :删除指定编号的断点,例如 d 1 删除 1 号断点。
  • disable 断点编号:暂时取消某个断点的效能,但保留断点。
  • enable 断点编号:重新启用被禁用的断点。
gdb 复制代码
(gdb) b 12
(gdb) info b
(gdb) d 1
(gdb) disable 2
(gdb) enable 2

注意:如果本次调试会话不退出,断点编号会持续累加,不会因为删除而重新编号。

6. 单步执行:逐过程与逐语句

程序在断点处暂停后,可以使用以下命令逐步执行:

  • next(或 n,对应 F10):逐过程执行,遇到函数调用时一次性跳过,不进入函数内部。
  • step(或 s,对应 F11):逐语句执行,遇到函数调用时会进入函数内部继续调试。
gdb 复制代码
(gdb) n
(gdb) s

GDB 会自动执行最新一条指令,因此直接按回车可以重复上一条命令。

7. 查看变量与继续运行

程序暂停后,可以通过以下命令查看变量状态、继续运行或跳出当前函数:

  • p 变量名 :打印变量的当前值,例如 p i 查看变量 i 的值。
  • c:继续运行,直到遇到下一个断点或程序结束。
  • until 行号 :运行到指定行号后暂停,例如 until 20 运行到第 20 行。
  • finish:运行完当前函数并返回,适合在逐语句进入函数后快速跳出。
  • display 变量名 :每次暂停时自动打印指定变量的值,例如 display i。
  • undisplay 编号 :取消某个自动显示项,编号可通过 info display 查看。
  • info locals:展示当前函数内部所有临时变量的名称和值。
gdb 复制代码
(gdb) p i
(gdb) c
(gdb) until 20
(gdb) finish
(gdb) display i
(gdb) undisplay 1
(gdb) info locals

8. 实战示例:完整调试流程

下面用一个简单的 C 程序演示完整调试流程。假设文件 mycode.c 内容如下:

c 复制代码
#include <stdio.h>

int main() {
    int i;
    int sum = 0;
    for (i = 1; i <= 5; i++) {
        sum += i;
    }
    printf("sum = %d\n", sum);
    return 0;
}

调试步骤:

bash 复制代码
gcc mycode.c -o mycode -std=c99 -g
gdb mycode
gdb 复制代码
(gdb) l
(gdb) b 6
(gdb) r
(gdb) p i
(gdb) n
(gdb) p sum
(gdb) c
(gdb) quit

通过以上步骤,可以观察循环中变量 i 和 sum 的变化,验证程序逻辑是否正确。

9. 常用指令速查表

指令 作用
gcc -g 编译时添加调试信息
list / l 从第一行开始显示源码
run / r 运行程序
b 行号 在指定行打断点
info b 查看所有断点
d 断点编号 删除指定断点
disable / enable 取消 / 启用断点效能
next / n(F10) 逐过程执行
step / s(F11) 逐语句执行
p 变量名 打印变量值
c 运行到下一个断点
until 行号 运行到指定行
finish 运行完当前函数并返回
display / undisplay 设置 / 取消自动显示变量
info locals 展示当前函数内部临时变量
相关推荐
Lucis__1 小时前
深入理解程序链接与加载—从动静态链接到库加载
linux·elf·链接·程序·动静态库
傲世仙尊1 小时前
类和对象中-构造函数与析构函数把初始化清理自动化
java·运维·自动化
七月吃橘子1 小时前
WSL2+Docker+Ollama,本地部署大模型实践(Qwen1.8b)
运维·docker·容器
贵州诚鑫致达科技有限公司1 小时前
PVID 是什么?端口参数三身份
服务器·经验分享
影视飓风TIM1 小时前
Linux 进程信号原理与剖析
linux·运维·服务器
缘友一世2 小时前
开源 Linux截图工具闪构(SnapForge)
linux·运维·ubuntu·开源·截图
iCxhust2 小时前
先想好如何测试:让测试驱动你的程序设计
运维·服务器·软件工程·编程的艺术
Philtell2 小时前
突然连接不上内网服务器的问题
运维·服务器
做运维的阿瑞2 小时前
Docker常见故障全方位排查指南
运维·docker·云原生·容器