【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调试工具---提供的帮助
- 启动程序
- 断点管理
- 检查程序状态
- 单步执行
- 继续执行
- 修改程序
- 查看源代码
- 反汇编
- 多线程调试
- 调试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命令启动程序。
GDB中的断点管理是一项关键功能,允许开发者在特定位置暂停程序执行以进行检查。以下是关于断点管理的一些常用操作和说明:
- 设置断点:
- 使用break或b命令可以在源代码的特定行或函数上设置断点。例如,break filename:linenum在filename文件的linenum行设置断点,而break function_name在给定的function_name函数处设置断点。
- 也可以通过条件表达式来设置断点,格式如break location if condition,其中location可以是行号、函数名等,condition是一个条件表达式。只有当该条件为真时,断点才会生效。
- 查看断点:
- 可以通过info breakpoints命令查看所有设置的断点,包括断点的位置、是否启用、类型、条件和命中次数等信息。
- 删除断点:
- 使用delete或d命令后接断点编号,可以删除特定的断点,例如delete 1删除编号为1的断点。
- 要删除所有断点,可以使用delete命令而不带任何参数。
- 禁用和启用断点:
- 可以使用disable和enable命令后接断点编号来禁用或启用特定的断点。例如,disable 2将禁用编号为2的断点,而enable 2将重新启用它。
- 断点的持久性:
- 在GDB中设置的断点默认情况下是非持久的,也就是说,当你退出GDB并重新启动程序时,这些断点将不再存在。然而,有些GDB版本和前端可能提供了保存和恢复断点的功能,使断点具有持久性。这通常涉及将断点信息保存到一个文件中,并在启动GDB时加载该文件。
- 临时断点:
- 除了普通断点外,GDB还支持所谓的“临时断点”(也称为“一次性断点”)。这种类型的断点在程序到达其位置后会自动删除,因此只会命中一次。这可以通过特定的GDB命令或前端界面来实现。
3)检查程序状态:
当程序被暂停时,GDB可以查看程序中的变量值、内存内容、函数调用栈等信息,帮助开发者了解程序当前的状态。
在GDB中,当程序被暂停时,你可以检查程序的状态,这包括查看变量的值、内存内容、寄存器的内容,以及当前的函数调用栈等信息。
- 查看变量值:使用print命令(或简写为p)可以查看变量的值。例如,print var_name会显示变量var_name的当前值。你也可以使用print命令进行一些复杂的表达式计算,如print var1 + var2。
- 查看内存内容:x命令可以用来检查内存的内容。你可以指定要查看的内存地址和格式。例如,x/16xb address会以16进制格式显示从address开始的16个字节的内容。
- 查看寄存器内容:你可以使用info registers命令查看当前所有寄存器的值。如果你只想查看某个特定的寄存器,可以使用print命令,如print $eax。
- 查看函数调用栈:使用backtrace命令(或简写为bt)可以查看当前的函数调用栈。这会列出从主函数到当前函数的所有函数调用,以及每个函数的参数值。你还可以使用frame命令切换到调用栈中的某个特定函数帧。
- 查看源代码:GDB还可以显示当前执行的源代码行。使用list命令(或简写为l)可以查看当前的源代码,并允许你在源代码中设置断点或查看变量值。
4)单步执行:
GDB支持逐条执行程序中的指令,方便开发者逐步跟踪程序的执行过程。
在GDB中,单步执行是一种重要的调试手段,它允许开发者逐条执行程序中的指令,以便仔细观察程序的行为。GDB提供了几种不同的单步执行命令,以满足不同的调试需求。
- next (或 n):
- 使用next命令可以执行程序中的下一行代码。如果当前行是一个函数调用,next命令会执行整个函数,然后在函数返回后暂停。
- 简而言之,next命令步进到下一行代码,但不进入函数内部。
- step (或 s):
- 与next不同,step命令在执行下一行代码时,如果遇到函数调用,会进入函数内部并逐条执行函数内的指令。
- 使用step命令可以深入函数内部进行调试。
- finish:
- 当已经步入一个函数内部,并希望快速执行完剩余部分时,可以使用finish命令。它会继续执行程序直到从当前函数中返回。
- 这个命令在已经了解函数内部行为,只想快速跳到函数完成后的状态时非常有用。
- continue (或 c):
- 虽然不是传统意义上的单步执行命令,但continue命令在调试过程中也很有用。它会继续执行程序,直到遇到下一个断点或程序结束。
- 在设置了断点后,使用continue可以让程序快速运行到下一个关注点。
- until:
- until命令用于在循环体内单步执行,直到退出循环。如果当前行不在循环体内,则等同于next命令。
- 这个命令在调试循环结构时特别有用,可以避免手动步进整个循环。
- 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中修改程序的一些方法:
- 设置变量值:
使用set命令可以修改变量的值。例如,set variable_name = new_value会将variable_name的值更改为new_value。这适用于全局变量和局部静态变量。对于非静态局部变量,你可能需要在正确的栈帧中操作。set variable_name = new_value
- 调用函数:
在GDB中,你可以使用call命令调用函数,这可能会改变程序的状态。例如,call function_name(arguments)会调用function_name并传递arguments。调用函数可能会影响程序的行为,因此在使用时需要谨慎。call function_name(arguments)
- 跳转执行:
尽管不常推荐,但在某些情况下,你可能想要改变程序的执行流程。使用jump命令(如果GDB支持的话)可以跳转到程序的另一个位置执行。然而,这可能会破坏程序的正常执行流程,因此应该非常小心地使用。
7)查看源代码:
GDB可以显示当前执行的源代码行,并允许开发者在源代码中设置断点或查看变量值。
以下是在GDB中查看源代码的几种方法:
- 使用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)
相关文章:

【Linux】 gdb-调试器初入门(简单版使用)
🔥系列文章:《Linux入门》 目录 一、背景 二、什么是GDB 🌷定义 🌷GDB调试工具---提供的帮助 三、GDB的安装教程-Ubuntu 🌷gdb的安装 四、哪类程序可被调试 🌷程序的发布方式 🌷Debug版…...
Spring 的事务支持
文章目录 1、Spring如何管理事务2、编程式事务1_基本用法2_创建TransactionTemplate实例3_TransactionTemplate的内部结构4_总结 3、声明式事务1_使用Transactional注解2_事务的传播行为3_配置4_总结 1、Spring如何管理事务 Spring为事务管理提供了一致的编程模板,…...

基于STM32开发的智能家居照明控制系统
目录 引言环境准备工作 硬件准备软件安装与配置系统设计 系统架构硬件连接代码实现 系统初始化传感器数据采集显示与控制逻辑Wi-Fi通信应用场景 家庭智能照明办公室节能照明控制常见问题及解决方案 常见问题解决方案结论 1. 引言 智能家居照明控制系统通过集成光照传感器、继…...
程序员的底层思维~张建飞
前言 ◆ 成人学习的目的不是获取更多的信息量,而是学习更好的思维模型。 ◆ 好的思维能力是可以被复制和迁移的,它应该是普适的,而不应该有行业的界限。 第一部分 基础思维能力 ◆ 因为语言的抽象性,我在团队中会要求大家使用通用…...

美股收涨,半导体板块领涨;苹果iPhone出货预测上调
市场概况 在昨夜的交易中,美股三大股指全线收涨。道琼斯工业平均指数上涨1.39%,纳斯达克综合指数上涨2.34%,标准普尔500指数上涨1.61%。值得注意的是,英伟达股票涨幅近4%,推动了科技股的整体表现。美国十年期国债收益…...

[学习笔记]在不同项目中切换Node.js版本
文章目录 使用 Node Version Manager (NVM)安装 NVM使用 NVM 安装和切换 Node.js 版本为项目指定 Node.js 版本 使用环境变量指定 Node.js安装多个版本的 Node.js设置环境变量验证配置使用 npm 脚本切换 在开发中,可能会遇到不同的Vue项目需要不同的Node.js…...

SOL项目开发代币DApp的基本要求、模式创建与海外宣发策略
Solana(SOL)作为一个高性能区块链平台,以其快速的交易速度和低交易成本吸引了大量开发者和投资者。基于Solana开发的去中心化应用程序(DApp)和代币项目正逐步成为区块链领域的重要组成部分。要成功开发并推广一个SOL项…...

如何在 FastReport .NET 中构建和安装 Postgres 插件
FastReport .NET 是一款全功能的Windows Forms、ASP.NET和MVC报表分析解决方案。 功能非常丰富,功能广泛。今天我们将介绍如何使用报表设计器的 FastReport 插件连接数据库。 FastReport .NET 是适用于.NET Core 3,ASP.NET,MVC和Windows窗体…...

JVM指令重排序
文章目录 什么是指令重排序编译器优化JIT 编译优化处理器优化重排序数据依赖性 硬件层的内存屏障指令重排的代码验证好处减少管道阻塞提高缓存利用率利用并行执行单元性能提升更好地利用硬件资源 问题内存可见性问题编程复杂性增加调试困难 解决方案:Java内存模型&a…...
改造字典关键字:
怎样把第一个关键字的值都 加到所有关键字上? {type: 7, typenum: , typemon: } 我们可以使用字典的keys()方法来获取所有的关键字,然后通过遍历字典的方式将第一个关键字的值添加到其他关键字的名称上。以下是一个示例代码: data {type: …...

Neo4j 图数据库入门
图形数据库存储节点和关系,而不是表或文档。数据的存储方式就像你在白板上勾画想法一样。您的数据存储不受预定义模型的限制,允许以非常灵活的方式考虑和使用它。 一、核心概念:属性图形模型 Neo4j使用属性图数据库模型。图数据结构由节点(离…...

linux 磁盘满了,程序运行失败,如何处理?df -h
场景:紧急呼救,上传图片失败了。我一脸懵,服务器这是又咋地了,别邪乎姐姐,姐姐胆子小啊。 一、寻找问题原因 1、OSS出问题了? 然后我尝试了 IOS 的APP是没问题的,Android提示上传失败…...

Python编码系列—前端后浪:Python前后端分离开发实战指南
🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中…...
Docker学习之路【五】了解数据卷
定义与特性 Docker数据卷是一个特殊目录,,用于实现容器间数据的持久化和共享。数据卷存在于宿主机上,可以被一个或多个容器使用。它独立于容器的生命周期,意味着即使容器被删除,数据卷中的数据也会保留。数据卷的主要…...
matlab如何设置产生的随机数一致
在MATLAB中,确保产生的随机数序列一致,通常需要使用随机数生成器的种子(seed)。通过设置相同的种子值,可以确保在每次运行代码时,随机数生成器从相同的初始状态开始,从而生成相同的随机数序列。…...

ansible --------拓展
编辑 hosts 配置文件 [rootmo ~]# vim /etc/ansible/hosts # 创建目录 [rootmo ~]# mkdir /etc/ansible/playbook # 编辑配置文件 [rootmo ~]# vim /etc/ansible/playbook/nginx.yml # 执行测试 [rootmo ~]# ansible-playbook /etc/ansible/playbook/nginx.yml roles 修…...

gazebo下使用Fast-planner配置(包含mpc局部规划+控制Gazebo小车以及FastPlanner配置)
源码链接: https://github.com/USE-jx/NMPC_CASADI_CPP?tabreadme-ov-file #这是NMPC的 里面有Fast-Planner,但编译可能缺少东西,所以再放一个Fast-Planner的,可以装装缺少的库 https://github.com/HKUST-Aerial-Robotics/Fast-P…...
Python核心编程--Python要点总结
Python 核心编程包括了一些关键的要点,理解这些要点对于掌握 Python 至关重要。以下是 Python 核心编程的一些要点: 1. 数据类型与数据结构 基本数据类型: int, float, str, bool容器类型: list, tuple, set, dict不可变类型与可变类型: tuple 是不可变…...
【mysql】mysql配置文件之优先级学习
本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》:python零基础入门学习 《python运维脚本》: python运维脚本实践 《shell》:shell学习 《terraform》持续更新中:terraform_Aws学习零基础入门到最佳实战 《k8…...

自然语言处理(NLP)大模型
自然语言处理(NLP)大模型 自然语言处理(NLP)领域中的一种重要技术,具有强大的语言理解和生成能力。以下是对NLP大模型的详细介绍: 一、定义与背景 NLP大模型是指通过大规模预训练和自监督学习技术构建的…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...

wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...