Linux:调试器 - gdb

Linux:调试器 - gdb

    • gbd基本概念
    • gbd调试
      • 浏览
      • 断点
      • 运行
      • 变量


gbd基本概念

GDB (GNU Debugger) 是一个强大的命令行调试工具,用于调试各种编程语言(如C、C++、Java、Python等)编写的程序。使用 gdb可以帮助开发人员更快地定位和修复程序中的缺陷,提高代码质量和开发效率。它是 Linux/Unix 系统上最常用的调试工具之一。

先在Linux主机上安装gdb

yum install -y gdb

该指令需要root权限,要么sudo进行提权,要么以root身份执行。

如果一个可执行程序想要被gdb调试,那么该可执行程序必须带有调试信息,也就是以debug形式发布。我们现在有一个test.c源文件:

如果直接使用gcc那么其编译出来就是release版本:

gcc -o test-r test.c

带上-g选项后,gcc会以debug形式编译:

gcc -g -o test-d test.c

在这里插入图片描述

可以看到的是,debug版本的可执行程序test-d明显比release版本的大。我们可以通过readelf指令来查看可执行文件中有没有调试信息,可执行文件也是有固定格式的,这个格式叫做ELF,而readelf指令就是用于查看可执行文件内部内容的

先查看release版本的文件:

readelf -S test-r | grep debug

以上指令,管道左侧用于输出可执行文件内的内容,右侧用于筛选含debug的字段,最后该指令什么也没有输出,说明release版本内部不存在debug信息,也就是调试信息

再查看debug版本的文件:

readelf -S test-d | grep debug

输出结果如下:

在这里插入图片描述

可见该文件内部确实有debug调试信息。

随后我们就可以直接用gdb来调试可执行程序了:

gdb test-d

当看到以下页面,说明成功开始调试了:

在这里插入图片描述

如果想退出,输入q或者ctrl + d


gbd调试

我以以下代码为例,来进行调试示范:

#include <stdio.h>int getNum(int n)
{int sum = 0;int j;for(j = 1; j <= n; j++){sum += j;}return sum;
}int main()
{int i, num = 0;for(i = 0; i < 10; i++){num += getNum(i);}printf("%d\n", num);return 0;                                                                                           
}

浏览

l #:列出以#行为中心的10行代码
l:从上一次的最后一行开始,列出往后的10行代码

此处的l也可以改为list

第一次执行l 1,就会列出从第1行开始的代码:

在这里插入图片描述

再次输入l,则会从上一次的后一行代码开始,也就是第11行开始:

在这里插入图片描述

输入l 16

在这里插入图片描述

其不是从第16行开始,而是把第16行放在最中间,之前l 1从第一行开始,是因为第一行上面没有代码了。

l 函数名:列出某个函数的源代码

比如l main,就是列出main函数的代码:
在这里插入图片描述

不过其不是把main放在第一行,而是把main放在中心。


断点

b #:在行号为#处设置一个断点、
b 函数名:在函数的开头设置一个断点

bbreak的简写,此处的b改为break也可以。

在这里插入图片描述

现在我们要在第22行设置断点,输入b 22

在这里插入图片描述

其显示我们把断点设置在了第22行,断点序号为1

再给getNum函数设置一个断点,b getNum

在这里插入图片描述

其显示我们把断点设置在了第5行,断点序号为2

如果想查看我们设置过的断点:

info b:查看断点信息

在这里插入图片描述

此时就列出了目前所有的断点信息,Num表示断点编号;Enb表示当前断点是否生效;What描述了该断点的信息。

d #:删除编号为#的断点

此处ddelete的缩写,把d换为delete也可以。

使用d 2,把编号为2的断点删掉:

在这里插入图片描述

此时再info b,就只剩下编号为1的断点了。

disable #:禁用编号为#的断点

使用disable 1,把1号断点禁止:
在这里插入图片描述

再次info b,可以看到一号断点的Enb属性变为n了,表示该断点失效了。

enable #:启用编号为#的断点

使用enable 1,把1号断点启用:

在这里插入图片描述

再次info b,可以看到一号断点的Enb属性变为y了,表示该断点启用了。

总结一下断点相关命令:

命令功能
b #在行号为#处设置一个断点
b 函数名在函数的开头设置一个断点
info b查看断点信息
d #删除编号为#的断点
disable #禁用编号为#的断点
enable #启用编号为#的断点

运行

r:运行程序

此处rrun的简写,使用run也可以

在这里插入图片描述

对当前程序使用r后,直接执行到了结尾,并输出结果165exit normally表示程序正常退出。

现在我们使用b getNumgetNum函数上打一个断点,再次执行r指令:

在这里插入图片描述

可以看到,此时没有直接执行完程序,而是执行到断点处就停止了。我们再执行一次r

在这里插入图片描述

其发出询问:"是否要从头开始执行",也就是说第一次使用r指令,会执行到下一个断点,如果没有断点就执行到程序结束,但是每次使用r都必须是从头开始执行的。因此r指令一般用于进入程序,后续的调试一般不用r

c:执行到下一个断点

此处的ccontinue的缩写,使用continue也可以。

对刚刚的程序执行c

在这里插入图片描述

第一次执行r指令,到达第一个断点,也就是第一次调用getNum的时候,此时参数n = 0。第二次执行c指令,到达下一个断点,第二次调用getNum此时参数n = 1。因此c用于断点之间的跳转。

n:逐过程调试

现在我们删除原先的getNum断点,把断点打在第22行:

在这里插入图片描述

也就是语句num += getNum(i);处。

对该程序多次使用n

在这里插入图片描述
第一次执行n,停在了for循环的语句;第二次执行n,停在了num += getNum(i);;第三次执行n,停在了for循环的语句。

逐过程调试的特点在于不会进入函数内部,把函数当成一个语句执行

s:逐语句调试

示例:

在这里插入图片描述

一开始我们处于num += getNum(i);中,此时执行s指令,其直接跳转到了getNum函数的内部,到达其第一条语句int sum = 0;

逐语句调试的特点在于会进入函数内部,详细展示函数内部的执行细节

finish:执行到当前函数返回

示例:

在这里插入图片描述

一开始我们处于getNum函数的第一条语句int sum = 0;处,此时直接执行finish指令,跳转到了函数结束,并告知本次调用函数返回值为6

总结:

命令功能
r运行程序
c执行到下一个断点
n逐过程调试
s逐语句调试
finish执行到当前函数返回

变量

我们也可以在gdb中随时查看变量的值。

p #:输出变量值

示例:

在这里插入图片描述

现在处于某一次调用getNum的过程中,使用p sum得到当前sum = 15p j得到当前j = 5p n得到当前n = 8

display #:跟踪名为#的变量,每次调试都会输出该变量的值

示例:

先跟踪nsumj三个变量:

在这里插入图片描述

支持c进行调试:

在这里插入图片描述

可以看到,其附带输出了nsumj的值。

每个变量前面都要一个数字,这是每个变量的编号。

undisplay #:取消对编号为#的变量的跟踪

示例:

在这里插入图片描述

一开始跟踪了nsumj三个变量,此时执行指令undisplay 2,就取消跟踪了sum变量。再次调试时,就没有sum变量了。

总结:

命令功能
p #输出变量值
display #跟踪一个变量,每次调试都会输出该变量的值
undisplay #取消对变量的跟踪

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

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

相关文章

二叉树经典OJ题(2)

一、根据二叉树创建字符串 . - 力扣&#xff08;LeetCode&#xff09; class Solution { public://前序遍历&#xff1a;根 左 右//左子树为空&#xff0c;右子树不为空的时候&#xff0c;不能省略左//左不为空&#xff0c;右子树为空的时候&#xff0c;可以省略右//都为空&am…

Java基于微信小程序的校园外卖平台设计与实现,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

使用Python爬虫代理IP快速增加博客阅读量

目录 前言 二、Python爬虫代理IP技术简介 1.什么是爬虫&#xff1f; 2.什么是代理IP&#xff1f; 3.为什么使用代理IP&#xff1f; 三、使用Python爬虫代理IP增加博客阅读量的步骤 1.获取代理IP地址 2.模拟多次访问 3.定时任务 四、注意事项 五、总结 前言 随着互联…

Matlab 2024安装教程(附免费安装包资源)

鼠标右击软件压缩包&#xff0c;选择“解压到MatlabR2024a“。 2.打开解压后的文件夹&#xff0c;鼠标右击“MATHWORKS_R2024A“选择装载。 鼠标右击“setup“选择”以管理员身份运行“。点击“是“&#xff0c;然后点击”下一步“。复制一下密钥粘贴至输入栏&#xff0c;然后…

【Tars-go】腾讯微服务框架学习使用01--初始化服务

1 初始INIT-Demo运行 按照官网描述 go get 安装框架依赖 # < go 1.16 go get -u github.com/TarsCloud/TarsGo/tars/tools/tarsgo go get -u github.com/TarsCloud/TarsGo/tars/tools/tars2go # > go 1.16 go install github.com/TarsCloud/TarsGo/tars/tools/tarsgolat…

SSH安全设置

今天发现自己的公有云服务器被攻击了 然后查看了登录日志&#xff0c;如上图 ls -sh /var/log/secure vim /var/log/secure然后增加了安全相关的设置 具体可以从以下方面增加安全性&#xff1a; 修改默认SSH端口公有云修改安全组策略及防火墙端口设置登录失败次数锁定用户及限…

MySQL事务与事务原理

目录 事务 事务的四大特性ACID 事务隔离级别 事务原理 存储引擎 四大特性的保证 MVCC 事务链 ReadView 事务 事务指逻辑上的一组操作&#xff0c;组成这组操作的各个单元&#xff0c;要么全部成功&#xff0c;要么全部失败。 start transaction; -- 开启事务 或者 b…

B端:设置页面如何减少用户的录入操作。

录入操作尤其是文字录入是比较是比较繁琐的&#xff0c;尤其是在移动端小屏幕上&#xff0c;简直就是灾难。不过我们可以通过合理的设置、识别、记忆、自动填充等技术来有效的减少录入。 在 B 端设置页面中&#xff0c;可以采取多种方式来减少用户的录入操作&#xff0c;提高用…

第二期书生浦语大模型训练营第三次作业

任务一&#xff1a;在茴香豆 Web 版中创建自己领域的知识问答助手 构建个人回答助手 进入web页面&#xff0c;传输属于自己的文件&#xff0c;此处进行输入大量投资领域资料&#xff0c;构建个人投资者问答助手 回答示例 茴香豆缺陷 此处会发现茴香豆仍然存在一些缺点&#…

一、基础算法-快速排序

1.快速排序 快速排序主要利用了分治的思想&#xff0c;具体步骤为&#xff1a; step1 确定分界点&#xff0c;常用为q[left],q[right],q[mid]&#xff0c;也可以是随机的 step2 调整区间&#xff0c;将比分界点小的放左边&#xff0c;大的放右边 step3 利用递归处理左右两端 …

Web攻防10_PHP反序列化_概念魔术方法POP链构造

文章目录 1、什么是反序列化操作&#xff1f; - 类型转换2、常见PHP魔术方法- 对象逻辑魔术方法概念常见魔术方法魔术方法与反序列化漏洞 3、反序列化安全漏洞原理&#xff1a;漏洞探针漏洞危害 4、反序列化漏洞利用- POP链构造反序列化常见起点反序列化常见跳板反序列化常见终…

LeetCode 19. 删除链表的倒数第 N 个结点

LeetCode 19. 删除链表的倒数第 N 个结点 1、题目 力扣题目链接&#xff1a;19. 删除链表的倒数第 N 个结点 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a; head [1,2,3,4,5], n 2 输出&am…

LeetCode 678——有效的括号字符串

阅读目录 1. 题目2. 解题思路3. 代码实现 1. 题目 2. 解题思路 需要两个栈&#xff0c;一个用来保存左括号所在的位置索引&#xff0c;一个用来保存星号所在的位置索引。 从左往右遍历字符串&#xff0c;如果是左括号或者星号&#xff0c;则将位置索引分别入栈&#xff0c;如…

ELK——日志处理界的瑞士军刀

目录 引言 一、ELK简介 &#xff08;一&#xff09;基本概述 1.Elasticsearch服务 2.Logstash服务 2.2 logstash关键组件 2.2 logstash数据流向 3.Kibana服务 &#xff08;二&#xff09;ELK工作流程 &#xff08;三&#xff09;ELK的应用价值 二、部署搭建ELK &…

【Web】NSSRound#1-20 Basic 刷题记录(全)

目录 [NSSRound#1 Basic]basic_check [NSSRound#1 Basic]sql_by_sql [NSSCTF 2nd]php签到 [NSSCTF 2nd]MyBox [NSSCTF 2nd]MyBox(revenge) [NSSCTF 2nd]MyHurricane [NSSCTF 2nd]MyJs [NSSRound#3 Team]This1sMysql [NSSRound#3 Team]path_by_path [NSSRound#…

【入门】时钟旋转

时间限制 : 1 秒 内存限制 : 128 MB 时钟上面的时针从m时走到n时旋转了多少度&#xff1f;&#xff08;m<n&#xff0c;且m和n都是1~12之间的整数&#xff09; 输入 2个整数m和n 输出 一个整数代表时针旋转的度数 样例 输入 1 4 输出 90 提示 基础问题 #includ…

SQL语法 case when语句用法讲解

CASE WHEN解释 &#xff1a; SQL中的CASE WHEN语句是一种条件表达式&#xff0c;它允许你根据不同的情况返回不同的值。CASE WHEN通常用于SELECT语句中&#xff0c;用于创建新的列&#xff0c;该列的值取决于其他列的值。CASE WHEN可以用于任何可以使用表达式的地方。 大致概…

二叉树和数据结构

小红的完全二叉树构造 题目描述 小红想构造一个总共 n 个节点完全二叉树&#xff0c;该二叉树满足以下两个性质&#xff1a; 1. 所有节点的权值值为 1 ~ n 的一个排列。 2. 除了根节点以外&#xff0c;每个节点的权值和它父亲的权值的乘积为偶数。 请你帮小红构造出这个二叉树…

K8S一 k8s基础知识及实战

一 K8S 概览 1.1 K8S 是什么&#xff1f; K8S官网文档&#xff1a;https://kubernetes.io/zh/docs/home/ K8S 是Kubernetes的全称&#xff0c;源于希腊语&#xff0c;意为“舵手”或“飞行员”&#xff0c;官方称其是&#xff1a;用于自动部署、扩展和管理“容器化&#xff08…

软考 系统架构设计师系列知识点之大数据设计理论与实践(5)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之大数据设计理论与实践&#xff08;4&#xff09; 所属章节&#xff1a; 第19章. 大数据架构设计理论与实践 第3节 Lambda架构 19.3.1 Lambda架构对大数据处理系统的理解 Lambda架构由Storm的作者Nathan Marz提出&…