Linux调试器:gdb
- gdb简介
- 基本使用和常见的指令
- 断点相关
- 运行相关命令
gdb简介
我们都知道一个程序一般有两个版本分别是debug,和release版本,后者就是发布给用户的版本,而前者就是我们程序员用来调试用的版本。
他们有什么区别呢:因为最终面向的是用户这一个群体,而他们并不需要了解这些调试信息,他们需要更加快速的下载和安装,所以二者最大区别就是大小的不同,debug比release要更加大并且给程序员添加了调试信息。
下面我们来讲解它的使用方法和一些基本指令操作
基本使用和常见的指令
第一步:yum -y install gdb
安装gdb
在使用它调式之前,我们需要知道的是使用gcc编译一个源文件的时候默认的release编译,那我们怎么切换到debug模式呢gcc -o -g XXX
只需要在编译的时候加上-g
命令就可以了
而二个我们需要了解的点是:调试究竟在干什么?
其实就两方面:
1、找到问题(其中包括:查找,范围查找以及局部逐行查找)
2、解决问题(联系上下代码)
那在Windows中我们使用的VS有以下的调试方式:
显示代码
运行
打断点
局部调试
显示局部变量的值和地址
显示调用栈
逐行执行
逐语句执行
现在我们在Linux中相当于用gdb来平替VS的调试功能
下面我们来看
首先gdb XXXX(文件名)
来运行起来
然后我们需要显示我们的代码才能方便调试:l +行号(显示指定行号后面的代码)
这里补充一点,gdb中默认会自动记录最近的一条指令,但是我们使用l +行号
的命令一般不会将代码显示完全,所以我们可以直接enter回车
,直到显示完我们代码为止。
也可以使用l +函数
的命令显示指定函数的代码:
并且如果有多文件的话,也支持l+文件名+行号
显示对应的文件的行号代码内容:
断点相关
增加断点:b(breakpoints)
+对应行号,并且用info b
命令查看增加的断点信息
这里展示的信息Num表示是第几个断点,Enb
表示这个断点是否有效,比如我设置了这个断点但是我不想让它生效,这时我们就可以用disable +断点序号
来使它无效化
这里可以看到Enb这一列变为了n也就是‘no’,这里需要的注意到是gdb中关于断点的操作,删除,无效化都必须是使用它的序号而不是使用断点对应的行号,这和VS中的就不相同,这也是感觉使用起来很不好的一点。
无效化相反的有效化就是enable +断点序号
比如删除:d +断点对应序号
:
运行相关命令
首先最开始的肯定是让程序先跑起来再谈调试什么的:r(run)
逐过程:首先理解什么是逐过程,就是把每一行代码都当作一个过程逐行执行,并不会进入函数内部
命令:n(next)
对应的逐语句:s(step)
这里可以看到进入到了handle这个函数的内部
那么我们如果想结束这个函数怎么办呢?:finish
可以看到finish
后直接执行完这个函数
下面我们在while这一行增加一个断点,进入到这个循环,并且我们想知道循环几次后i的值是多少,这时候就可以用p +变量名显示
那如果我们需要这个变量一直显示呢?可以用display +变量名
可以看到此后运行代码,i变量一直都是常显示的,并且还可以取其地址
相反用undisplay +变量名
来取消
另外如何从一个断点跳转到另一个断点呢?
命令:c(continue)
可以看到从14行跳到了19行
如果我们还想指定运行到指定行号呢?:until +行号
下面补充两个命令:
查看堆栈:bt
可以看到调用的main函数和handle函数
以及设定变量的值set var 变量名=value
比如这样一个场景我们定义的tmp变量等于1的时候执行一个逻辑,等于0是另一个逻辑,为了调试不同分支的代码,我们就可以用这个命令
最后想说的就是我们调试代码可以用二分的一个思想,如果代码有问题先把后一半注释掉,执行,如果没问题,再注释掉一半,继续下去,如果出问题可以在把它分为不同模块来调试,另外如果一个循环太多,不用逐语句执行,可以先用n
命令执行完看这个函数有没有问题,因为不管是n
命令还是until
它们都不止是简单的跳转到某一行而是执行完了对应区域的代码。
以上就是Linux中gdb调试器的一些常见的命令以及使用,如有问题,欢迎指正,谢谢大家!