【Linux】 gdb-调试器初入门(简单版使用)

🔥系列文章:《Linux入门》


目录

一、背景

二、什么是GDB 

🌷定义

🌷GDB调试工具---提供的帮助

 三、GDB的安装教程-Ubuntu

🌷gdb的安装

四、哪类程序可被调试

🌷程序的发布方式

🌷Debug版本、Release版本的区别

🌷编译器的选择

五、调试指令                        

1)启动程序:

3)检查程序状态:

4)单步执行:

5)继续执行:

6)修改程序:

7)查看源代码:

8)退出gdb


一、背景

        GDB是Linux下的调试工具。

        对于GDB调试器来说,是采用纯命令行的形式进行调试。

        所以大家又要开始对于指令的学习!!


本文中采用C语言,编译器使用gcc


二、什么是GDB 

🌷定义

GDB(GNU Debugger)是GNU开源组织发布的一个强大的Linux下的程序调试工具。它主要用来调试C/C++语言写的程序,但也可以调试其他语言程序。

GDB提供了丰富的命令来实现相关功能,如break设置断点、run启动程序、next单步执行、continue继续执行、print打印变量值等。此外,GDB还支持条件断点、断点命令列表、监视点等高级功能,满足开发者在调试过程中的各种需求。

🌷GDB调试工具---提供的帮助

  1. 启动程序
  2. 断点管理
  3. 检查程序状态
  4. 单步执行
  5. 继续执行
  6. 修改程序
  7. 查看源代码
  8. 反汇编
  9. 多线程调试
  10. 调试coredump文件

 三、GDB的安装教程-Ubuntu

🌷gdb的安装

sudo apt install gdb


四、哪类程序可被调试

🔥 要使用gdb调试,必须使用release 版本。

🌷程序的发布方式

只有两种:

  • debug版本:程序本身会被加入更多的调试信息,以便于进行调试。
  • release版本:不会添加任何调试信息,是不可调试的。 

🌷Debug版本、Release版本的区别

  • debug版本:有调试信息,文件大小更大
  • release版本:无调试信息,文件更小

对于不同身份:

  • 对于程序员:在编写代码后运行一般是使用【DeBug】环境进行运行。因为在企业里写软件项目,将代码写完后程序员自己要做简单的测试。当程序员自己测试完没有问题之后,就会将这个可执行程序给到测试人员进行测试,而且会给出自己的单元测试报告。
     
  • 对于测试人员:所处的模式是【Release】,也就是将来客户要使用的这款软件的发布版本。                       当测试在测的过程中,一定会发现一些问题。此时测试人员就会把报告再打回研发部。研发部做修改重新生成Release版本的可行性程序给到测试人员继续测试。最后只有当测试通过了,再将生成的【单元测试报告】与产品经理进行核对之后没有问题,那这个软件才可以真正地面向市场👉

    🌷编译器的选择

不同编译器生成一个可执行程序时,默认发布版本是不同的。

在本文中使用的gcc编译器,生成的可执行程序,它是一个【Release】版本的,因此无法进行调试。

如果想生成debug版本,就需要在使用gcc/g++生成可执行程序时加上-g选项。

如下,利用 test.c 生成可执行程序mytest的release版本

gcc -o mytest test.c  -g


五、调试指令
                        

1)启动程序:

GDB可以按照自定义的要求启动程序,例如设置参数、环境变量等。
在GDB中,启动程序主要有两种方式:使用run命令或者start命令。

run命令:(无断点直接运行、有断点从第一个断点处开始运行

这是最常用的启动程序的方式。在GDB中输入run(或者简写为r)后,程序会开始执行。

如果程序中设置了断点,那么程序会执行到第一个断点处暂停;

如果没有设置断点,程序会一直执行到结束。此外,run命令也可以带参数,这些参数会被传递给被调试的程序。

start命令:

与run命令不同,start命令会执行程序至main()主函数的起始位置,即在main()函数的第一行语句处停止执行(该行代码尚未执行)。

可以理解为,使用start命令启动程序,完全等价于先在main()主函数起始位置设置一个断点,然后再使用run命令启动程序。

2)断点管理:

GDB中的断点管理是一项关键功能,允许开发者在特定位置暂停程序执行以进行检查。以下是关于断点管理的一些常用操作和说明:

  1. 设置断点
    • 使用break或b命令可以在源代码的特定行或函数上设置断点。例如,break filename:linenum在filename文件的linenum行设置断点,而break function_name在给定的function_name函数处设置断点。
    • 也可以通过条件表达式来设置断点,格式如break location if condition,其中location可以是行号、函数名等,condition是一个条件表达式。只有当该条件为真时,断点才会生效。
  2. 查看断点
    • 可以通过info breakpoints命令查看所有设置的断点,包括断点的位置、是否启用、类型、条件和命中次数等信息。
  3. 删除断点
    • 使用delete或d命令后接断点编号,可以删除特定的断点,例如delete 1删除编号为1的断点。
    • 要删除所有断点,可以使用delete命令而不带任何参数。
  4. 禁用和启用断点
    • 可以使用disable和enable命令后接断点编号来禁用或启用特定的断点。例如,disable 2将禁用编号为2的断点,而enable 2将重新启用它。
  5. 断点的持久性
    • 在GDB中设置的断点默认情况下是非持久的,也就是说,当你退出GDB并重新启动程序时,这些断点将不再存在。然而,有些GDB版本和前端可能提供了保存和恢复断点的功能,使断点具有持久性。这通常涉及将断点信息保存到一个文件中,并在启动GDB时加载该文件。
  6. 临时断点
    • 除了普通断点外,GDB还支持所谓的“临时断点”(也称为“一次性断点”)。这种类型的断点在程序到达其位置后会自动删除,因此只会命中一次。这可以通过特定的GDB命令或前端界面来实现。

3)检查程序状态:

当程序被暂停时,GDB可以查看程序中的变量值、内存内容、函数调用栈等信息,帮助开发者了解程序当前的状态。
在GDB中,当程序被暂停时,你可以检查程序的状态,这包括查看变量的值、内存内容、寄存器的内容,以及当前的函数调用栈等信息。

  1. 查看变量值:使用print命令(或简写为p)可以查看变量的值。例如,print var_name会显示变量var_name的当前值。你也可以使用print命令进行一些复杂的表达式计算,如print var1 + var2。
  2. 查看内存内容:x命令可以用来检查内存的内容。你可以指定要查看的内存地址和格式。例如,x/16xb address会以16进制格式显示从address开始的16个字节的内容。
  3. 查看寄存器内容:你可以使用info registers命令查看当前所有寄存器的值。如果你只想查看某个特定的寄存器,可以使用print命令,如print $eax。
  4. 查看函数调用栈:使用backtrace命令(或简写为bt)可以查看当前的函数调用栈。这会列出从主函数到当前函数的所有函数调用,以及每个函数的参数值。你还可以使用frame命令切换到调用栈中的某个特定函数帧。
  5. 查看源代码:GDB还可以显示当前执行的源代码行。使用list命令(或简写为l)可以查看当前的源代码,并允许你在源代码中设置断点或查看变量值。

4)单步执行:

GDB支持逐条执行程序中的指令,方便开发者逐步跟踪程序的执行过程。
在GDB中,单步执行是一种重要的调试手段,它允许开发者逐条执行程序中的指令,以便仔细观察程序的行为。GDB提供了几种不同的单步执行命令,以满足不同的调试需求。

  1. next (或 n):
    • 使用next命令可以执行程序中的下一行代码。如果当前行是一个函数调用,next命令会执行整个函数,然后在函数返回后暂停。
    • 简而言之,next命令步进到下一行代码,但不进入函数内部。
  2. step (或 s):
    • 与next不同,step命令在执行下一行代码时,如果遇到函数调用,会进入函数内部并逐条执行函数内的指令。
    • 使用step命令可以深入函数内部进行调试。
  3. finish:
    • 当已经步入一个函数内部,并希望快速执行完剩余部分时,可以使用finish命令。它会继续执行程序直到从当前函数中返回。
    • 这个命令在已经了解函数内部行为,只想快速跳到函数完成后的状态时非常有用。
  4. continue (或 c):
    • 虽然不是传统意义上的单步执行命令,但continue命令在调试过程中也很有用。它会继续执行程序,直到遇到下一个断点或程序结束。
    • 在设置了断点后,使用continue可以让程序快速运行到下一个关注点。
  5. until:
    • until命令用于在循环体内单步执行,直到退出循环。如果当前行不在循环体内,则等同于next命令。
    • 这个命令在调试循环结构时特别有用,可以避免手动步进整个循环。
  6. advance:
    • advance命令可以指定向前执行到程序的某个位置,这个位置可以是源代码行号、函数名或某个特定的地址。不过请注意,并非所有GDB版本都支持此命令。

5)继续执行:

GDB可以在暂停后继续执行程序,直到遇到下一个断点或程序结束。
在GDB中,继续执行被调试的程序是一个常见的操作,尤其是在设置了断点或进行了单步执行之后。以下是关于如何在GDB中继续执行程序的信息:


continue命令(或简写为c)
这个命令用于继续执行被调试的程序。在程序暂停后(例如,由于遇到了断点或执行了单步调试命令),你可以使用continue命令恢复程序的执行。程序将继续运行,直到遇到下一个断点、接收到一个信号,或者程序正常结束。
示例

(gdb) continue

或者简写为:

(gdb) c

如果希望程序继续执行并跳过一定数量的断点,可以在continue命令后加上一个数字,表示希望跳过的断点次数(包括当前这一次)。例如:

(gdb) continue 5

上述命令将使程序继续执行,并跳过接下来的5个断点(但请注意,这种用法可能不是GDB的标准功能;标准的GDB通常只支持不带参数的continue命令)。

然而,在实际使用中,GDB通常只会继续执行到下一个断点或程序结束,而不支持跳过指定数量的断点如果需要跳过某些断点,可以考虑临时禁用或删除这些断点。


总的来说,在GDB中使用continue命令是继续执行被调试程序的标准方式。在执行该命令之前,请确保已经设置了适当的断点或其他停止条件,以防止程序无限制地运行下去。

6)修改程序:

GDB允许在调试过程中修改程序中的变量值或内存内容,这对于测试某些特定条件非常有用。
在GDB中,修改程序通常指的是在调试过程中动态地改变变量的值或内存区域的内容。这种能力对于测试和调试非常有用,尤其是在需要模拟特定条件或绕过错误时。
以下是在GDB中修改程序的一些方法:

  1. 设置变量值
    使用set命令可以修改变量的值。例如,set variable_name = new_value会将variable_name的值更改为new_value。这适用于全局变量和局部静态变量。对于非静态局部变量,你可能需要在正确的栈帧中操作。
    set variable_name = new_value
  2. 调用函数
    在GDB中,你可以使用call命令调用函数,这可能会改变程序的状态。例如,call function_name(arguments)会调用function_name并传递arguments。调用函数可能会影响程序的行为,因此在使用时需要谨慎。
    call function_name(arguments)
  3. 跳转执行
    尽管不常推荐,但在某些情况下,你可能想要改变程序的执行流程。使用jump命令(如果GDB支持的话)可以跳转到程序的另一个位置执行。然而,这可能会破坏程序的正常执行流程,因此应该非常小心地使用。

7)查看源代码:

GDB可以显示当前执行的源代码行,并允许开发者在源代码中设置断点或查看变量值。
以下是在GDB中查看源代码的几种方法:

  1. 使用list命令
    GDB的list命令(或简写为l)可以用来显示当前行的源代码以及周围的代码。你可以指定要显示的行号或函数名。例如,list function_name将显示名为function_name的函数的源代码,而list linenum将显示指定行号linenum周围的代码。如果不带任何参数,list命令通常会显示当前执行点周围的代码。

8)退出gdb

输入 quit

或者 快捷键  ctrl + d 

参考文章

http://t.csdnimg.cn/tVKIf

全网最全GDB调试整理 - 小白编程开发 - 博客园 (cnblogs.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/403787.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vscode——如何实现 Ctrl+鼠标左键 跳转函数内部的方法

一、对于Python代码 安装python插件即可实现 二、对于C/C代码 安装C/C插件即可实现

5.3 表结构设计与数据完整性

欢迎来到我的博客,很高兴能够在这里和您见面!欢迎订阅相关专栏: 工💗重💗hao💗:野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典:收集整理全网各大IT互联网公司技术、项目、HR面试真题.…

Linux:开发工具(2)

一、Linux编译器-gcc/g使用 1.1 为什么我们可以用C/C做开发呢? 无论是在windows、还是Linux中,C的开发环境不仅仅指的是vs、gcc、g,更重要的是语言本身的头文件(函数的声明)和库文件(函数的实现&#xff0…

Cesium 实战 - 自定义纹理材质系列之 - 半球雷达效果(力场闪烁)

Cesium 实战 - 自定义纹理材质系列之 - 半球雷达效果(力场闪烁) 核心代码完整代码在线示例Cesium 给实体对象(Entity)提供了很多实用的样式,基本满足普通项目需求; 但是作为 WebGL 引擎,肯定不够丰富,尤其是动态效果样式。 对于实体对象(Entity),可以通过自定义材…

后端Web之数据库(以MySQL为例)

目录 1.概述 2.MySQL 3.DDL 4.DML 5.DQL 1.概述 对于我们自己写的一些小功能,数据一般存储在文件中,比如XML文件。而在实际项目中,数据都是存放在数据库中的。数据库(DataBase )是一个存储数据的集合&#xff0c…

OpenCv图像处理: 时域滤波与频域滤波

时域滤波: 空间域滤波的步骤一般如下: 1. 选择滤波器 选择一种低通滤波器,常见的包括: 均值滤波(平均滤波器)高斯滤波(Gaussian filter) 2. 定义滤波器核 根据选择的滤波器类型&…

【C++篇】迈入新世界的大门——初识C++(上篇)

文章目录 C发展历史C起源C版本更新C23小故事 C在工作领域的应用C参考网站及文档书籍编程语言排行榜C难度参考文档书籍参考文档参考书籍 C第一个程序命名空间为什么要使用namespacenamespace定义及规则命名空间使用 C输入&输出名字含义 缺省参数函数重载 C发展历史 C起源 …

VUE中出现Cannot find module ‘@/api/xxx.js‘ or its corresponding type declarations

在使用VSCode编写Vue程序时发现之前使用以下代码时却报出了错误 import {getEmployeeList} from /api/employee\ 保证文件地址正确且其中的方法也可以正常调用,只是报出了错误,该行代码上加入一个‘//ts-ignore’就可以解决。 修改后的代码 //ts-ig…

python基础篇(15):闭包

在函数嵌套的前提下&#xff0c;内部函数使用了外部函数的变量&#xff0c;并且外部函数返回了内部函数&#xff0c;我们把这个使用外部函数变量的内部函数称为闭包。 1 简单闭包 def outer(logo):def inner(msg):print(f"<{logo}>{msg}<{logo}>")retu…

苹果(ios)私钥证书和profile文件申请教程

苹果&#xff08;ios&#xff09;私钥证书&#xff0c;可以理解为p12后缀的苹果证书&#xff0c;我们在苹果开发者中心可以生成cer格式的证书&#xff0c;然后使用mac电脑或者第三方转换成p12后缀格式的私钥证书。 证书profile文件&#xff0c;又叫描述文件&#xff0c;这个文…

Android系统和开发--安全性和权限管理 SELinux 策略 安全架构

学习android权限知识 SElinux chmod -R 777 ./ setenforce 0 adb root su fastboot oem at-unlock-vboot adb disable-verity Android权限 Android系统是基于Linux内核构建的&#xff0c;因此它继承了Linux的权限管理机制。Android应用需要通过声明权限来访问系统的某些功能&…

融资融券利率和手续费详情,融资融券开通门槛50W资产必须沪深市值?

融资融券利率和手续费 融资融券就是可以向证券公司借钱借券来进行证券交易&#xff0c;实现杠杆操作。融资是向证券公司借款买入股票&#xff0c;而融券则是向证券公司借入股票并卖出。 融资融券的利率是浮动的、个性化的&#xff0c;但一般最低可以达到4.0%~5.0%&#xff0c…

Selenium + Python 自动化测试14(发送报告)

我们的目标是&#xff1a;按照这一套资料学习下来&#xff0c;大家可以独立完成自动化测试的任务。 上一篇我们讨论了使用HTMLTestRunner 生成HTML报告的方法。 本篇文章我们接着讲生成HTML报告是否可以自动邮件发送出去&#xff0c;提高我们测试报告的及时性&#xff0c;方便…

WordPress美化节日灯笼插件,适合春节的时候使用

源码介绍&#xff1a; WordPress美化节日灯笼插件&#xff0c;适合每年过年的时候安在网站上使用&#xff0c;这款插件可以备用着&#xff0c;一款WordPress节日灯笼美化插件&#xff0c;可以给网页自动加一个灯笼效果使用说明&#xff1a;到网站WP后台 - 插件 - 安装插件 - 上…

Java代码基础算法练习-乘阶求和-2024.08.18

对应的源代码可以在我的 Gitee 仓库中找到&#xff0c;欢迎star~ [Gitee 仓库](https://gitee.com/yukongji/java-basic-algorithm) 任务描述&#xff1a; 求Sn1!2!3!4!5!…n!之值&#xff0c;其中n是一个数字(n<10)。 解决思路&#xff1a; 输入: 读取用户输入的 n 值。检查…

Android:使用Gson常见问题(包含解决将Long型转化为科学计数法的问题)

一、解决将Long型转化为科学计数法的问题 1.1 场景 将一个对象转为Map类型时&#xff0c;调用Gson.fromJson发现&#xff0c;原来对象中的long类型的personId字段&#xff0c;被解析成了科学计数法&#xff0c;导致请求接口失败&#xff0c;报参数错误。 解决结果图 1.2、Exa…

leetcode108.把升序数组转换成二叉搜索树

题目描述 [-10,-3,0,5,9] 转换成如下二叉搜索树&#xff1a; 解题的核心原理是&#xff1a;二叉搜索树的中序遍历结果是一个升序数组&#xff0c;所以根节点的数值&#xff0c;也位于数组的中部。 class Solution {public TreeNode sortedArrayToBST(int[] nums) {return h…

基于Hadoop的汽车大数据分析系统设计与实现【爬虫、数据预处理、MapReduce、echarts、Flask】

文章目录 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主项目介绍爬虫数据概览HIve表设计Cars Database Tables1. cars_data2. annual_sales_volume3. brand_sales_volume4. city_sales_volume5. sales_volume_by_year_and_brand6. sales_distribu…

MATLAB 手动实现一种高度覆盖值提取建筑物点云的方法(74)

专栏往期文章,包含本章 MATLAB 手动实现一种高度覆盖值提取建筑物点云的方法(74) 一、算法介绍二、算法实现1.代码2.效果总结一、算法介绍 手动实现一种基于高度覆盖值的建筑物点云提取方法,适用于高大的城市建筑物,比只利用高度提取建筑物的方法更加稳定和具有价值,主要…

IntelliJ IDEA 集成 ShardingSphere-JDBC 访问分库分表

背景 众所周知&#xff0c;IntelliJ IDEA 是 Java 领域常用的开发工具之一&#xff0c;IDEA Ultimate&#xff08;旗舰版&#xff09;或其他例如 DataGrip 等 Intellij 平台的工具都集成了对数据库的访问能力。 但是&#xff0c;对于做了分库分表的项目&#xff0c;直接使用 …