1、GDB入门:GDB是什么、GDB与Qt的关系、GDB的安装与版本检查
1.1 GDB到底是什么?
GDB,全称GNU Debugger。说白了,就是一个让你能「看穿」程序运行过程的工具。
我刚开始学C++那会儿,调试全靠printf。满屏幕打印日志,改完还得重新编译。效率低不说,有时候加了一堆打印,问题反而被掩盖了。后来接触了GDB,才明白什么叫「降维打击」。
GDB能做什么?我列几个最常用的场景:
- 断点调试:让程序在指定行停下来,你慢慢看
- 单步执行:一行一行地走,观察变量怎么变
- 查看堆栈:程序崩溃了?看一眼调用链,问题出在哪一目了然
- 修改变量:运行到一半,你可以强行改某个值,看看程序会怎样
你想想看,这些能力在排查复杂bug时有多重要。尤其是那种「偶尔崩溃、日志又看不出问题」的玄学bug,GDB几乎是唯一解法。
核心认知:GDB不是图形界面工具,它是命令行工具。但正因为是命令行,它可以在任何环境下工作——本地、远程、嵌入式、服务器。这一点,很多IDE调试器做不到。
1.2 GDB与Qt的关系
Qt项目能不能用GDB?当然能。而且我建议你学会在Qt Creator里用GDB,也要学会在命令行里直接用GDB。
为什么?
Qt Creator默认集成了GDB作为调试后端。你在IDE里点那个绿色小虫子按钮,背后其实就是GDB在工作。但IDE帮你封装了大部分命令,你只需要点点鼠标。
这样做的好处是上手快。坏处呢?
我记得有一次,项目在客户现场崩溃了。我远程连上去,只有命令行环境,没有Qt Creator。如果只会点鼠标,那就彻底抓瞎了。还好我习惯在开发时也偶尔用命令行GDB,那次直接在终端里定位了问题——一个信号槽连接时的野指针。
所以我的建议是:
- 日常开发用Qt Creator + GDB,效率高
- 复杂问题或远程调试时,直接上命令行GDB,更灵活
另外要注意一点:Qt的信号槽机制,在GDB里看起来有点「绕」。因为信号槽底层是元对象系统在调度,你打断点时可能发现调用栈里多了一层QMetaObject::activate。嗯,这个后面我们会专门讲。
小技巧:在Qt Creator里调试时,你其实可以打开「调试器」视图,看到GDB实际执行的命令。这样既能享受IDE的便利,又能学到GDB的用法,一举两得。
1.3 GDB的安装与版本检查
安装GDB其实很简单。不同系统略有差异,我分别说一下。
Linux(Ubuntu/Debian)
sudo apt update
sudo apt install gdb
macOS
brew install gdb
注意:macOS上安装GDB后,还需要做代码签名,否则调试时会报权限错误。这个坑我踩过,折腾了半小时才搞定。
Windows
如果你用的是MinGW版本的Qt,GDB通常已经随Qt一起安装了。路径一般在:
C:\Qt\Tools\mingw730_64\bin\gdb.exe
如果你用的是MSVC版本的Qt,那调试器是CDB(Microsoft Console Debugger),不是GDB。不过别担心,CDB的用法和GDB很像,后面我们也会提到两者的差异。
版本检查
安装完成后,打开终端,输入:
gdb --version
你会看到类似这样的输出:
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
...
版本号至少要在7.0以上,最好用8.0或更高。太老的版本对C++11/14/17的支持不够好,调试Qt项目时可能会遇到一些奇怪的问题。
注意:如果你在Windows上使用MSVC + CDB,不要强行装GDB。CDB和Qt Creator配合得很好,而且微软官方一直在维护。我个人的经验是:MSVC项目用CDB,MinGW项目用GDB,各司其职就好。
1.4 本章知识体系
下面这张图,帮你快速理清GDB入门阶段的核心脉络:
1.5 验证安装是否成功
装完之后,最好做个快速验证。写一个简单的C++程序:
// test.cpp
#include <iostream>
int main() {
int a = 10;
int b = 20;
int c = a + b;
std::cout << "c = " << c << std::endl;
return 0;
}
编译时加上-g选项,这个选项告诉编译器保留调试信息:
g++ -g -o test test.cpp
然后用GDB启动:
gdb ./test
进入GDB后,你会看到类似这样的提示符:
(gdb)
输入break main设置断点,然后输入run运行。如果一切正常,程序会在main函数入口处停下来。这时候输入print a,应该能看到a = 10。
嗯,到这里,你的GDB环境就准备好了。
个人建议:刚开始用GDB时,别急着学高级技巧。先把break、run、next、step、print、continue这六个命令练熟。它们能覆盖你日常80%的调试需求。
好了,GDB入门的第一章就到这里。记住:工具是死的,思路是活的。GDB再强大,也得靠你判断「该在哪里打断点」、「该观察哪些变量」。这些经验,我们后面慢慢聊。