当前位置: 首页 > article >正文

【Linux学习】(9)调试器gdb

前言

Linux基础工具:安装软件我们用的是yum,写代码用的是vim,编译代码用gcc/g++,调试代码用gdb,自动化构建用make/Makefile,多人协作上传代码到远端用的是git。

在前面我们把yum、vim、gcc、make、git都已经学习了,今天我们就将学习最后一种基础工具gdb调试器

调试器gdb

1. 背景——debug和release

  1. 源文件编译时有有两种模式,debug模式和release模式
  2. debug通常称为调试版本,它包含调试信息,并且不做任何优化,便于程序员调试程序(因为debug模式在形成可执行程序的时候,添加了debug信息,所以可以被追踪调试)
  3. release称为发布版本,它往往是进行了各种优化,是程序在代码大小和运行速度上都是最优的,以便用户很好的使用
  4. 在Linux系统上gcc/g++形成的可执行程序,默认是release版本
  5. 如果想以debug形式编译,我们需要添加-g选项(-g生成调试信息)
  6. 验证:readelf -S指令可以读取可执行程序对应的二进制构成,再通过grep debug可以将debug信息过滤出来在这里插入图片描述

2. 使用gdb

  • 启动gdb:gdb 可执行程序
  1. 调试需要启动gdb在这里插入图片描述
  2. 注意在Linux系统上gcc/g++形成的可执行程序,默认是release版本。
  3. 如果想以debug形式编译,我们需要添加-g选项
  • 退出gdb:quit/q
  1. 调试结束,退出gdb在这里插入图片描述
  • 查看到调试的代码:list/l
(gdb) l		#list不一定从第一行开始显示调试代码,并且只显示一部分代码
(gdb) l n	#指定显示第n行调试代码
(gdb) l function	#指定显示某函数的代码块
(gdb) l [begin,end]	#指定显示某区间的代码块
  1. list查看调试代码,注意list不一定从第一行开始显示调试代码,并且只显示一部分代码在这里插入图片描述
  2. 如果我们想从第一行开始显示所有调试代码,list 0之后继续不断list或者直接回车即可显示所有代码在这里插入图片描述
  3. gdb会自动记录最近一条指令
  • 运行程序:run/r
  1. 运行程序,直到遇到断点或者程序运行结束在这里插入图片描述
  2. 在gdb中的run指令相当于VS中运行的快捷键Ctrl+F5
  • 设置断点:break/b
(gdb) b 行号	#在某一行设置断点
(gdb) b 函数名	#在某一个函数开头设置断点,即函数代码块的起始位置第一条有效语句
(gdb) b 文件名:行号N	#在某个文件的第N行打断点,即跨文件设置断点
(gdb) b 文件名:函数名	#在指定文件的指定函数设置断点
  1. 要调试代码,我们一般都需要先设置断点在这里插入图片描述
  2. 在VS中我们设置了断点,就可以在该代码行的最左侧显示一个红点,表示在当前行设置了断点,但是在gdb中它不是图形化界面,不会显示红点也没有任何提示,那我们在gdb中我们如何知道在哪里设置了断点了
  • 查看断点信息:info break
  1. 查看断点信息在这里插入图片描述
  2. 注意当我们退出了gdb,那我们在上一次所有设置的断点就没有了
  • 删除断点:delete/d
(gdb) delete [breakpoints] n	#删除断点编号为n的断点
(gdb) delete [breakpoints]		#删除所有断点
  1. 注意删除断点是根据断点编号删除的,不能像通过断点的行号删在这里插入图片描述
  2. 删除所有断点在这里插入图片描述
  • 禁用断点:disable
(gdb) disable 断点编号N	#禁用断点编号为N的断点
  1. 有的时候我们不想删除某个断点,但也不想使这个断点起效那该怎么办呢——禁用断点在这里插入图片描述
  2. 不想删某个断点是因为想保留调试的痕迹,不想使这个断点起效是因为我们已经确定问题不在该断点处
  • 启用断点:enable
(gdb) enable 断点编号N	#启用断点编号为N的断点
  • 逐语句和逐过程:step/s & next/n
  1. 我们调试代码一般先run将代码运行至断点停下来之后,就需要逐语句或逐过程一步一步慢慢的调试代码找出问题所在
  2. 逐语句和逐过程:
    • 逐语句:遇到函数,进入函数体中,不跳过函数体中的语句
    • 逐过程:把函数也当做一个语句,直接调试到下一条语句
    • 区别:逐语句和逐过程都是一次执行一条语句,唯一的区别就在于逐语句会进入函数,逐过程不会进入函数在这里插入图片描述
  3. gdb调试会直接跳过空行,跳转到下一句有效代码处
  4. 我们现在可以gdb中设置断点,逐过程的调试代码了,但是在调试代码时我们还需要监视变量
  • 打印变量值:print/p 变量
  1. 打印变量值在这里插入图片描述
  2. 但是我们发现print打印变量的值不能边调试边打印变量值,即不能常显示变量值
  • 边调试边打印变量值(常显示变量值):display 变量
  1. 跟踪查看一个变量,每次停下来都显示它的值在这里插入图片描述
  • 取消常显示变量值:undisplay
(gdb) undisplay 变量编号	#取消指定变量编号的常显示
(gdb) undisplay			#取消所有变量的常显示
  1. 取消对常显示变量的监视,注意不是通过变量名取消的,而是通过变量编号取消的在这里插入图片描述
  • 跳转到N行:until 行号N
  1. 例如现在我们的代码陷入到了一个循环中,我们想直接把这个循环执行完,那就可以使用until直接跳转到循环的下一行在这里插入图片描述
  • 快速调试一个函数是否有bug:finish
  1. finish:执行到当前函数返回,然后停下来等待命令在这里插入图片描述
  2. 注意:使用finish需要先进入到函数
  • 从一个断点处运行到下一个断点处:continue/c
  1. continue:从当前位置开始连续而非单步执行程序,一般用于从一个断点处运行到下一个断点处在这里插入图片描述
  2. run VS continue
    • run:从开始连续 而非单步执行程序——一般run运行程序到第一个断点处停下来
    • continue:从当前位置开始连续 而非单步执行程序——一般continue从当前断点运行到下一个断点停下来
  3. until & finish & continue
    • until:在函数内范围式 的运行
    • finish:按函数为单位 的运行
    • continue:从一个断点到下一个断点 大面积的范围式的运行
    • 调试:调试的本质是先一定要找到问题,只有找到了问题位置,才能通过分析它周边的数据,分析上下文,分析出问题出错的原因,原因清楚了,我们才知道对应的解决方案!
    • 我们可以通过until、finish、continue、等操作不断地缩小定位问题所在位置。
    • 一般先使用continue不断将问题从多个函数缩小到两个函数,再通过finish将问题缩小到一个函数,最后再通until、逐语句逐过程的定位问题所在位置
  • 修改变量的值:set var 变量=变量值
  1. 例如在一个循环中,我们知道了当循环变量的值为98的时候就会出现bug,那我们怎么可以快速执行到循环变量值为98的时候呢——修改变量的值在这里插入图片描述
  • 查看各级函数调用及参数:breaktrace/bt
  1. 查看各级函数调用及参数在这里插入图片描述
  • 查看当前栈帧局部变量的值:info/i locals

http://www.kler.cn/a/369791.html

相关文章:

  • SpringBoot-Vue整合百度地图
  • C基础寒假练习(4)
  • 论文阅读(十五):DNA甲基化水平分析的潜变量模型
  • 第05章 13 椭球体张量可视化应用一则-神经束追踪
  • Unreal Engine 5 C++ Advanced Action RPG 十一章笔记
  • 神经网络|(四)概率论基础知识-古典概型
  • 获取上传至DMS服务器上文件的URL
  • 00 嵌入式知识-目录篇
  • 多级反馈队列
  • Docker方式部署ClickHouse
  • 使用JavaScript进行网页设计
  • 传输层协议TCP详解(上篇)
  • Java程序员如何获得高并发经验?
  • Apache paimon 优化
  • 图为大模型一体机新探索,赋能智能家居行业
  • Linux系统下minio设置SSL证书进行HTTPS远程连接访问
  • 深入理解gPTP时间同步过程
  • Lua 从基础入门到精通(非常详细)
  • ipad-make-sense:首个支持 iPad 的开源数据标注工具
  • 基于ESP32的RGB便携式视频灯
  • 2.Linux按键驱动-创建字符设备,通过应用程序读取按键值
  • 算法复杂度概述
  • MySql中的锁的分类
  • C++学习:类和对象(一)
  • 使用Python读取word表格里的数据,存为excel表格,以此来解决word表格复制到excel表格一个单元格变过个单元格的问题
  • react18中react-thunk实现公共数据仓库的异步操作