【Linux】gdb-调试代码的工具

目录

一、概述

1.1 gdb是什么

1.2 为什么要使用gdb

二、gdb的简单使用

2.1 安装gdb

2.2 软件的debug版本和release版本

2.3 常用的gdb命令


在之前的学习中,我们已经能够用vim编写和gcc/g++编译代码了,下面来学习如何调试代码。

一、概述

1.1 gdb是什么

在Linux系统中,GDB(GNU Debugger)是一个强大的、灵活的、开源的调试工具,用于对程序进行调试。它允许开发人员在程序崩溃或者运行出错时检查程序的内部状态,跟踪代码的执行过程,并尝试找出程序中的错误。

gdb是 GDB 命令行工具的缩写形式,可以在终端中使用该命令启动 GDB 调试器。

1.2 为什么要使用gdb

我们在编写代码时总会有各种各样的错误,这些错误基本可以分为两类:

  1. 语法错误:编译器会报错,解决比较方便
  2. 逻辑错误:此时就需要调试代码

虽然我们有各种各样的IDE,但是对于从事 Linux C/C++ 开发的程序员来说,大多数都需要熟悉gdb调试工具。尤其当不具备IDE的环境时(嵌入式系统等资源限制的场景),gdb以其占用资源少、开源免费和方便实用的优势被广泛使用。

二、gdb的简单使用

在Linux下调试代码分为两步:

  1. 调试代码的思路。
  2. 调试代码的工具。

确定问题、分析缩小范围、找到问题所在、提出解决方案。这种调试代码的思路都是一样的,所以调试代码侧重点在于把调试思路用在gdb这个调试工具上

2.1 安装gdb

  1. 打开终端并输入以下命令来安装gdb:
    sudo yum install -y gdb
  2. 安装完成后,您可以使用以下命令来验证gdb是否成功安装:
    gdb --version

2.2 软件的debug版本和release版本

程序的发布方式有两种,debug模式和release模式,debug模式可以被调试,release版本用于测试和发布。
原因:测试人员要测试的代码,必须是用户最终用的,debug版本有很多调试信息,这些信息用户不需要而且也会使软件资源占用较大。release版本的代码都是用户需要的。

使用 gdb <可执行程序名>  即可进入调试模式,

但要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 -g 选项,否则报错。

Linux gcc/g++出来的二进制程序,默认是release模式。 
证明:1.在debug发布的时候,一定要给可执行程序内部添加debug信息,否则无法调试!
           2.release文件更小

我们在Linux中形成的可执行程序格式:ELF格式  ,包含很多可执行程序的信息,如代码开始和结束的位置,用以下命令读取。

readelf -S <可执行程序名> -g | grep -i debug

-S 读取二进制文件构成, -i 忽略大小写

执行readelf -S <可执行程序名> -r | grep -i debug  不会显示信息,因为没有release版本没有调试信息。

结论:如果你想让你的程序被调试,必须加 -g 以debug方式发布!

2.3 常用的gdb命令

使用 gdb <可执行程序名>  即可进入调试模式,q 退出

 常用的 gdb 命令:

  • list(l) 行号:显示binFile源代码,接着上次的位置往下列,每次列10行。
  • list(l) 函数名:列出某个函数的源代码。
  • run(r):运行程序。
    类似vs的F5,没有断点是直接运行。
  • next(n):单条执行。
    类似Vs的F10
  • step(s):进入函数调用
    类似Vs的F11
  • break(b) 行号:在某一行设置断点
    b 18 给当前文件18行打断点
    b mycode.c:20    在mycode.c的第20行打断点
  • break(b)  函数名:在某个函数开头设置断点                     
    b main    在main函数的入口处打断点
    b mycode.c:ADD   在mycode.c的ADD函数的入口处打断点
  • info(i) break(b) :查看断点信息。

    Enb:使能,即断点有没有开启/生效
  • finish:执行到当前函数返回,然后停下来等待命令
    运行一个函数至函数完成
  • print(p):打印表达式的值,通过表达式可以修改变量的值或者调用函数
    print(x+1) 将输出 x+1 表达式的计算结果。
  • p 变量:打印变量值。
    p x 将输出变量 x 当前的值
  • set var:修改变量的值
    不是一直执行到变量为该值,而是直接修改变量,最终结果可能不符合期望,例如累加。
    常用于条件判断
    用法:set var i = 99    将 i 的值改为99
  • continue(或c):从当前位置开始连续而非单步执行程序
    从一个断点运行到下一个断点处
  • run(或r):从开始连续而非单步执行程序
  • delete breakpoints:删除所有断点
  • delete breakpoints n:删除序号为n的断点
  • disable breakpoints:禁用断点
    断点存在,但是不起作用
  • enable breakpoints:启用断点
    与 disable 相反,该命令将启用当前所有被禁用的断点,使它们重新生效。
  • display 变量名(或变量的地址):跟踪查看一个变量,每次停下来都显示它的值
    长显示一个变量,并带上编号,从下往上递增
  • undisplay n:取消对先前设置的序号为n的变量的跟踪
    取消长显示,序号递增不会重复
  • until X行号:跳至X行
    如果目的行不是有效代码( '{' '}' 或空格 ),将会跳到下一个有效代码的位置。
    不用打断点就可以跳到指定行,常用于循环。
  • breaktrace(或bt):查看各级函数调用及参数
    查看调用堆栈
  • info(i) locals:查看当前栈帧局部变量的值
  • quit:退出gdb

注:

  1. list可简写成 l ,break 可简写成 b ,print 可简写成(p),continue 可简写成 c ,
    run可简写成 r ,info 可简写成 i ,quit 可简写成 q
  2. gdb会记录最近执行的命令,按回车键可执行上一次的命令。
    例如输入 l 后,按回车键直接继续向下展开代码,直至结束,不用再输入“l 行号”。
  3. gdb文件可以根据文件的行号、文件名打断点,但是删除断点时不能使用行号或函数名,只能根据断点编号删除(使用info b查看)
  4. 在一个调试周期中,断点的编号是一直递增的,一个编号只会出现一次,退出gdb模式时,所有的断点信息被清空

以上所讲都是常用命令,希望大家能够熟练使用,也希望大家能在网上搜索和学习gdb的其他使用方法。

  • 23
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值