【linux】linux调试器-gdb的使用
小编个人主页详情<—请点击
小编个人gitee代码仓库<—请点击
linux系列专栏<—请点击
倘若命中无此运,孤身亦可登昆仑,送给屏幕面前的读者朋友们和小编自己!
目录
- 前言
- 一、debug和release
- 二、要进行调试的准备工作
- 三、gdb的使用
- 启动gdb
- 退出
- 查看行号对应10行代码
- 查看函数代码
- 运行程序
- 设置断点
- 查看断点
- 删除断点
- 禁用断点
- 启用断点
- 逐过程调试
- 逐语句调试
- 打印变量值
- 跟踪变量(让变量每次停下来都显示)
- 取消追踪变量
- 查看当前局部变量的值
- 设置局部变量的值
- 执行到函数返回
- 跳到下个断点
- 跳转到指定行
- 查看函数调用堆栈
- 总结
前言
【linux】倒计时小程序、进度条小程序及其puls版本—书接上文详情请点击<—
本文由小编为大家讲解—【linux】linux调试器-gdb的使用
一、debug和release
- 在linux中,编译器默认生成的可执行程序(二进制程序)是release发布版本,即追求性能的版本
- 如果想要生成debug版本的可执行程序,就需要我们在使用gcc/g++工具将源文件进行编译链接生成二进制程序的时候进行手动指定选项-g添加debug信息,使我们的可执行程序可以被执行追踪
- 通常debug版本由于添加了debug调试信息,通常都是比默认生成的release版本的所占用的空间大
- gcc 要进行编译的文件 -o 可执行文件名 -g
readelf -S 可执行文件名,可执行文件形成的时候不是无序的,而是有独特的格式,可执行程序有自己的二进制格式(elf格式),我们可以使用readelf -S 可执行文件名,来进行查看可执行文件的二进制格式
同时我们还可以借助管道,使用grep对二进制格式中的信息进行搜索,其中-i选项是忽略大小写进行查找,grep的使用请点击<—,由于test是release是发行版本,没有添加debug信息,所以无法查找到debug,test_debug是debug版本,添加了debug信息,所以可以查找到debug
二、要进行调试的准备工作
- 编写要进行调试的代码,小编已经创建了一个test.c的文件用于编写如下代码,这里小编编写了一个求x减到1的总和函数用于进行我们的调试
#include
int func(int x)
{
int sum=0;
while(x)
{
sum+=x;
x--;
}
return sum;
}
int main()
{
printf("gdb-begin
");
int ret = func(100);
printf("ret : %d
",ret);
printf("gdb-end
");
return 0;
}
linux项目自动化构建工具-make/Makefile的使用详情请点击<—
- 创建自动化构建工具的文件makefile,并写入指令,这里特别注意由于我们想要生成的是可调试的debug版本的可执行程序,那么要在我们使用gcc命令后面加入-g选项,底行模式wq保存退出之后,在命令行运行make指令生成debug版本的二进制程序test
test:test.c
gcc test.c -o test -g
clean:
rm -f test
- 检查,当你的程序使用readelf -S 文件名 | grep debug查找到如下debug信息代表你生成dubug版本的二进制程序成功,该程序可以使用gdb进行调试
三、gdb的使用
启动gdb
- gdb 可执行文件名,观察到如下场景即为我们的gdb调试器启动成功,那么接下来我们将在(gdb)命令行中输入调试命令进行我们程序的调试
退出
- q,退出gdb
查看行号对应10行代码
- l n,n代表你所要查看行号,即可显示该行号对应代码,如果输入的行号为1,那么会从第1行开始显示共计10行代码,如果该行号为一个中间的行号,那么会居中显示该行号,并且显示该行号上5行,下5行,共计10行代码
- gdb会默认记住命令,如果你输入命令后,下一次输入默认继续执行上一次的命令,并且如果你查看的是行号会继续从上一次查看的最后一行的位置继续向下查看
查看函数代码
- l 函数名
运行程序
- r ,可以运行程序,如果没有设置断点,那么默认执行到程序的最后,如果设置了断点,那么默认运行到第一个断点的位置
设置断点
- b n,n代表行号,在某一行设置断点
- b 函数名,在函数的开头设置断点
- b 源文件: n,在源文件行号为n的位置处设置断点
查看断点
- info b,可以查看断点的信息,并且根据断点设置的时间先后标序号
删除断点
- d n,这个n代表断点的序号,例如下图中的Nnm那一行代表的序号
- d breakpoints,可以删除所有断点
禁用断点
启用断点
- disable n,这个n代表断点的序号,禁用断点
- enable n,这个n代表断点的序号,启动断点
逐过程调试
逐语句调试
- 这里的调试过程一定是r先运行起来才能进行逐过程调试或逐语句调试
- n,逐过程调试,类似于vs中的F10,不会进入函数
- s,逐语句调试,类似于vs中的F11,会进入函数
打印变量值
- p 变量,调试运行起来,可以进行打印变量对应的值(这里的作用仅仅是打印,无其它作用)
跟踪变量(让变量每次停下来都显示)
- display 变量名,跟踪查看一个变量,每次停下来都显示它的值,类似于vs中的监视窗口监视变量的作用
取消追踪变量
- undisplay,可以取消对所有变量的追踪(这里不可以单独取消对某个变量的追踪,要取消只能统一取消对全部变量的追踪)
查看当前局部变量的值
- info locals,可以查看当前局部变量的值
设置局部变量的值
- set var 变量名=你要给变量设置的值,比如循环前50次没有问题,你想快速跳转至第51次有没有问题,可以使用修改循环变量的值达到快速跳转进行调试
执行到函数返回
- finish,可以指向到当前函数的返回,并且停在函数调用的那个位置
跳到下个断点
- c,跳转到下一个断点
跳转到指定行
- until n,n代表行号,跳转到指向行n
查看函数调用堆栈
- bt,查看函数调用堆栈(即各级函数调用及其参数)
总结
以上就是今天的博客内容啦,希望对读者朋友们有帮助
水滴石穿,坚持就是胜利,读者朋友们可以点个关注
点赞收藏加关注,找到小编不迷路!