0


【Linux】Linux调试器-gdb使用

个人主页 : zxctscl
如有转载请先通知

文章目录

1. 前言

在前面的博客【Linux】编译器-gcc/g++使用已经分享了关于编译器的使用,而编译器的使用离不开调试,这次就来分享一下Linux调试器-gdb使用。

2. 调试前准备

要调试就得先有代码,先用C语言写一段简单的代码myprocess.c,再写好Makefile:
myprocess.c代码:

1#include<stdio.h>23   int AddToTarget(int start,int end)4{5   int i=start;6   int sum=0;7   for(i=start;i<=end;i++)8{9sum+=i;10}11returnsum;1213}14 int main()15{16   printf("run begin...\n");1718   int result=0;19result=AddToTarget(1,100);20   printf("result:%d\n",result);2122   printf("run end...\n");23}

Makefile:

1 myprocess:myprocess.c
  2   gcc -o$@ $^
  3 .PHONY:clean
  4 clean:
  5rm-f myprocess

make一下没有问题:
在这里插入图片描述
在这里插入图片描述

在vs发布软件有两种模式一种是debug,一种是release。
测试用的是debug,可以被跳绳,而开发出来的release版本,是不可以调试的。

在debug版本中,编译器形成可执行程序的时候,会给可执行程序添加调试信息。

gcc/g++默认编译,采用的是release模式
在这里插入图片描述

如果想让gcc/g++采用debug模式,就得再后面加上-g选项
在这里插入图片描述

怎么来判断是不是debug模式呢?
在debug模式下新加了调试信息,体积就会比release模式下的大,那么就确定debug模式会新增加东西。
来测试一下:在Makefile里面新加-g选项:

1 myprocess-debug:myprocess.c
  2   gcc -o$@ $^ -g3 .PHONY:clean
  4 clean:
  5rm-f myprocess

然后make一下:
发现两个程序都可以跑:
在这里插入图片描述
对比发现debug的体积比较大:
在这里插入图片描述
为了给用户更好的体验,发布release模式,减少了不必要的调试,也减小下载时带宽的浪费。
而程序员在写代码的时候需要调试,所以就有了release模式和debug模式。
在这里插入图片描述

读一下debug模式下的信息:

readelf -S myprocess-debug

发现下面有debug信息
在这里插入图片描述
忽略大小写信息,在debug下的调试信息:

readelf -S myprocess-debug |grep-i debug

在这里插入图片描述
用同样的方式来查看release版本下的调试信息:

readelf -S myprocess | grep -i debug

发现没有debug信息
在这里插入图片描述

3. 使用

3.1 进入gdb

默认系统中会安装gdb,使用方法就是gdb后面直接加上调试的可执行程序名:

 gdb myprocess-debug

就会默认进入到调试模式
在这里插入图片描述
想要退出就直接输入quit或者q

quit/q

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
gdb本身就是一个进程,把程序启动起来
在这里插入图片描述

3.2 list

list来显示程序代码

list

在这里插入图片描述
list后面直接更程序名是查不了代码的:
在这里插入图片描述
在这里插入图片描述
**为了方便list可以直接简写为

l

。**

如果想要从程序第一行开始查就用命令:

l 0

在这里插入图片描述

还可以使用l加程序名再加0的方式

l myprocess.c:0

在这里插入图片描述
不可以直接查文件,但是加上行号就可以查。
还可以查main函数:

l myprocess.c:main

在这里插入图片描述
想要查某一块代码可以加上行号,也可以加上对应的函数名就可以了。
在这里插入图片描述
发现gdb查代码只能默认查10行
在这里插入图片描述
如果想要全部打出来怎么办?
gdb默认会记录用户最近的一条命令,直接按回车
就可以拿到全部的代码
在这里插入图片描述
在这里插入图片描述
如果查看第15行:
在这里插入图片描述
发现它并不是从15行开始,而15行差不多是在显示的代码中间的位置。
同样查看AddToTarget也是:
在这里插入图片描述

l查指定的行或者函数时候,会显示它的上下文。

3.3 run

run

就是把程序运行起来,简写为

r


在这里插入图片描述
这个run的功能就类似于VS里面的F5,直接运行不调试。

3.4 与断点有关操作

3.4.1 b打断点

gdb中用b来打断点
可以直接用b加程序名加函数
比如在main函数处打一个断点:

b myprocess.c:main

在这里插入图片描述

比较一下发现,代码断点并不是打在15行位置,而值17行,因为17行是main函数的入口位置:
在这里插入图片描述
在第20行打断点,直接这样:

b myprocess.c:20

在这里插入图片描述
因为每个断点都有自己的编号
在这里插入图片描述
在这里插入图片描述
想要连续打断点,怎么办呢?
如果加上“,”发现不能用。
在这里插入图片描述
试一下空格:发现也不行
在这里插入图片描述
所以断点不允许连续去打,而必须一个一个去打:
在这里插入图片描述
而这里的断点编号是3和4,因为1和2在前面已经用了。

所以断点的本质是一个线性增长的计数器。
代码运行到断点位置就会停下来:
在这里插入图片描述

3.4.2 info显示断点位置

info(或i) breakpoints

:参看当前设置了哪些断点

info(i) locals

:查看当前栈帧局部变量的值
在vs下打断点就会有红点
在这里插入图片描述
那么在gdb下怎么知道哪些地方打了断点呢?
这里就要用到一个命令info

info b

或者写成:

i b

就能显示出来在哪些地方打了断点:
在这里插入图片描述
这里的Enb表示使能,代表一定有断点,但不一定打开。而这里的y表示断点打了能用。
在这里插入图片描述
info查当前变量的值:
在这里插入图片描述

3.4.3 d去断点

在vs里面要取消断点直接点一下或者按F9。
在gdb下用的是d加文件名加行号,发现不能用
在这里插入图片描述

删断点就要用这里的Num:
在这里插入图片描述
删除一号断点:

d 1

在这里插入图片描述

再删除2号断点
在这里插入图片描述
此时已经没有断点了。

3.4.4 disable使能

在vs中在断点位置右击可以禁用断点:
在这里插入图片描述
在调试的时候就会跳过禁用的断点:
在这里插入图片描述
也就是把这个断点使能了。

而在gdb中也想这样做,那么就用下面这个命令:

disable Num

试一下myprocess.c里面的3号断点:

disable 3

发现3号断点的Enb就变为n了:
在这里插入图片描述
在这里插入图片描述
重新运行一下代码:发现停在了19行,因为17行的断点使能已经关闭,而18行是空行,就直接到了19行:
在这里插入图片描述
空行是不做调试的,打了断点也没用。
在这里插入图片描述
在vs里面要想启动断点,直接右击就会出现
在这里插入图片描述
而在gdb中重新启动,想要用到命令:

enable Num

重新启动3号断点:

enable3

发现这里的3号断点的Enb就变为y了
在这里插入图片描述
在这里插入图片描述

3.5 next/n逐过程

在vs里面的F10就是逐过程,就是在调试时候单步往下走时,如果碰见当前行的代码是函数,就直接把这个函数执行完,把这个函数当成一条语句直接执行完。
在gdb中想要实现逐过程就得用到命令:

next/n

打了一个断点在17行:
在这里插入图片描述
然后用来实现逐过程调试:发现并没有进入到AddToTarget函数里面:
在这里插入图片描述

3.6 step/s逐语句

在在vs里面的F11就是逐语句,在调试的时候,遇到函数就要进到这个函数里面,把这个函数里面的代码一行一行运行完。

在gdb中想要进入到函数的内部就用命令:

step/s

打了一个断点在17行:
在这里插入图片描述
然后用来实现逐语句调试:发现进入到AddToTarget函数里面:
在这里插入图片描述
发现这个代码就在7和9行之间反复执行:
在这里插入图片描述

3.7 print/p查看变量内容及地址

print/p查看变量内容及地址
在vs里面常用的监视窗口:
在这里插入图片描述
而在gdb中用到的命令就是:

 print/p

来试一下:
这时就能看到i对应的值了:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
查里面的地址就加上取地址符就行:
在这里插入图片描述

3.8 display常显示

每次都先输入p才能查看监视的内容,太麻烦,就用display来进行常显示,每次都自动变化:

display

在这里插入图片描述
它也可以来查看地址:
在这里插入图片描述
在这里插入图片描述

3.9 undisplay

发现每一次常显示前面都会有一个编号:
在这里插入图片描述

如果不想常显示,就用到undisplay去掉常显示

undisplay+编号

去掉5号和4号监视:
在这里插入图片描述

3.10 continue/c运行到下一个断点处

一般在vs里面可以直接从一个断点处运行到下一个断点处,就是执行中间那一部分。
而在gdb中想要一个部分一个部分的调试,从而方便找出代码的问题,就用到命令:

continue/c

先打一些断点;
在这里插入图片描述
此时运行的时候就发现在17行就停下来了:
在这里插入图片描述
想要直接从一个断点运行到下一个断点处就直接:

c

在这里插入图片描述

3.11 finish

finish运行结束所在函数,就停下来
如果函数里面有问题,在不进入函数里面,就想知道函数有没有问题,就用到命令:

finish

finish就是把指定的函数跑完
来测试一下:
在这里插入图片描述

3.12 until

until:跳转到指定行,中间的代码都是运行了的。
进入到函数体里面就退不出来

在这里插入图片描述
如果想要跳转到某一行,就用到命令:

until

试一下跳转到12行:
在这里插入图片描述
总结一下gdb使用就是:
在这里插入图片描述
set var:修改变量的值
把指定变量直接修改为目标值,然后检测等于这个目标值时会不会执行对应代码。
举个例子:把i值改为100
在这里插入图片描述

3.13 bt

bt就相当于调用堆栈
在这里插入图片描述

有问题请指出,大家一起进步!!!

标签: linux chrome 运维

本文转载自: https://blog.csdn.net/zxctsclrjjjcph/article/details/137337957
版权归原作者 zxctscl 所有, 如有侵权,请联系我们删除。

“【Linux】Linux调试器-gdb使用”的评论:

还没有评论