前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【探索 GDB 和 CGDB】:强大的调试工具介绍

【探索 GDB 和 CGDB】:强大的调试工具介绍

作者头像
用户11316099
发布2024-10-15 20:45:32
990
发布2024-10-15 20:45:32
举报
文章被收录于专栏:学习之路

1. 引言📃

1.1 什么是GDB / CGDB?

🚀GDB(GNU Debugger)是 GNU 项目提供的一种调试工具,用于调试 C、C++ 和其他编程语言编写的程序。它允许程序员查看和控制程序的执行,从而帮助找到和修复程序中的错误。

🚀CGDB 是 GDB 的一个前端,它提供了一个更为用户友好的命令行界面,结合了文本用户界面(TUI)和普通的命令行。CGDB 提供了更加直观的视图和界面,使得调试过程更为高效。

1.2 两者各自的功能

【GDB 的主要功能】

  1. 启动程序:可以在 GDB 中启动程序,设置参数和环境变量。
  2. 设置断点:允许用户在程序中的特定位置设置断点,以便程序执行到该位置时暂停。
  3. 单步调试:可以逐行执行代码,观察每一步的行为和变量的变化。
  4. 查看和修改变量:可以查看程序中的变量值,也可以在调试过程中修改这些变量。
  5. 调用栈跟踪:可以查看当前的调用栈,帮助识别程序执行路径。
  6. 后退调试:支持在某些情况下“后退”执行,以帮助分析错误。
  7. 脚本和自动化:支持通过脚本进行自动化调试,便于重复调试相似的问题。

【CGDB 的主要功能】

  1. 图形化用户界面:提供了一个可视化的界面,使得调试过程更为直观。
  2. 命令窗口与文本窗口结合:可以在同一界面中查看代码和 GDB 命令的输出,提高调试效率。
  3. 多窗口支持:支持多个窗口,使得同时查看代码、变量和命令输出变得容易。
  4. 快捷键支持:提供了多种快捷键来快速执行常用操作,提升使用体验。
1.3 如何安装
代码语言:javascript
复制
-- 安装gdb/cgdb
sudo yum install -y gdb 
sudo yum install -y cgdb

-- 检查是否安装成功
gdb --version
cgdb --version

2. GDB / CGDB 的使用

  1. 程序的发布方式有两种, debug 模式和 release 模式
  2. Linux gcc/g++ 出来的二进制程序,默认是 release 模式,不可调试
  3. 要使用 gdb / cgdb 调试,必须在源代码生成二进制程序的时候 , 加上 - g 选项
🥑 代码案例

下面是我们这次调式需要使用代码:

代码语言:javascript
复制
#include <stdio.h>

int flag = 0;
int sum(int s, int e){
    int sum = 0;
    int i = s;
    for(; i <= e; i++) sum += i;
    return sum * flag;
}

int div(int x, int y){
    if(y == 0) return -1;
    int z = x / y;
    return z;
}

int main()
{
    printf("process is running ");
    int start = 1;
    int end = 10;
    int result = sum(start, end);
    printf("process is done, result: %d\n",result);
    
    int a =  div(10, 0);
    printf("process is done, result: %d\n",a);

    return 0;
}
🥝 生成调试文件

不调试的情况下,使用 gcc 指令编译文件一般是:gcc test.c -o test 但是,如果要调试,那么就必须要加上 -g 指令。其原理用 Visual Studio Code 环境下来类比,使用该 IDE 熟悉的话便知道 发行一个程序的时候,可以有 release 版本和 debug 版本,只有我们选择 debug 版本的时候,程序才可以被调试,否则不行。这里也类似,加上 -g 就相当于生成 debug 版本的程序,不加就默认是 release 版本的。

方式一:

方式二:

🍊可以看到的是,debug版本的可执行程序test.d明显比release版本test.r的大。

方式三:

为了方便,我们还是把调式代码指令写到Makefile 文件中。上面的test.r 和 test.d 的调式版本只是给大家看一下,下面我们不做过多区分,统一用 test 可执行文件来替代。

代码语言:javascript
复制
test:test.c
	gcc -o $@ $^ -g -std=c11

.PHONY:clean
clean:
	rm -f test
🥑 readelf命令

🍊我们可以通过readelf指令来查看可执行文件中有没有调试信息。

3. 调式指令📚

3.1 指令集

💢 gdb binFile 退出: ctrl + d 或 quit 调试命令:

指令名

作用

l(list) 行号/函数名

显示对应的code,每次10行

r(run)

F5【无断点直接运行、有断点从第一个断点处开始运行】

b(breakpoint) + 行号

在哪一行打断点

b 源文件:函数名

在该函数的第一行打上断点

b 源文件:行号

在该源文件中的这行加上一个断点

info b

查看断点的信息

breakpoint already hit 1 time

【此断点被命中一次】

d(delete) + 当前要删除断点的编号

删除一个断点【不可以d + 行号】

若当前没有跳出过gdb

则断点的编号会持续累加

d + breakpoints

删除所有的断点

disable b(breakpoints)

使所有断点无效【默认缺省】

enable b(breakpoints)

使所有断点有效【默认缺省】

disable b(breakpoint) + 编号

使一个断点无效【禁用断点】

enable b(breakpoint) + 编号

使一个断点有效【开启断点】

enable breakpount

使一个断点有效【开启断点】

n(next)

逐过程【相当于F10】

s(step)

逐语句【相当于F11】

bt

看到底层函数调用的过程【函数压栈】

set var

修改变量的值

p(print) 变量名

打印变量值

display

跟踪查看一个变量,每次停下来都显示它的值【变量/结构体…】

undisplay + 变量名编号

取消对先前设置的那些变量的跟踪

until + 行号

进行指定位置跳转,执行完区间代码

finish

在一个函数内部,执行到当前函数返回,然后停下来等待命令

c(continue)

从一个断点处,直接运行至下一个断点处【VS下不断按F5】

3.2 案例演示

首先我们进入到 gdb / cgdb,然后它会等待我们输入指令

代码语言:javascript
复制
cgdb test 或者 cgdb test 

🍅l -- 行号显示

注:还可以查看指令文件,并且在输入指令之后,可以一直回车,就会显示该文件下的所有内容了

🍅 r -- 直接运行程序

🍅 增加/查看/删除断点

🍅 n/s -- 逐过程/逐语句

3.3 补充

watch(监视)

执行时监视一个表达式(如变量)的值,如果监视的表达式在程序运行期间的值发生变化,GDB 会暂停程序的执行,并且通知使用者

注:如果你有一些变量不应该修改,但是你怀疑它修改导致了问题,就可以 watch 它,如果发生了变化,就会通知你。

set var (确定问题原因)

更改一下标志位

条件断点

条件断点添加常见两种形式:1. 新增 2. 给已有断点追加

  • 新增:b 行号/文件名:行号/函数名 if i == 30 (条件)
  • 给已有断点追加:condition 2 i == 30, 其中 2 是已有断点编号,没有if

在此其他的指令我们就不过多讲解,大家可以看完文章后自行实践一下

4. 为什么要使用gdb / cgdb 来调试

1. 强大的调试功能

  • GDB 功能强大:GDB 允许开发者进行单步调试、设置断点、观察变量的值、检查内存状态等。这些功能帮助开发者深入了解程序的执行流程,并迅速定位错误。

2. 支持多种编程语言

  • 多语言支持:GDB 支持多种编程语言,包括 C、C++、Fortran、Go 等。这使得它成为跨语言开发的通用调试工具。

3. 适合命令行操作

  • 命令行界面:在 Linux 环境中,命令行操作是常见的工作方式。GDB 提供了一个强大的命令行界面,使得高级用户可以通过命令快速高效地调试程序。

4. 与其他工具的集成

  • 与其他开发工具集成:GDB 可以与许多其他开发工具和 IDE(集成开发环境)集成,例如 Eclipse、VSCode 等。这使得在开发过程中调试变得更加方便。

5. CGDB 提升用户体验

  • CGDB 的图形化界面:CGDB 提供了一个基于终端的用户界面,可以在终端中以图形化的方式查看代码和调试信息。这对于喜欢在终端中工作的开发者来说,提供了更好的可视化体验,尤其是在处理大型代码时。

6. 实时调试

  • 实时调试能力:GDB 支持对正在运行的程序进行调试,可以暂停程序的执行、检查状态并修改变量值,从而实时查看更改对程序行为的影响。

7. 追踪内存和资源问题

  • 内存调试:GDB 可以帮助开发者追踪内存泄漏和未定义行为,这对于 C 和 C++ 等语言尤为重要,因为这些语言对内存管理的要求较高。

8. 开源与社区支持

  • 开源和广泛社区支持:GDB 是开源的,拥有广泛的用户和开发者社区。用户可以获得丰富的文档、教程和支持,这对于解决问题和学习使用非常有帮助。

📖 总结

补充:当我们的 shell 光标消失了之后该咋办,如下:

输入 qui,然后光标就会恢复了

本文主要讲了关于 gdb / cgdb 是什么、怎么用、以及为什么要去使用两者来调试,对于上面的一些基础指令,大家还是要多去运用熟悉。

💞 💞 💞【*★,°*:.☆( ̄▽ ̄)/$:*.°★* 】那么本篇到此就结束啦,如果我的这篇博客可以给你提供有益的参考和启示,可以三连支持一下 !!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-10-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 引言📃
    • 1.1 什么是GDB / CGDB?
      • 1.2 两者各自的功能
        • 1.3 如何安装
        • 2. GDB / CGDB 的使用
          • 🥑 代码案例
            • 🥝 生成调试文件
              • 🥑 readelf命令
              • 3. 调式指令📚
                • 3.1 指令集
                  • 3.2 案例演示
                    • 3.3 补充
                    • 4. 为什么要使用gdb / cgdb 来调试
                    • 📖 总结
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档