Linux 中的调试器 gdb 的基本使用

Linux 中的调试器 gdb 的基本使用

在这里插入图片描述


每博一文案

有人说,小孩子才会仰天大哭。
成年人的世界早就都调成了静音模式,连崩溃也很懂事。
一路走来,我们一边受伤,也一边变得更坚强,慢慢的不再逢人就笑了,
也不再期待谁的拥抱了。我们习惯了一边打伞一边奔跑,在没人帮的时候,
学会了独立,也在没人疼的时候学会了自愈,明白了,想要去的地方,要
自己走过去。想要的安全感也只能自己给,没有人生来坚强,只是后来学会了隐藏。
听说这样一句话,时间顺流而下,生活逆水行舟,人生不可能一帆风顺,经历
过磨难在所难免。很多时候,我们都是逼自己穿起了戎装,硬着头皮去面对,
不愿在人前展露出一丝一毫的脆弱。仿佛一旦示弱,就会被生活生吞活剥。
其实这个世界上没有那么多的感同身受,有的,只是冷暖自知,你的眼泪,只有关心你的
人心疼,你的笑容,也只有在乎你的人重视。
所以不要把硬扛伪装成坚强,把困难修饰成笑脸,只为了让自己看起来还算体面。
你的眼睛很漂亮,看错人没关系,爱流泪,也没关系。
                                        ————————     一禅心灵庙语



调试

调试(英语:Debugging / Debug) ,又称除错 ,是发现和减少计算机程序或电子仪器设备中程序
错误的一个过程。

调试 是为了定位出现问题的存在位置(行号,区域)——>从而分析问题——> 解决问题——> 问题的最优解

调试的步骤

  1. 发现程序错误的存在
  2. 以隔离,消除等方式对错误进行定位
  3. 确定错误产生的原因
  4. 提出纠正错误的解决方法
  5. 对程序错误给予改正,重新测试

Debug和Release的介绍

  • Debug 通常称为调试版本 ,它包含调试信息,所以并且不作任何优化,便于程序员调试程序。

  • Release 称为发布版本 ,不包含调试信息的,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用,注意: Release 因为不含有调试信息,所以是不可以调试的。

  • DebugRelease 最主要的区别就是: Debug 含有调试信息,可用于程序员调试代码,因为包含有调试信息,所哟一般的 Debug 版本的存储大小上会比 Release 版本的存储大一些,而Release 因为没有调式信息,所以存储大小上比较小并且无法 调试 ,但却是优化了的


gdb 调试器的使用

在Linux gcc/g++出来的二进制程序,默认是release模式 ,是无法调试的,要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 -g 选项 ⭐⭐⭐⭐⭐⭐

如果没有在Linux 中没有 gdb 调试器需要安装一下

[linux@localhost dir2]$ sudo yum install -y gdb.x86_64 

安装好以后,我们需要编写一个C语言程序用于调试演示使用,代码如下

#include<stdio.h>    

void func()    
{    
  int i = 0;    
  for(i= 0;i<10;i++)    
  {    
    printf("hello world\n");    
    
  }    
    
}    
    
int main()    
{    
  printf("hello\n");    
  func();                                                                             
  return 0;    
}   

在这里插入图片描述


我们知道,在Linux gcc/g++出来的二进制程序,默认是release模式 ,是无法调试的,要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 -g 选项 ⭐⭐⭐⭐⭐⭐,先测试一下使用

  1. 使用 gcc 编译我们的C语言程序,这里我们不带上 -g 试试可否调试, 对于 gcc 不懂的可以移步到 🔜🔜🔜 Linux编译器-gcc的使用_ChinaRainbowSea的博客-CSDN博客
[linux@localhost dir2]$ gcc test.c -o mybin
  1. 使用 gdb 调试工具,gdb 的使用格式
[linux@localhost dir2]$ gdb mybin
gdb + 文件名(你所需要调试的文件名)

在这里插入图片描述

从图上我们可以看到,出现了 (no debugging symbols found)…done. (没有找到调试符号)的提示,原因是:在Linux gcc/g++出来的二进制程序,默认是release模式 ,无法调试的,所以才出现了这样的提示。

我们可以退出 gdb 调试器,重新生成一个 Debug 可调试版本的,我们使用命令 quit 退出 gdb 调试器

(gdb) quit

在这里插入图片描述


我们需要生成的是 Debug 可调试版本的,需要在 gcc 的最后加 -g 就可以生成的是可调试Debug版本的了

[linux@localhost dir2]$ gcc test.c -g -o mybin_d

在这里插入图片描述

我们明显可以看到 Debug 的mybin_d 的存储大小上是比 Release 版本的大一些的,

我们再使用 gdb 调试器,调试 Debug 文件的 mybin_d

[linux@localhost dir2]$ gdb mybin_d

在这里插入图片描述

从结果上我们可以看到已经没有所谓的 (no debugging symbols found)…done. (没有找到调试符号)的提示了,下面我们就可以,进入gdb 的调试命令中了


gdb的基本调试命令

gdb binFile 退出: ctrl + d 或 quit 调试命令:
(gdb) list/l 行号:显示binFile源代码,接着上次的位置往下列,每次列10行。[重要]⭐⭐⭐
(gdb) list/l 函数名:列出某个函数的源代码。
(gdb) r或run:运行程序,在断点处停止。[重要]⭐⭐⭐

(gdb) n 或 next:单条执行于 ,类似于VS 中的 F10 ,逐过程,就是不会进入到函数中去。[重要]⭐⭐⭐
(gdb) s或step:进入函数调用,类似于 ,VS 中 F11的逐语句,就是一步一步的向下执行,会进入函数中去[重要] ⭐⭐⭐
(gdb) break(或b) 行号:在某一行设置断点,+行号 [重要]⭐⭐⭐
(gdb) break(或b) 函数名:在某个函数开头设置断点 ,+ 函数名
(gdb) info break(或 info b) 查看所有断点信息。⭐⭐⭐
(gdb) finish(或f):执行到当前函数返回,然后挺下来等待命令,就是跳出函数,然后停下来
(gdb) print(或p):打印表达式的值,通过表达式可以修改变量的值或者调用函数
(gdb) p + 变量名:打印变量值。[重要]⭐⭐⭐
(gdb) set var:修改变量的值
(gdb) continue(或c):从当前位置开始连续而非单步执行程序(就是跳转到下一个断点处)[重要]⭐⭐⭐
(gdb) run(或r):从开始连续而非单步执行程序
(gdb) delete breakpoints:删除所有断点
(gdb) delete breakpoints n:删除序号为n的断点[重要]⭐⭐⭐
(gdb) disable breakpoints:禁用断点
(gdb) enable breakpoints:启用断点
(gdb) info(或i) breakpoints:参看当前设置了哪些断点
(gdb) display 变量名:跟踪查看一个变量,每次停下来都显示它的值
(gdb) undisplay + 编号:取消对先前设置的那些变量的跟踪
(gdb) until X行号:跳至X行
(gdb) breaktrace(或bt):查看各级函数调用及参数
(gdb) info(i) locals:查看当前栈帧局部变量的值
(gdb) quit:退出gdb


这里我们就简单的讲解一个比较重要的命令

  1. 我们可以在 gdb 调试器中查看我们的代码,我们可以使用命令 gdb) list/l + 行号 :显示源代码,每次显示10 行,因为 gdb 有记忆命令的能力,会将最近的一次命令记录下来,所以当你使用回车键的时候,接着上次的位置往下列 l2、l3 的往下,每次列10行
(gdb) l 1

在这里插入图片描述

(gdb) + 回车键

在这里插入图片描述

  1. 我们知道进入调试的后,我们需要设置一个断点,让程序在该位置停下了,好一步一步的查看运行过程,这里我们使用 命令 (gdb) break(或b) + 行号 :在某一行设置断点 ,设置成功后,会打印显示该断点信息
(gdb) b 5
在第 5 行处设置断点

在这里插入图片描述


  1. 使用命令 (gdb) r或(run) :运行程序,在断点处停止,跳转到断点处,等同于 VS2019中的 F5 ,如果没有设置断点,就会直接运行到结束
(gdb) r

在这里插入图片描述

还有就是当还没有结束调试时,再一次使用 r 命令会,会提示你**(Start it from the beginning? (y or n))** 是否重新开始调试,你回答 y 就是重新开始调试,你回答 n 就是不重新调试,结束调试

在这里插入图片描述


  1. 程序运行到断点处后,我们可以根据需要调试代码,这里我们可以使用 (gdb) n 或 next :单条执行 ,类似于VS 中的 F10 ,逐过程,就是不会进入到函数中去
(gdb) n

因为gdb 有记忆命令的功能,我们最近使用一次了,就可以使用 回车键来代替了

在这里插入图片描述


  1. 我们可以使用命令查看 变量、或者是变量的地址的在运行过程中的变化情况(gdb) display +(变量名/&变量的地址) :跟踪查看一个变量,每次停下来都显示它的值
(gdb) display i
(gdb) display &i

在这里插入图片描述


  1. 同样我们也是可以 取消对应的变量值和地址的显示的,使用命令**(gdb) undisplay + 编号** :取消对先前设置的那些变量的跟踪,注意 接的是编号
(gdb) undisplay 2
取消编号为 2 对应变量的显示

在这里插入图片描述


  1. 当我们需要跳到指定的行位置时,使用**(gdb) until +(X行号)** :跳至X行的位置
(gdb) until 10
跳到 第 10 行位置

在这里插入图片描述


  1. 当我们需要跳出函数的时候,可以使用**(gdb) finish(或f)** :执行到当前函数返回(就是运行到返回值,结束函数),然后挺下来等待命令,就是跳出函数,然后停下来
(gdb) finish

在这里插入图片描述


  1. 当我们需要进入到函数里面的时候,可以使用命令**(gdb) s或step** :进入函数调用,类似于 ,VS 中 F11的逐语句,就是一步一步的向下执行,会进入函数中去
(gdb) s

在这里插入图片描述


10 . 我们可以删除不必要的 断点(gdb) delete breakpoints n简写为(d + 断点编号) :删除序号为n的断点[重要]注意 后接的时断点编号,所以再删除断点之前,我们需要查到知道我们需要删除的断点的信息使用命令**(gdb) info break(或 info b)** 查看所有断点信息

(gdb) info b

在这里插入图片描述


删除断点

(gdb) d 1
删除后,再使用命令查看是否删除成功
(gdb) info b

在这里插入图片描述


  1. 我们还可以使用命令,再断点处,跳转 (gdb) continue(或c) :从当前位置开始连续而非单步执行程序(就是跳转到下一个断点处)
(gdb) c

在这里插入图片描述


最后调试完,找到了错误位置及其原因,退出gdb 调试器,可以使用命令 quit 退出 gdb 调试器,或者是 快捷键 Ctrl + D


最后:

限于自身水平,其中存在的错误,希望大家给予指教,韩信点兵——多多益善,谢谢大家,后会有期,江湖再见!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值