“程序员不是编写代码的人,而是调试错误的人。” – 约翰·本尼斯(John Bennet)
目录
前言
在虚拟机中安装 GDB
GDB调试的实战演练
创建示例代码
例子:
使用 GDB 调试
编译代码
启动 GDB
设置断点
运行程序
打印变量值
回溯错误
修复代码
结束语
相关阅读
总阅读时间约为 10~15分钟。
前言
gdb(GNU 调试器)是一个强大的调试工具,用于调试 C、C++ 等程序。对于一个Linux下工作的c/c++程序员,GDB是必不可少的工具,它可以帮助我们检查程序的运行情况,分析错误,并且能够逐行跟踪程序的执行过程。
在虚拟机中安装 GDB
在终端中运行以下命令安装 GDB:
sudo apt updatesudo apt install gdb
安装完成后,可以检查 GDB 版本以确认安装成功:
gdb --version
GDB调试的实战演练
不必介绍太多理论知识,我们只要知道怎么用,使得我们的程序能够成功跑起来即可。
创建示例代码
例子:
在计算数组平均值时,由于访问越界,导致程序计算出错。
在当前目录中创建一个名为 example.cpp 的文件,输入以下代码:
#include <iostream>double calculateAverage(int* numbers, int size) {int sum = 0;for (int i = 0; i <= size; ++i) { // 错误:i <= size 导致数组越界访问sum += numbers[i];}return static_cast<double>(sum) / size;
}int main() {int numbers[] = {10, 20, 30, 40, 50};int size = sizeof(numbers) / sizeof(numbers[0]);std::cout << "Calculating average..." << std::endl;double average = calculateAverage(numbers, size);std::cout << "The average is: " << average << std::endl;return 0;
}
期望结果为30,但编译运行代码发现每次得到的结果明显与期望结果不同,如下图:
使用 GDB 调试
编译代码
使用 -g 选项启用调试信息编译代码:
g++ -g -o debug_example example.cpp
启动 GDB
gdb debug_example
设置断点
在 calculateAverage 函数入口设置断点:
(gdb) break calculateAverage
运行程序
运行程序,让其停在断点处:
(gdb) run
单步调试
进入函数并逐行执行代码,观察变量变化:
(gdb) step # 进入 calculateAverage 函数(gdb) next # 逐行执行
打印变量值
观察变量 i 和 numbers[i] 的值:
(gdb) print i(gdb) print numbers[i]
当 i == 5 时,程序尝试访问数组越界的元素。
回溯错误
在程序出现错误后,使用以下命令查看调用栈,定位错误位置:
(gdb) bt
这表明错误发生在 debug_example.cpp 第 6 行。
修复代码
修改 calculateAverage 中的循环条件:
for (int i = 0; i < size; ++i) { // 修正:i < size 避免越界访问
重新编译并运行程序,确保问题已解决。
通过以上例子,我们学习到如何在 GDB 中设置断点、逐行调试代码、检查变量值,以及分析错误原因。
结束语
在调试 C++ 程序时,GDB 是一个强大的工具,它能够帮助我们深入分析程序的执行流程,查找潜在的错误和性能瓶颈。通过使用 GDB 的各种命令,如 bt 来查看调用堆栈、break 设置断点、run 启动程序等,我们可以逐步定位问题并找到解决方法。
相关阅读
- Books/GDB完全手册.pdf at master · zhuzongzhen/Books
- Books/GDB中文手册完美版.pdf at master · zhuzongzhen/Books
- GDB 参考手册 & gdb 快速入门 - 菜鸟教程