前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux中的gdb调试

Linux中的gdb调试

作者头像
薛定谔方程难
发布2024-07-30 13:47:35
1160
发布2024-07-30 13:47:35
举报
文章被收录于专栏:我的C语言

1、背景

在Linux命令行中,我们还不知道怎么调试我们编写的代码。按照通常情况来说的话,Windows版本下我们编写代码有debug和release版本,那么Linux下也应该是有这两个版本的,那么我们该如何操作的呢? Linux中gcc/g++出来的二进制程序,默认是release模式。 所以我们需要在gcc/g++的过程中需要加上一些指令。

2、为什么会有Debug与Release版本的区别

Debug版本下通常是程序员用的,能够适合程序员进行程序的调试,而Release版本通常情况下都是发布出来给普通人使用的版本。正常情况下,给程序员使用的版本都会比较大一些,因为需要添加一些调试信息,能够保证调试的时候能够正常的运行。可是对于普通用户来说的话并不需要这些功能,这样的话也就导致,Release版本本身的大小就会比Debug版本小很多。用户只需要能够运行就行了,没必要去调试。 在这种情况之下,就会导致不得不产生两种状态,分别适合于不同的人去使用,一种方便调试,但是可能文件会大一点,一种方便运行,没有多余的信息,文件相对而言大小会少一点。

3、Linux命令语句界面下观察版本区别

代码语言:javascript
复制
gcc/g++ (文件) -g:让编译器在debug模式下编译

如何进行对比比较? 观察大小,因为debug版本下就是会新增一些信息。

果然见到了debug模式下,会大一点。并且要是运行的话,两个生成的文件都能够运行。 想要进一步的查看到底是不是有什么区别的话

代码语言:javascript
复制
readelf -S (文件):查看文件的头部信息

这样就能够看到两者之间的真正的区别了。

debug版本存在这样的区域,而release没有这样的区域。这也就怪不得前面的比后面的文件大了。

4、使用gdb调试的命令

代码语言:javascript
复制
gdb (需要调试的文件):gdb使用方法
//在gdb情况之下的命令
list:查看源文件(可简写为 l )
l n:l是list的缩写,n代表的是查看第几行
l (文件名):n :表示查看指定文件的第n行

上面的操作保证的是所输入的行代表的是,第n行能基本的显示在屏幕的中心位置,并不是说是从15行开始。 可是如果像上面那样操作的话,只能显示出10行,如果想要看到后续的行应该怎么操作呢?

代码语言:javascript
复制
(Enter):按回车
代码语言:javascript
复制
l (函数名):能够直接定位到函数定义的部分,展示文中的内容
其实想看到全文的内容也很简单,直接l 0,然后按回车键直到结尾就行

在Windows之下的vscode中,存在着F5,F9,F10,F11这样的快捷键,方便我们的调试。 那么在Linux中的gdb下,我们应该怎么运行呢? 首先确保的是,程序得先运行起来。所以在gdb下

代码语言:javascript
复制
r/run:运行程序

可是直接运行的话就直接结束了,所以还要再run之前先打一个断点。

代码语言:javascript
复制
b n:在第n行打断点
b (文件):n :在指定文件的第n行打断点
b (函数名):在函数内部第一行打上断点

那我们怎么能够看得出来在哪里打的断点呢? 在有图形化界面的时候能够看到头部的时候会有红点,那Linux下怎么看的出来断点在哪里呢?

代码语言:javascript
复制
info b/i b:查询断点细节

那断点怎么取消呢?

代码语言:javascript
复制
//错误示范
b (文件名):n(行号) :这种方法是错的。
//每个断点都有自己的编号
d n(断点的编号) :去除断点

删除之前的断点的话,继续重新设置断点的话,断点的序号会是线性增长的,不会重复使用。

打完断点之后,重新输入run之后,运行的时候会自动停到打断点的位置。当然了,我们也能够在不删除断点的条件下让断点失去作用。这样的话,算是让断点“失去能量”的效果。

代码语言:javascript
复制
disable n:关闭n号断点的效果

如果运行过程中突然不想运行了,或者换句话说是想要重新运行的话,就需要再输入一遍run命令

再选择y,就能够实现重新运行调试。同样的,如果刚刚还没有重新开始的时候就跟随着文章让断点失去作用的话,现在也应该能够发现现在的断点没有停留在上次的地方,反而是继续向下进了几步。如果断点的位置是空行的话,不会执行停留,会到下一个断点的位置 如果想要打开原本“失去作用的断点”的话应该这样子做

代码语言:javascript
复制
enable n:使能n号断点

那么逐过程和逐语句是怎么实现的呢? 逐过程:遇到函数语句的时候直接执行到最后返回,不会进入函数一行一行的实现。 逐语句:不同于逐过程,会进入到函数中一行一行的执行。 gdb会记住最新一次输入的指令,所以逐过程或者逐语句的时候能够直接一次过后就按回车就行。

代码语言:javascript
复制
n(next):逐过程
s(step):逐语句

那么我们怎么在gdb的情况下查看变量的值呢?

代码语言:javascript
复制
p (想要查询的变量的名称)

前面的$n的意思是代表总共查询了n次。 当然了,能够查看变量的值,也能够查看变量的地址

代码语言:javascript
复制
p &(变量的名称)

还是不够,我们再vs里面查询数值之后就能够直接显示再下面,我们能不能再Linux的gdb也常显示再下方,不要一次一次的重新输入语句来查看变量值呢? 当然!能够实现变量的常显示

代码语言:javascript
复制
display (变量名)

每一个变量面前都是有序列的,这是不是又是似曾相识啊!和原来的断点好像是很像啊,那到底有什么作用呢?下面就来介绍。 怎么取消常显示呢?

代码语言:javascript
复制
//错误示范
undisplay (变量名)
//正确方法
undisplay n(序号名)

怎么实现F5的功能呢?就是实现断点间的过程跳跃呢?

代码语言:javascript
复制
c (continue):实现断点间的跳跃运行
finish:直接执行完所在函数就停下来(逐函数运行)

如果写的一个函数里面有一个比较大的循环的话,我们进来运行几遍发现并没有什么问题,那我们进来了怎么出去呢?

代码语言:javascript
复制
until (行):跳转到指定行(中间部分的代码都是运行了的)

额外的几个小点

代码语言:javascript
复制
info locals/i locals:查看当前栈帧的变量
set var (变量名)=(数值):设置变量为指定的数值
bt:查看调用栈

5、命令总结

对于基础代码还是很方便使用的,但是到后期的时候,调试大代码的时候可能就是会有一些难以解决的问题。所以后期的时候,我们就会将Linux远程连接到我们本地的vscode就能够相对于是方便我们的使用。 那为什么我还会写这篇文章呢?那是因为即使是有图形化界面能够方便我们去进行一系列的操作,但是对于学习来说,我们还是需要去理解命令行的含义的,需要理解服务器的基本指令的。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-07-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、背景
  • 2、为什么会有Debug与Release版本的区别
  • 3、Linux命令语句界面下观察版本区别
  • 4、使用gdb调试的命令
  • 5、命令总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档