前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >一文搞懂 | C语言编程必备技能—GDB调试

一文搞懂 | C语言编程必备技能—GDB调试

作者头像
C语言中文社区
发布2025-06-24 10:35:25
发布2025-06-24 10:35:25
20100
代码可运行
举报
文章被收录于专栏:C语言中文社区C语言中文社区
运行总次数:0
代码可运行

正文

一、GDB 简介

GDB(GNU Debugger) 是一款开源调试工具,支持多种编程语言(如 C、C++、Python 等),主要用于在程序运行时检查其状态,包括变量值、内存布局、调用堆栈等。它可以帮助开发者定位逻辑错误、内存泄漏、段错误等问题。

1. 安装 GDB

Linux:大多数发行版自带 GDB,可通过包管理器安装:

代码语言:javascript
代码运行次数:0
运行
复制
sudo apt update
sudo apt install gdb

Windows:可以通过 MinGW 或 Cygwin 安装 GDB。

macOS:使用 Homebrew 安装:

代码语言:javascript
代码运行次数:0
运行
复制
brew install gdb

二、编译带有调试信息的程序

为了使用 GDB 调试,编译时需加入 -g 选项,保留调试信息(如变量名、源代码行号等)。

代码语言:javascript
代码运行次数:0
运行
复制
gcc -g program.c -o program

三、启动 GDB

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

代码语言:javascript
代码运行次数:0
运行
复制
gdb ./program

进入 GDB 交互界面后,可以输入命令进行调试。


四、基本调试命令

1. 查看源代码

  • list(或 l):显示当前代码。
  • list main:显示 main 函数附近的代码。
  • list 10:显示第 10 行附近的代码。

2. 设置断点

  • break main:在 main 函数入口设置断点。
  • break 20:在第 20 行设置断点。
  • break filename.c:line:在指定文件的指定行设置断点。

3. 运行程序

  • run(或 r):启动程序,遇到断点会暂停。

4. 单步执行

  • next(或 n):执行下一行代码,不进入函数内部
  • step(或 s):执行下一行代码,进入函数内部
  • finish:执行完当前函数并暂停。

5. 查看变量值

  • print x(或 p x):打印变量 x 的值。
  • print /x x:以十六进制打印变量 x
  • display x:每次暂停时自动显示 x 的值。

6. 修改变量值

  • set variable x = 10:在程序运行时修改变量 x 的值为 10。

7. 查看调用栈

  • backtrace(或 bt):显示当前调用栈,查看函数调用顺序。
  • frame n:切换到第 n 个栈帧(用于查看局部变量)。

8. 继续执行

  • continue(或 c):继续执行程序,直到遇到下一个断点或程序结束。

9. 退出 GDB

  • quit(或 q):退出 GDB。

五、进阶调试技巧

1. 条件断点

在特定条件下触发断点:

代码语言:javascript
代码运行次数:0
运行
复制
break 20 if x > 10

x > 10 时,程序会在第 20 行暂停。

2. 观察点(Watchpoints)

监控变量值的变化:

代码语言:javascript
代码运行次数:0
运行
复制
watch x

当变量 x 的值被修改时,程序会暂停。

3. 多线程调试

  • info threads:查看所有线程。
  • thread n:切换到第 n 个线程。
  • break foo thread 2:在线程 2 中设置断点。

4. 调试 Core 文件

当程序崩溃时,系统会生成 Core 文件(需提前设置允许生成 Core 文件):

代码语言:javascript
代码运行次数:0
运行
复制
ulimit -c unlimited

使用 GDB 分析 Core 文件:

代码语言:javascript
代码运行次数:0
运行
复制
gdb ./program core

在 GDB 中使用 bt 查看崩溃时的调用栈。

5. 反汇编调试

  • disassemble(或 dis):显示当前函数的汇编代码。
  • x/8xb &x:以十六进制查看变量 x 的内存布局。

6. 自动化调试脚本

编写 .gdbinit 文件,定义调试时自动执行的命令。例如:

代码语言:javascript
代码运行次数:0
运行
复制
# .gdbinit
break main
run

六、完整调试实例

1. 示例代码:swap.c

代码语言:javascript
代码运行次数:0
运行
复制
#include <stdio.h>

void swap(int *p1, int *p2) {
    int *p = p1;
    p1 = p2;
    p2 = p;
}

int main() {
    int a = 10, b = 20;
    printf("Before swap: a = %d, b = %d\n", a, b);
    swap(&a, &b);
    printf("After swap: a = %d, b = %d\n", a, b);
    return 0;
}

2. 编译程序

代码语言:javascript
代码运行次数:0
运行
复制
gcc -g swap.c -o swap

3. 启动 GDB 并调试

代码语言:javascript
代码运行次数:0
运行
复制
gdb ./swap

4. 调试步骤

查看源代码

代码语言:javascript
代码运行次数:0
运行
复制
(gdb) list

设置断点

代码语言:javascript
代码运行次数:0
运行
复制
(gdb) break main
(gdb) break swap

运行程序

代码语言:javascript
代码运行次数:0
运行
复制
(gdb) run

单步执行

代码语言:javascript
代码运行次数:0
运行
复制
(gdb) step

查看变量值

代码语言:javascript
代码运行次数:0
运行
复制
(gdb) print a
(gdb) print b

发现逻辑错误

  • swap 函数中,变量 p1p2 的值交换了,但 ab 的值未改变。
  • 修改代码为:void swap(int *p1, int *p2) { int tmp = *p1; *p1 = *p2; *p2 = tmp; }

重新编译并调试

代码语言:javascript
代码运行次数:0
运行
复制
gcc -g swap.c -o swap
gdb ./swap

七、调试常见问题

1. 程序崩溃

  • 原因:访问非法内存、空指针、数组越界等。
  • 解决方法
    • 使用 bt 查看崩溃时的调用栈。
    • 使用 watch 监控变量值变化。

2. 死循环

  • 原因:循环条件错误或逻辑缺陷。
  • 解决方法
    • 设置断点检查循环条件。
    • 使用 step 单步执行循环体。

3. 内存泄漏

  • 原因:未释放动态分配的内存。
  • 解决方法
    • 使用 Valgrind 检查内存泄漏。
    • 在 GDB 中使用 watch 监控内存分配与释放。

八、总结

GDB 是 Linux 环境下调试 C 程序的强大工具,掌握其基本命令和高级技巧可以显著提升调试效率。通过实践以下步骤,开发者可以快速定位并修复代码中的问题:

  1. 编译程序时加入 -g 参数
  2. 使用 break 设置断点
  3. 使用 run 启动程序
  4. 使用 stepnext 单步执行
  5. 使用 printwatch 监控变量
  6. 使用 bt 查看调用栈
  7. 分析 Core 文件解决崩溃问题

通过不断实践和探索 GDB 的高级功能(如条件断点、观察点、多线程调试),可以更高效地调试复杂程序,提升代码质量和开发效率。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-06-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 C语言中文社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 正文
    • 一、GDB 简介
      • 1. 安装 GDB
    • 二、编译带有调试信息的程序
    • 三、启动 GDB
    • 四、基本调试命令
      • 1. 查看源代码
      • 2. 设置断点
      • 3. 运行程序
      • 4. 单步执行
      • 5. 查看变量值
      • 6. 修改变量值
      • 7. 查看调用栈
      • 8. 继续执行
      • 9. 退出 GDB
    • 五、进阶调试技巧
      • 1. 条件断点
      • 2. 观察点(Watchpoints)
      • 3. 多线程调试
      • 4. 调试 Core 文件
      • 5. 反汇编调试
      • 6. 自动化调试脚本
    • 六、完整调试实例
      • 1. 示例代码:swap.c
      • 2. 编译程序
      • 3. 启动 GDB 并调试
      • 4. 调试步骤
    • 七、调试常见问题
      • 1. 程序崩溃
      • 2. 死循环
      • 3. 内存泄漏
    • 八、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档