linux下的gdb调试

目录

前情提要

如何下载gdb呢?

此时就要学习一些gdb里面的指令了

第一条指令是list/l 可以缩写成l,l+数字,就是显示行号信息,默认从上次位置开始显示10行。

接着由于我们用过Vistdio,调试时则使用F5来编译通过打断点来直接按顺序执行,F10来逐过程,F11来逐语句,F9来设置断点以及手动禁用断点(不删除只不过是根据需求暂时禁用)。

删除指定断点:delete+断点编号

删除所有断点:delete+breakpoints

添加删除结束后,还有使能(enable)断点,也就是vs下的禁用和启用断点

断点的设置说完后则是调试,也就是vs下的f10逐过程、f11逐语句

接下来是类似VS下的监视窗口

接下来是p(print打印)的使用

如何直接跳过并且执行整个循环呢?

其次再学习一个命令c/continue   继续的意思,意义在于断点与断点的跳跃。

或者使用until+行号,这也是一个命令,直接跳到指定行号。

当然看到这里肯定也收获不少,但是gdb很乱不方便我们使用,还不如图形化界面,此时我们就需要下载一个新的东西叫cgdb。

其他的还有finish命令来直接执行一整个函数,方便排查、搜寻错误。

接下来看一下cgdb的界面

接下来再学习一个指令叫:bt   来查看堆栈情况​编辑

以及info local 来查看当前栈帧局部变量的值

问:调试的本质是什么?

接下来再学习一个watch,通过watch也相当于打个断点,watch所打断点的变量变了,就会显示出来

再学习一个set var来修改变量的值

那么如何像vs那样设置条件断点呢?

有两种情况一种是1.新增,另一种是2.给已有断点追加

接下来是已经存在的断点进行条件判断添加:

习题


前情提要

在vs下程序有debug版本和release版本,debug版本方便程序员调试,release版本也就是发布版本,是供用户调试使用的。

gcc/g++的可执行程序默认是release版本。

上图代码是个简单的小程序,通过这个代码我们来测试一下gcc下编译后的可执行程序是否是release版本。

通过使用makefile来进行编译

debug版本则需要加“-g”也就是debug的最后一个字母。

gcc -o myexe-debug test.c -g

myexe的文件大小明显比myexe-debug文件大小要小

readelf,elf大致意思是查看文件的格式.

自上往下看两者图其实是紧挨着的代码和显示结果。

只有后缀为debug的文件显示了有结果。

注意学习gdb调试工具,必然是要以debug版本的可执行程序为基准。

再一个通过file指令也可以对比出结果。

如何下载gdb呢?

本人用的是Ubuntu操作系统,yum是在centos上用,出现了一个问题,就是yum下载不了,当查阅了相关资料可以看一位网友的博客分享

使用指令“gdb”可以查看是否下载了gdb

如果没下载就需要指令:“sudo apt-get install gdb”

下载完后使用指令:“gdb --version”来查看下载gdb后的版本信息

下面就是如何使用gdb来进行调试了。

在命令行输入gdb就能够进入gdb界面

输入quit来退出gdb

通过输入gdb myexe-debug来进入调试模式

此时就要学习一些gdb里面的指令了

第一条指令是list/l 可以缩写成l,l+数字,就是显示行号信息,默认从上次位置开始显示10行。

如上图,第二次命令行什么也没输入,是因为gdb会记录最新的一条命令,直接回车就是默认执行该指令。

上图为l+函数名 表示列出指定函数的源代码

上图为l+文件名:行号 表示显示指定文件第n行的代码

接着由于我们用过Vistdio,调试时则使用F5来编译通过打断点来直接按顺序执行,F10来逐过程,F11来逐语句,F9来设置断点以及手动禁用断点(不删除只不过是根据需求暂时禁用)。

linux操作系统下也有对应的指令。

比如打断点:break/b+行号

行号打断点后也有删除断点,当然如图还有info b的意思是查看断点信息

删除指定断点:delete+断点编号

删除所有断点:delete+breakpoints

添加删除结束后,还有使能(enable)断点,也就是vs下的禁用和启用断点

disable+breakpoints:禁用所有断点

enable+breakpoints:启用所有断点

使用quit先退出当前调试,从新做示范,差别我用红色方框标注出来了。

断点的设置说完后则是调试,也就是vs下的f10逐过程、f11逐语句

在linux下如何呢?

r/run ,F5

n/next表示单步执行,不进入函数内部,也就是f10;

s/step表示单步执行,进入函数内部,f11

接下来是类似VS下的监视窗口

以上是:display+变量名    跟踪显示指定变量的值

以上是:undisplay+编号 取消对制定编号的变量的跟踪显示

上图明显undisplay跟dispaly不一样,两者的差别跟b打断点相似,都是有编号的,并且编号是递增的。

接下来是p(print打印)的使用

如图是循环体的两次循环,以及i的两次++,p打印两次i的结果不同。

这里的i是100,那如果是1000、10000呢?那调试就会很鸡肋了。

如何直接跳过并且执行整个循环呢?

首先在Sum函数里打一个断点到return返回值的位置。

其次再学习一个命令c/continue   继续的意思,意义在于断点与断点的跳跃。

或者使用until+行号,这也是一个命令,直接跳到指定行号。

当然看到这里肯定也收获不少,但是gdb很乱不方便我们使用,还不如图形化界面,此时我们就需要下载一个新的东西叫cgdb。

CentOS:sudo yum install -y cgdb

Ubuntu: sudo apt-get install -y cgdb

通过cgdb --version来查看安装结果和版本。

其他的还有finish命令来直接执行一整个函数,方便排查、搜寻错误。

如图finish直接结束整个Sum函数,并且返回结果。

接下来看一下cgdb的界面

这里有两个窗口通过ESC键来进入上面的页面,通过i来进入下面的页面。

很显然打过断点的行有红色行号标记,cgdb更方便使用。

接下来再学习一个指令叫:bt   来查看堆栈情况

以及info local 来查看当前栈帧局部变量的值

相当于VS下的自动窗口

问:调试的本质是什么?

answer:找到问题!而解决bug是目标,因为解决bug是人来操作的。

通过断点+finish+until+c:对大的代码块进行区间debug---》快速定位问题的位置

接下来再学习一个watch,通过watch也相当于打个断点,watch所打断点的变量变了,就会显示出来

这个watch可以用于const常量的watch打断点,因为如果出现没写const,而这个值变了,就会显示出来变化的情况。

再学习一个set var来修改变量的值

比如修改一下代码,增加一个flag,看结果。

接下来makefile用myexe来演示,不用myexe-debug(就改个名字而已)。

如上代码,通过display表达式的值,until到11后发现表达式为0,但是p sum后值是正确的,那么就可以锁定错误的值为flag,但是还要quit出去vim去修改flag的值,但是我现在立刻需要个结果怎么办?

这时就需要set var 变量=变量值

那么如何像vs那样设置条件断点呢?

有两种情况一种是1.新增,另一种是2.给已有断点追加

如上代码:b+行号+if+判断条件就可以设置条件判断,即使用finish结束函数,也只会在此断点打断。

注意:打断点的行号要写循环体内,而不是7,eg:b 8 if i==10,在此之前可以使用display来观察i的值的情况。

上图是两次finish才结束函数体。

接下来是已经存在的断点进行条件判断添加:

通过condition+断点编号+新增条件来给已有的断点设置条件判断

注意与直接设置条件判断断点的区别在于没有if,并且用了condition+断点编号+新增条件的方式来使用。

习题

若基于Linux操作系统所开发的源文件名为test.c,生成该程序代码的调试信息,编译时使用的GCC命令正确的是? 

A.gcc -c -o test.o test.c

B.gcc -S -o test.o test.c

C.gcc -o test test.c

D.gcc -g -o test test.c

答案解析

gcc常见选项:

-c 汇编完成后停止,不进行链接

-E 预处理完成后停止,不进行编译

-S 编译完成后停止,不进行汇编

-o 用于指定目标文件名称

-g 生成debug程序。向程序中添加调试符号信息

根据各个选项作用分析,得到正确答案为D,使用-g选项生成包含有调试信息的可执行程序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值