第一章:GDB入门——调试,从认识GDB开始

说实话,我刚开始做嵌入式那会儿,调试基本靠printf。代码里到处是打印语句,改一次编译一次,效率低得让人抓狂。直到有一天,我的导师扔给我一句话:「去学学GDB吧,别再用笨办法了。」

嗯,这一学,就再也没放下过。今天咱们就来聊聊GDB——这个我用了十几年的调试利器。

GDB是什么?

GDB,全称GNU Debugger,是GNU项目下的一个调试器。说白了,它就是一个能让你「看穿」程序运行过程的工具。

你想想看,平时写代码,程序跑起来就是个黑盒子。你只知道输入和输出,中间发生了什么?变量值对不对?程序卡在哪一行?这些你都不知道。GDB就是帮你打开这个黑盒子的钥匙。

我个人习惯把GDB比作「程序的CT机」。它能扫描程序的每一个角落,告诉你哪里出了问题。

GDB能做什么?

我遇到过不少新手,觉得GDB就是用来「看变量值」的。其实它的能力远不止这些。咱们列一下:

  • 启动程序:可以带参数启动,也可以指定环境变量
  • 设置断点:在指定行、函数、条件满足时停下来
  • 单步执行:一行一行地走,看程序是怎么跑的
  • 查看变量:随时查看、修改变量的值
  • 查看堆栈:函数调用关系一目了然
  • 分析崩溃:程序挂了,GDB能告诉你挂在哪、为什么挂
  • 反汇编:想看汇编代码?没问题
  • 多线程调试:每个线程都能单独控制

我记得有一次,一个同事调了三天都没找到的bug,我用GDB看了下堆栈,五分钟就定位到了问题。从那以后,他再也不用printf调试了。

GDB的安装

安装GDB其实很简单。不同平台方法略有不同:

操作系统 安装命令
Ubuntu/Debian sudo apt-get install gdb
CentOS/RHEL sudo yum install gdb
macOS brew install gdb
Windows 安装MinGW或Cygwin,自带GDB

装完之后,在终端输入 gdb --version,能看到版本信息就说明装好了。

小提示:嵌入式开发中,我们经常用交叉编译版本的GDB,比如arm-none-eabi-gdb。用法和普通GDB完全一样,只是目标平台不同。

GDB的启动

启动GDB有两种常见方式:

方式一:直接启动

gdb ./my_program

这样会进入GDB交互界面,然后你可以用 run 命令启动程序。

方式二:先启动,再加载

gdb
(gdb) file ./my_program
(gdb) run

我个人习惯用第一种,省事。但如果你要调试core dump文件,就得用第二种了:

gdb ./my_program core.dump
注意:要调试的程序在编译时必须加上 -g 选项,否则GDB看不到源码和变量名。我曾经帮一个同事看问题,他编译时没加 -g,结果GDB里全是地址,根本没法看。

GDB的核心逻辑

为了让你更直观地理解GDB的工作方式,我画了一张图:

GDB调试核心流程 编译 gcc -g -o prog prog.c 启动GDB gdb ./prog 设置断点 break main 运行程序 run 调试循环 单步执行 | 查看变量 | 查看堆栈 | 修改变量 next | print | backtrace | set var

这张图展示了GDB调试的核心流程:从编译开始,到启动GDB,设置断点,运行程序,最后进入调试循环。说白了,就是「停住程序,然后慢慢看」。

一个简单的例子

光说不练假把式。咱们写个简单的程序试试:

// test.c
#include <stdio.h>

int add(int a, int b) {
    return a + b;
}

int main() {
    int x = 10;
    int y = 20;
    int result = add(x, y);
    printf("result = %d\n", result);
    return 0;
}

编译:

gcc -g -o test test.c

启动GDB:

gdb ./test

在GDB里:

(gdb) break main
(gdb) run
(gdb) print x
$1 = 10
(gdb) next
(gdb) print y
$2 = 20
(gdb) step
(gdb) print a
$3 = 10
(gdb) print b
$4 = 20
(gdb) continue

看到了吗?每一步都能看到变量的值。这就是GDB的魅力。

核心要点:

  • 编译加 -g 选项
  • 用 break 设置断点
  • 用 run 启动程序
  • 用 print 查看变量
  • 用 next 和 step 单步执行

嗯,第一章就到这里。记住,调试不是玄学,GDB就是你手里的手术刀。用好了,再复杂的bug也能迎刃而解。

我的经验:刚开始用GDB时,别贪多。先把 break、run、print、next、step 这五个命令练熟,就够你应付80%的调试场景了。

可可精品资料库