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

ops/2024/12/13 3:40:31/

“程序员不是编写代码的人,而是调试错误的人。” – 约翰·本尼斯(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 快速入门 - 菜鸟教程

http://www.ppmy.cn/ops/141424.html

相关文章

【CKA】Kubernetes(k8s)认证之CKA考题讲解

CKA考题讲解 0.考试101 0.1 kubectl命令⾃动补全 在 bash 中设置当前 shell 的⾃动补全&#xff0c;要先安装 bash-completion 包。 echo "source <(kubectl completion bash)" >> ~/.bashrc还可以在补全时为 kubectl 使⽤⼀个速记别名&#xff1a; al…

Ubuntu中使用C#调用Fortran编译so文件

环境说明&#xff1a; Ubuntu版本&#xff1a;v22.04 LTS.NET版本&#xff1a;v8.0.110GFortran版本&#xff1a;v11.4.0 安装Fortran编译器 在Ubuntu上安装Fortran编译器&#xff1a; # 更新包列表 sudo apt update# 安装gfortran编译器 sudo apt install gfortran创建.NE…

基于51单片机64位病床呼叫系统设计( proteus仿真+程序+设计报告+原理图+讲解视频)

基于51单片机病床呼叫系统设计( proteus仿真程序设计报告原理图讲解视频&#xff09; 仿真图proteus7.8及以上 程序编译器&#xff1a;keil 4/keil 5 编程语言&#xff1a;C语言 设计编号&#xff1a;S0095 1. 主要功能&#xff1a; 基于51单片机的病床呼叫系统proteus仿…

BA和CS算法中的Levy飞行策略

Levy飞行策略通过模拟自然界中动物的长距离迁徙行为&#xff0c;指导粒子进行更大范围的搜索&#xff0c;有助于算法快速找到全局最优解。它是一种具有独特优势的随机行为策略&#xff0c;模拟随机游走或搜索过程中的步长和方向&#xff0c;其步长的概率分布为重尾分布&#xf…

说下JVM中一次完整的GC流程?

大家好&#xff0c;我是锋哥。今天分享关于【说下JVM中一次完整的GC流程&#xff1f;】面试题。希望对大家有帮助&#xff1b; 说下JVM中一次完整的GC流程&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在JVM中&#xff0c;垃圾回收&#xff08;GC&am…

DVWA亲测sql注入漏洞

LOW等级 我们先输入1 我们加上一个单引号&#xff0c;页面报错 我们看一下源代码&#xff1a; <?php if( isset( $_REQUEST[ Submit ] ) ) { // Get input $id $_REQUEST[ id ]; // Check database $query "SELECT first_name, last_name FROM users WHERE user_id …

LLaMA-Factory 上手即用教程

LLaMA-Factory 是一个高效的大型语言模型微调工具&#xff0c;支持多种模型和训练方法&#xff0c;包括预训练、监督微调、强化学习等&#xff0c;同时提供量化技术和实验监控&#xff0c;旨在提高训练速度和模型性能。 官方开源地址&#xff1a;https://github.com/hiyouga/L…

【蓝桥杯Day1】:LCR 018. 验证回文串,left++<right--?

1&#xff1a;isalnum() 函数说明&#xff1a; 检查参数c,是否为英文字母或阿拉伯数字。 2.int toupper( int c)&#xff0c;toupper():将字母转位大写。 3.int tolower( int c)&#xff0c;tolower():将字母转为小写。 下面是我自己写的&#xff0c;感觉写的有点搓。 特别注…