第一章: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的启动
启动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调试的核心流程:从编译开始,到启动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也能迎刃而解。
break、run、print、next、step 这五个命令练熟,就够你应付80%的调试场景了。