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.mfbz.cn/a/555470.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python介绍(未完)

文章目录 Python 背景知识Python 是谁创造的&#xff1f;Python 可以用来干什么&#xff1f;Python 的优缺点 搭建 Python 环境安装 Python搭建 PyCharm 环境新工具到手&#xff0c;赶紧试试中文设置第一个Python程序 Python基础语法基础语法&#xff08;1&#xff09;常量和表…

Error : java 错误 : 不支持发行版本5 ( 完美解决)

解决方案 1. 原因 idea的默认配置JDK版本与当前项目所需版本不一样 方案一&#xff08;每一个项目可能都要配置一遍&#xff09; Ctrlshitalts 打开项目结构&#xff0c;设置项目所需的JDK版本&#xff0c;本项目需要JDK8 Modules的JDK版本为5&#xff0c;这时就会报Error …

最大公约数和最小公倍数(C语言)

一、N-S流程图&#xff1b; 二、运行结果&#xff1b; 三、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>//实现最大公约数函数&#xff1b; int max(int x, int y) {//初始化变量值&#xff1b;int judge 1;//运算&#xff1b;judge x %…

Ubuntu 23.10.1 nginx源码安装

注&#xff1a;以下所有命令均在root管理员模式下&#xff0c;若不是&#xff0c;请在所有命令前加sudo 1、安装依赖库 1.1、安装gcc g的依赖库 apt-get install build-essential apt-get install libtool1.2、安装pcre依赖库 apt-get update apt-get install libpcre3 lib…

剑指Offer题目笔记33(并查集)

面试题116&#xff1a; 解决方案&#xff1a; ​ 一个班级可以包含一个或多个朋友圈&#xff0c;对应的图中可能包含一个或多个子图&#xff0c;每个朋友圈对应一个子图。因此&#xff0c;这个问题可以转化为如何求图中子图的数目。图的搜索算法可以用来计算图中子图的数目。扫…

企业Linux特殊权限位/为什么会存在SUID?/企业环境测试(原理剖析)-4989字解析

企业高薪思维&#xff1a; 坚持很难&#xff0c;优秀的人才是少数&#xff0c;很重要 坚持不下去&#xff0c;问自己想要什么&#xff1f; 问问自己想要好的生活状态&#xff1f;问自己有背景吗&#xff1f;你学历是亮点吗&#xff1f;有钱没&#xff0c;你也就是一般家庭&…

selenium 下载文件取消安全下载的方法

问题描述 我要从一个网站上下载文件&#xff0c;谷歌浏览器总是自动阻止下载&#xff0c;并询问我是否保留。 可是&#xff0c;我想要的是不要询问&#xff0c;默认下载即可。 运行环境 OS: macOSselenium: 4.19.0python: 3.10.11Chrome: 124.0.6367.62selenium chromedrive…

工会排队模式:创新营销的双赢之道

工会排队模式全面解读 在当今数字化营销的大潮中&#xff0c;促销方式层出不穷&#xff0c;但能真正抓住消费者眼球并带来双方共赢的模式并不多见。而工会排队模式便是在这样的背景下崭露头角&#xff0c;它巧妙地融合了工会积分、奖金池与排队机制&#xff0c;为消费者与商家…

linux进阶篇:重定向和管道操作

Linux中的重定向和管道操作 llinux中的三种IO设备&#xff1a; 标准输入&#xff08;STDIN&#xff09;,文件描述符号为&#xff1a;0&#xff0c;默认从键盘获取输入 标准输出&#xff08;STDOUT&#xff09;,文件描述符号位&#xff1a;1&#xff0c;默认输出到显示终端 标准…

java宠物领养系统的设计与实现(springboot+mysql+源码)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的宠物领养系统的设计与实现。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 基于Spring Bo…

udemy视频教程下载:AI和ChatGPT提示工程精通指南

欢迎来到 ChatGPT 大师班&#xff01; 这个 ChatGPT 大师班&#xff1a;AI 和提示工程指南是您通往 AI 未来的全通道通行证。 以下是您的学习旅程&#xff1a; 理解和掌握 ChatGPT&#xff1a;您将深入了解 AI 和语言模型&#xff0c;重点是 ChatGPT。我们设计了这个部分&am…

Linux--进程间的通信-命名管道

前文&#xff1a; Linux–进程间的通信-匿名管道 Linux–进程间的通信–进程池 命名管道的概念 命名管道是一种进程间通信&#xff08;IPC&#xff09;机制&#xff0c;运行不同进程之间进行可靠的、单向或双向的数据通信。 特点和作用&#xff1a; 跨平台性&#xff1a;在W…

ue4打包多模块

首先&#xff0c;每个模块&#xff0c;包含插件内的模块在内&#xff0c;都要用IMPLEMENT_MODULE(类名, 模块名)的方式&#xff0c;模块名就是带.build.cs的第一个单词。 build.cs里就说了这个模块该怎么用&#xff0c;用c#编写。 打包中要考虑到target.cs,将工程中相应的模块…

Linux服务器磁盘满了如何清理

生产环境中&#xff0c;磁盘很容易被日志文件沾满&#xff0c;如何查找和清理呢&#xff1f; 分享一下个人的经验&#xff1a; 1.先查询到哪个磁盘占用的最多 使用命令&#xff1a;df -h 2.查询/目录下磁盘占用情况 使用命令&#xff1a;du -sh * 3.同理进入占用磁盘比较大…

聊聊binlog是什么

1. 上一讲思考題解答:redo日志刷盘策略的选择建议 先给大家解释一下上一讲的思考題&#xff0c;我给大家的一个建议&#xff0c;其实对于redo日志的三种刷盘策略&#xff0c;我们通常建议是设置为1 也就是说&#xff0c;提交事务的时候&#xff0c;redo日志必须是刷入磁盘文件…

接口测试之用Fiddler对手机app进行抓包

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

基于FPGA的OMEGA东京奥运会计时器

截至2019年共举办了31届奥运会&#xff0c;其中27届的计时设备都由欧米茄&#xff08;OMEGA&#xff0c;Ω&#xff09;提供&#xff0c;今年的东京奥运会将会是第28届。 瑞士计时公司&#xff08;Swiss Timing&#xff09;基于火星Mars ZX2核心板打造了为奥运会等大型体育赛事…

Redis教程——数据类型(哈希、集合)

上篇文章我们学习了Redis教程——数据类型&#xff08;字符串、列表&#xff09;&#xff0c;这篇文章学习Redis教程——数据类型&#xff08;哈希表、集合&#xff09; 哈希表Hash 哈希表是一个string类型的field(字段)和value(值)的映射表&#xff0c;hash特别适合用于存储…

web轮播图

思路&#xff1a; 例如&#xff1a;有5张轮播的图片&#xff0c;每张图片的宽度为1024px、高度为512px.那么轮播的窗口大小就应该为一张图片的尺寸&#xff0c;即为&#xff1a;1024512。之后将这5张图片0px水平相接组成一张宽度为&#xff1a;5120px,高度依然为&#xff1a;5…

问题解决:pip install __命令安装不了Python库

项目环境&#xff1a; 我的环境&#xff1a;Window10&#xff0c;Python3.7&#xff0c;Anaconda3-2.4.0&#xff0c;Pycharm2023.1.3 问题描述①&#xff1a; pip install 命令安装不了需要的安装的Python库&#xff0c;以PyMuPDF为例 1 socket.timeout: The read operation t…