C++小碗菜之五:GDB调试工具

发布于:2024-12-18 ⋅ 阅读:(87) ⋅ 点赞:(0)

“程序员不是编写代码的人,而是调试错误的人。” – 约翰·本尼斯(John Bennet)

目录

前言

在虚拟机中安装 GDB

GDB调试的实战演练

创建示例代码

例子:

使用 GDB 调试

编译代码

启动 GDB

设置断点

运行程序

打印变量值

回溯错误

修复代码

结束语

相关阅读


总阅读时间约为 10~15分钟。

前言

gdb(GNU 调试器)是一个强大的调试工具,用于调试 C、C++ 等程序。对于一个Linux下工作的c/c++程序员,GDB是必不可少的工具,它可以帮助我们检查程序的运行情况,分析错误,并且能够逐行跟踪程序的执行过程。

在虚拟机中安装 GDB

在终端中运行以下命令安装 GDB:

sudo apt update

sudo 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 启动程序等,我们可以逐步定位问题并找到解决方法。

相关阅读