第一章:GDB入门——GDB是什么、能做什么、怎么装、怎么启动
大家好,我是你们的老朋友。今天咱们正式开始《GDB多线程调试实战课程》的第一章。
说实话,我刚开始接触Linux C/C++开发那会儿,调试全靠printf。打印一行,编译,运行,看输出,再改代码……循环往复。直到有一次,一个多线程死锁问题让我整整折腾了两天,printf打了上百行,愣是没找到根因。后来一位老同事走过来,敲了几个命令,十分钟定位了问题。他用的就是GDB。
从那天起,我就再也没离开过GDB。
1.1 GDB是什么?
GDB,全称GNU Project Debugger,是GNU项目下的一个源码级调试器。说白了,它就是一个能让你“钻进”程序内部,观察程序运行时状态的神器。
你想想看,平时我们写代码,编译完直接运行,程序要么跑对了,要么崩了。崩了之后呢?core dump一出来,你只能对着堆栈发愣。但有了GDB,你可以让程序在任意一行停下来,看看变量值对不对,线程栈长什么样,甚至能动态修改内存里的数据。
我个人习惯把GDB比作“程序的CT机”。它能扫描程序的每一个角落,告诉你哪里出了问题。
核心一句话:GDB让你拥有“上帝视角”,观察程序运行时的每一个细节。
1.2 GDB能做什么?
GDB的能力,远不止“打断点、看变量”这么简单。我列几个我在项目中实际用过的场景:
- 设置断点:在代码的某一行、某个函数、甚至某个条件满足时停下来。
- 单步执行:一行一行地走,或者一次执行一个函数调用。
- 查看变量和内存:打印变量的值,查看内存地址里的内容,甚至修改它们。
- 分析堆栈:程序崩溃时,查看函数调用链,定位崩溃点。
- 多线程调试:切换线程、查看线程状态、分析锁竞争——这是咱们课程的核心。
- 远程调试:程序跑在嵌入式设备上,你在PC上用GDB连过去调试。
- 反汇编调试:没有源码时,直接看汇编指令的执行。
嗯,这里要注意:GDB不是万能的。它不能帮你修复逻辑错误,也不能自动发现内存泄漏。但它能给你足够的信息,让你自己找到问题。
1.3 GDB的安装
安装GDB其实很简单。不同系统下方法略有不同,我分别说一下:
| 操作系统 | 安装命令 | 备注 |
|---|---|---|
| Ubuntu/Debian | sudo apt-get install gdb |
最常用,版本较新 |
| CentOS/RHEL | sudo yum install gdb |
或者用dnf |
| macOS | brew install gdb |
需要Homebrew,且需额外签名 |
| Windows | 安装MinGW或WSL | 建议用WSL,体验更接近Linux |
安装完成后,在终端输入gdb --version,如果能看到版本号,就说明装好了。我曾经在CentOS 6上装过一个老版本,结果调试多线程时各种诡异问题,后来升级到7.7以上才解决。所以我的建议是:尽量用新版本,至少7.0以上。
小技巧:如果你在嵌入式环境里,可能需要交叉编译版本的GDB,比如arm-linux-gdb。安装方法类似,只是包名不同。
1.4 GDB的基本启动
启动GDB的方式有好几种,我挑最常用的三种讲:
方式一:直接启动,再加载程序
gdb
(gdb) file ./my_program
这种方式适合你还没想好要调试哪个程序,先打开GDB再说。
方式二:启动时直接加载程序
gdb ./my_program
这是我最常用的方式。一步到位,省事。
方式三:调试core dump文件
gdb ./my_program core.12345
程序崩溃后,如果生成了core dump文件,用这种方式可以直接定位到崩溃点。我曾经在生产环境上遇到过段错误,就是靠这个命令三分钟找到原因的。
注意:要生成core dump文件,需要先设置ulimit -c unlimited。否则程序崩了就崩了,什么痕迹都不会留下。我见过不少新手踩这个坑。
1.5 第一个GDB调试会话
咱们写一个最简单的程序,感受一下GDB怎么用:
// test.c
#include <stdio.h>
int add(int a, int b) {
int result = a + b;
return result;
}
int main() {
int x = 10;
int y = 20;
int sum = add(x, y);
printf("sum = %d\n", sum);
return 0;
}
编译时记得加-g选项,这样才能保留调试信息:
gcc -g -o test test.c
然后启动GDB:
gdb ./test
进入GDB后,你可以做这些操作:
break main—— 在main函数入口设断点run—— 运行程序,会在main处停下next—— 单步执行,不进入函数内部step—— 单步执行,会进入函数内部print x—— 打印变量x的值continue—— 继续运行,直到下一个断点或程序结束quit—— 退出GDB
试试看,你会看到程序在每一行停下来,你可以随时查看变量的值。这种感觉,比printf爽多了。
1.6 本章知识体系
下面这张图,帮你快速理清本章的核心内容:
这张图把本章的知识点串起来了。从“GDB是什么”出发,到“能做什么”,再到“怎么安装”,最后落到“基本命令”。后面的章节,我们会在这个基础上,一步步深入多线程调试的世界。
我的建议:别急着往后看。先把GDB装好,拿上面那个test.c练练手。熟悉了break、next、print这几个命令,后面学多线程调试会轻松很多。
好了,第一章就到这里。记住,调试不是玄学,是技术。GDB就是你手里最趁手的工具。用好它,你的排错效率至少提升一个数量级。
可可精品资料库