🚀GDB(GNU Debugger)是 GNU 项目提供的一种调试工具,用于调试 C、C++ 和其他编程语言编写的程序。它允许程序员查看和控制程序的执行,从而帮助找到和修复程序中的错误。
🚀CGDB 是 GDB 的一个前端,它提供了一个更为用户友好的命令行界面,结合了文本用户界面(TUI)和普通的命令行。CGDB 提供了更加直观的视图和界面,使得调试过程更为高效。
【GDB 的主要功能】
【CGDB 的主要功能】
-- 安装gdb/cgdb
sudo yum install -y gdb
sudo yum install -y cgdb
-- 检查是否安装成功
gdb --version
cgdb --version
下面是我们这次调式需要使用代码:
#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 可执行文件来替代。
test:test.c
gcc -o $@ $^ -g -std=c11
.PHONY:clean
clean:
rm -f test
🍊我们可以通过readelf
指令来查看可执行文件中有没有调试信息。
💢 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】 |
首先我们进入到 gdb / cgdb
,然后它会等待我们输入指令
cgdb test 或者 cgdb test
🍅l -- 行号显示
注:还可以查看指令文件,并且在输入指令之后,可以一直回车,就会显示该文件下的所有内容了
🍅 r -- 直接运行程序
🍅 增加/查看/删除断点
🍅 n/s -- 逐过程/逐语句
watch(监视)
执行时监视一个表达式(如变量)的值,如果监视的表达式在程序运行期间的值发生变化,GDB 会暂停程序的执行,并且通知使用者
注:如果你有一些变量不应该修改,但是你怀疑它修改导致了问题,就可以 watch 它,如果发生了变化,就会通知你。
set var (确定问题原因)
更改一下标志位
条件断点
条件断点添加常见两种形式:1. 新增 2. 给已有断点追加
在此其他的指令我们就不过多讲解,大家可以看完文章后自行实践一下
1. 强大的调试功能
2. 支持多种编程语言
3. 适合命令行操作
4. 与其他工具的集成
5. CGDB 提升用户体验
6. 实时调试
7. 追踪内存和资源问题
8. 开源与社区支持
补充:当我们的 shell 光标消失了之后该咋办,如下:
输入 qui,然后光标就会恢复了
本文主要讲了关于 gdb / cgdb 是什么、怎么用、以及为什么要去使用两者来调试,对于上面的一些基础指令,大家还是要多去运用熟悉。
💞 💞 💞【*★,°*:.☆( ̄▽ ̄)/$:*.°★* 】那么本篇到此就结束啦,如果我的这篇博客可以给你提供有益的参考和启示,可以三连支持一下 !!