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

GDB:从零开始入门GDB

目录

        1.前言

        2.开启项目报错

        3.GDB的进入和退出

        4.GDB调试中查看代码和切换文件

        5.GDB调试中程序的启动和main函数传参

        6.GDB中断点相关的操作

        7.GDB中的调试输出指令

        8.GDB中自动输出值指令

        9.GDB中的调试指令


前言

        在日常开发中,调试是我们必不可少的技能。在专业的编译器中,如VSCode,VS等编译器中都提供了较为完全的调试功能,如单步调试,异步调试等等。而在Linux中我们可以使用GDB工具来调试自己编写的代码,本篇文章就皆在讲解GDB的使用以及调试方法


开启项目报错

        在关于《MinGW:从入门到链接库》的文章中,曾对如何开启代码调试,关闭调试进行简单的讲解,在对GDB调试工具讲解之前,先简单回顾以下这些内容

        1.使用-W命令开启编译生成期间的警告

//开启编译生成期间的警告
g++ -o 可执行文件名 -W 源文件.cpp

图1.使用-W命令开启警告

        2.使用-Wall命令开启编译生成期间的所有警告

//开启编译生成期间的所有警告
g++ -o 可执行文件名 -Wall 源文件.cpp

图2.使用-Wall命令开启警告

        3.使用-Wunused-variable命令开启指定的Wunuser-variable警告和默认警告(其他指定的警告也可以通过修改-Wunused-variable的类型来修改)

//开启指定的wunuser-variable警告和默认警告
g++ -o 可执行文件名 -Wunused-variable 源文件.cpp

图3.使用-Wunused-variable命令开启默认警告和指定警告

        4.使用-Wno命令关闭编译期间的指定警告

//关闭指定的return-local-addr警告和默认警告
g++ -o 可执行文件名 -Wno-return-local-addr 源文件.cpp

图4.使用-Wno命令关闭指定的return-local-addr警告

        5.使用Werroe命令将编译生成期间的警告当作错误提示

//使用Werroe命令将编译生成期间的警告当作错误提示
g++ -o 生成的可执行文件名 -Werror 源文件.cpp

图5.使用-Werror命令将编译生成期间的警告当作错误提示

        6.使用-O命令(大写)设置文件优化等级其中优化等级共分为3个,优先级从1到3

//在编译生成期间对文件进行优化,优化等级为1
g++ -o 可执行文件名 -O1 源文件.cpp//在编译生成期间对文件进行优化,优化等级为2
g++ -o 可执行文件名 -O2 源文件.cpp//在编译生成期间对文件进行优化,优化等级为3
g++ -o 可执行文件名 -O3 源文件.cpp

图6.对编译源文件进行等级为1的优化


GDB的进入和退出

        在启动GDB调试之前,需要先对项目进行编译生成可执行文件。此时为了能进入GDB调试,在编译器CPP文件时需要加入-g命令,为生成的可执行文件添加调试信息,具体代码如下:

g++ -g -o 可执行文件名 要编译文件示例:g++ -g -o Demo2 txt1.cpp

图7.使用-g命令生成的可执行文件区别

        生成可执行文件后,可以使用gdb命令进入调试界面,如下:

gdb 可执行文件名示例:gdb Demo

图8.使用gdb命令进入GDB调试

        在进入GDB调试后,可以使用quit命令退出GDB调试,如下:

quit

图9.退出GDB调试


GDB调试中查看代码和切换文件

        在正式启动可执行文件前,我们一般需要先查看程序代码,找到合适的地方打断点,以下是几种查看代码和切换文件的方式:

                1.使用list命令查看当前调试的文件(默认显示前10行)

list
list 指定的文件名:行号
list 指定的文件名:函数名示例:list main:5  //查看main文件中的第五行(显示上下文代码)
示例:l main:fun   //仓库main文件中的fun函数
PS:也可以使用缩写l

    

图10.使用list命令查看代码

                2.使用set listsize命令设置默认显示的行数

set listsize示例 set listsize 20
PS:可简写为set list

                3.使用show listsize命令显示当前的显示行数

show listsizePS:可简写为 show list

图11.显示和设置的显示的行数

                4.使用fram命令查看当前显示代码的位置(可防止频繁调用list查看代码显示范围越界):

fram

图12.查看当前显示的行数


GDB调试中程序的启动和main函数传参

        在使用gdb命令进入GDB调试后,可以使用以下两种方式启动程序:

                1.使用run命令启动程序(执行到断点位置,无断点则全部执行):

run

图13.使用run命令启动程序

                2.使用start命令启动程序(执行到程序的第一行代码):

stars

图14.使用start命令启动程序

        一般我们在调试可执行文件时,需要传入参数,而且main函数也自带两个参数分别是int型的argc对象和char*型的argv对象,我们可以使用以下命令对其传参和显示当前传入参数:

                1.使用set args命令传入参数

set args 传入的参数示例:sey args 1 2 3

                2.使用show args命令显示当前传入的参数

show args

图15.设置参数和显示参数


GDB中断点相关的操作

        断点的类型分为两种,一个是条件断点,即满足指定条件则在该断点处停止,二是常规断点,程序运行到该位置便停止。在GDB中可以将断点设置到具体的行中,也可以设置到具体的函数中,具体参考如下:

                1.使用break命令设置断点

break 行数(函数名)示例: break 10
示例: b fun
PS:可使用简写b

图16.设置断点

                2.使用break命令设置条件断点

break 行数 if 条件示例:break 5 if i == 2

                3.使用break命令设置其他文件的断点

break 文件名:行数(函数名)示例:break main:5

        设置完断点后,可以取消设置的断点以及查看当前调试的断点信息,具体操作如下:

                1.使用info break命令查看断点信息

info breakPS:可简写为i b

图17.查看断点信息

                2.使用delete命令删除断点

delete 断点编号示例:delete 1
PS:可简写为d

                

图18.删除指定断点

                3.使用disable命令设置断点的状态为无效

disable 断点编号示例:disable 1    //设置编号为1的无效
示例:disable 1-3  //设置编号为1到3的无效
PS:可简写为dis

图19.使用disable命令设置断点状态为无效

                4.使用enable命令设置断点状态为有效

enable 断点编号示例:enable 1    //设置编号为1的断点生效
示例:enable 1-3  //设置编号为1到3的生效
PS:可简写为ena

图20.使用enable命令设置断点状态为有效


GDB中的调试输出指令

        在GDB中我们可以使用run和start指令来启动程序,当遇到断点时会停止,继续输入run或者start指令,则会提示我们是否要重新执行该程序。如果要继续执行则要使用continue指令,具体如下:

        1.使用continue指令继续运行程序

continuePS:可简写为c

图21.使用continue命令继续执行程序

        在调试过程中,我们在代码中也可能会经常使用printf或者cout函数来输出代码中执行的变量信息,这样能实时的观察到变量值的变化,方便我们定位代码的Bug。而在GDB中我们也可以做类似的操作,具体如下:

        1.使用print指令输出指定变量的值

                在使用print指令输出变量的值的时候,我们可以使用格式化字符限制输出的字符格式,类似于C语言中的scanf函数,具体格式化字符信息如下:

格式化字符备注
/x以十六进制的形式打印出整数
/o 以八进制的形式打印出整数
/t 以二进制的形式打印出整数
/f 以浮点数的形式打印变量或表达式的值
/c 以字符形式打印变量或表达式的值
/d 以有符号、十进制的形式打印出整数
/u 以无符号、十进制的形式打印出整数

表1.格式化字符表

        在使用print命令前,需要先给程序打上断点,并且使用run或start指令启动程序,当运行到断点时,即可使用print指令查看对象的值

print 变量名
print 格式化字符 变量名示例:print obj
示例:p /x obj
PS:可简写为p

图22.使用print命令输出指定对象的值

        2.使用ptype命令输出指定的变量的类型

ptype 变量名示例:ptype obj 

图23.使用ptype命令输出指定对象的类型


GDB中自动输出值指令

        在GDB调试中,我们会经常遇到循环,为了方便输出循环中的值,我们可以使用print指令输出,但是每一次执行后都执行一遍print指令则会十分麻烦。这时我们可以display指令自动输出指定变量的值,具体如下:

         1.使用display命令自动输出指定变量的值

                使用display命令输出变量的值,也可以使用格式化字符输出,具体可参考print指令的格式化字符表(表1),具体操作如下:

display 变量名
display 格式化字符示例:display obj

图24.使用display命令自动输出指定对象的值

        2.使用info命令输出自动显示表(使用display指令指定输出过的对象的值):

info display

图25.使用info命令输出自动显示表

        3.使用undisplay指令删除指定变量的自动输出

undisplay 变量编号示例:undisplay 1

        4.使用disable指令将自动输出变量的状态设为禁用

disable 变量编号示例:disble 1

        5.使用enable指令将自动输出变量的状态设为启用

enable 变量编号示例:enable 1

PS:具体可以参考断点中相关的操作


GDB中的调试指令

        我们在使用各种编译器进行调试时,会提供一些类似于单步调试等功能,而GDB也同样支持这些功能,具体如下:

        1.使用step命令执行下一行代码(当遇到函数时,将跳转至函数体内):

stepPS:可简写为s

        2.使用finish命令跳出函数体(使用step命令执行到函数体内部时,使用该指令跳出函数体。PS:保证函数体内不存在断点,若存在断点则还是执行该函数体内的代码):

finsh

        3.使用next命令执行下一行代码(当遇到函数时,不会跳转至函数体内):

nextPS:可简写为n

        4.使用unit跳出循环体(当断点在循环内时,可以使用该指令):

unit

相关文章:

GDB:从零开始入门GDB

目录 1.前言 2.开启项目报错 3.GDB的进入和退出 4.GDB调试中查看代码和切换文件 5.GDB调试中程序的启动和main函数传参 6.GDB中断点相关的操作 7.GDB中的调试输出指令 8.GDB中自动输出值指令 9.GDB中的调试指令 前言 在日常开发中,调试是我们必不可少的技能。在专业…...

服务器权限管理

我们linux服务器上有严格的权限等级,如果权限过高导致误操作会增加服务器的风险。所以对于了解linux系统中的各种权限及要给用户,服务等分配合理的权限十分重要。(权限越大,责任越大) 1.基本权限 U--user用户,G-group…...

08 SpringBoot 自定定义配置

SpringBoot自定义配置有三种方式: 使用PropertySource进行自定义配置 使用ImportResource进行自定义配置 使用Configuration进行自定义配置 PropertySource ​ 如果将所有的配置都集中到 application.properties 或 application.yml 中,那么这个配置文…...

Java之3DES(Triple DES)加密计算(DESede/ECB/ZeroPadding)

Java环境本身并不直接支持DESede/ECB/ZeroPadding。 不过,可以通过以下几种方式来实现DESede/ECB/ZeroPadding: 手动实现填充和去除填充:如前面示例代码所示,在加密之前进行填充,在解密之后去除填充。这是一个通用的方…...

从0开发一个Chrome插件:项目实战——广告拦截插件

前言 这是《从0开发一个Chrome插件》系列的第十七篇文章,本系列教你如何从0去开发一个Chrome插件,每篇文章都会好好打磨,写清楚我在开发过程遇到的问题,还有开发经验和技巧。 专栏: 从0开发一个Chrome插件:什么是Chrome插件?从0开发一个Chrome插件:开发Chrome插件的必…...

C++ 32 之 静态成员函数

#include <iostream> #include <string> using namespace std;// 特点: // 1.在编译阶段就分配了内存空间 // 2.类内声明&#xff0c;在类外进行初始化 // 3.所有对象共享一份静态成员数据 class Students02{ public:int s_c;static int s_d;// 静态成员函数&#…...

Python闯LeetCode--第1题:两数之和

Problem: 1. 两数之和 文章目录 思路解题方法复杂度Code 思路 看到这道题第一思路就是暴力破解&#xff0c;枚举&#xff0c;两个for循环遍历&#xff0c;直到找到满足要求的答案。主要因题目假设只有一组满足结果的答案&#xff0c;因此难度大大降低&#xff0c;作为第一道题&…...

SSM情侣购物系统-计算机毕业设计源码02387

目 录 摘要 1 绪论 1.1 开发背景与意义 1.2开发意义 1.3Vue.js 主要功能 1.3论文结构与章节安排 2 情侣购物系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据流程 3.3.2 业务流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 系统用例分…...

09-Spark架构

相比MapReduce僵化的Map与Reduce分阶段计算&#xff0c;Spark计算框架更有弹性和灵活性&#xff0c;运行性能更佳。 1 Spark的计算阶段 MapReduce一个应用一次只运行一个map和一个reduceSpark可根据应用复杂度&#xff0c;分割成更多的计算阶段&#xff08;stage&#xff09;…...

挑战5分钟内基于Springboot+SpringMVC+Mybatis-plus快速构建web后端三层架构

目标 在清晨的代码编辑器上&#xff0c;一场新的挑战即将开始。程序员们肃立于安静的办公室&#xff0c;眼神专注地盯着屏幕&#xff0c;等待着编译器的一声提示。 随着编译器输出的激动人心的"start!"的提示&#xff0c;战斗的序幕拉开了。Bug如潮水般涌来&#x…...

浅谈JavaScript中的作用域

前言 今天就来简单聊聊JavaScript中的作用域吧&#xff01;&#xff01;&#xff01; 正文 我们都知道&#xff0c;在任何一门编程语言里面都是有作用域这个概念的&#xff0c;不然岂不乱套了 在js中的作用域一共分为三种&#xff0c;全局域、函数域和块级作用域 全局域 全…...

Python | C++漂移扩散方程和无风险套利公式算法微分

&#x1f3af;要点 &#x1f3af;漂移扩散方程计算微分 | &#x1f3af;期权无风险套利公式计算微分 | &#x1f3af;实现图结构算法微分 | &#x1f3af;实现简单正向和反向计算微分 | &#x1f3af;实现简单回归分类和生成对抗网络计算微分 | &#x1f3af;几何网格计算微分…...

python如何对list求和

如何在Python中对多个list的对应元素求和&#xff0c;前提是每个list的长度一样。比如&#xff1a;a[1&#xff0c;2&#xff0c;3]&#xff0c;b[2&#xff0c;3&#xff0c;4]&#xff0c;c[3&#xff0c;4&#xff0c;5]&#xff0c;对a&#xff0c;b&#xff0c;c的对应元素…...

如何解决mfc100u.dll丢失问题,关于mfc100u.dll丢失的多种解决方法

在计算机使用过程中&#xff0c;我们常常会遇到一些错误提示&#xff0c;其中之一就是“计算显示缺失mfc100u.dll”。这个问题可能会影响到我们的正常使用&#xff0c;因此了解它的原因、表现以及解决方法是非常重要的。小编将详细介绍计算显示缺失mfc100u.dll的问题&#xff0…...

算法day32

第一题 207. 课程表 步骤一&#xff1a; 通过下图的课程数组,首先画出DAG图&#xff08;有向无环图&#xff09; 步骤二&#xff1a; 其次我们按照DAG图&#xff0c;来构建该图的拓扑排序&#xff0c;等有效的点都按照规则排完序后&#xff0c;观察是否有剩下的点的入度不为0&…...

【QT】信号与槽

目录 概述 Q_OBJECT 自定义信号 自定义槽 带参数的信号和槽 信号与槽断开 定义槽函数时&#xff0c;使用lambda表达式 概述 所谓的信号槽&#xff0c;要解决的问题&#xff0c;就是响应用户的操作&#xff0c;这是QT与其他GUI开发框架比较不同的地方。其他的GUI开发框…...

【Java】解决Java报错:IllegalArgumentException

文章目录 引言1. 错误详解2. 常见的出错场景2.1 非法的参数值2.2 空值或 null 参数2.3 非法的数组索引 3. 解决方案3.1 参数验证3.2 使用自定义异常3.3 使用Java标准库中的 Objects 类 4. 预防措施4.1 编写防御性代码4.2 使用注解和检查工具4.3 单元测试 结语 引言 在Java编程…...

完美的移动端 UI 风格让客户无可挑剔

完美的移动端 UI 风格让客户无可挑剔...

【React】在 React 组件中,怎么使用useContext

在React中,useContext 是一个Hook,它允许你无需显式地通过组件树的每一层来传递 props,就能将值深入到组件树的任何位置。要使用 useContext,你需要先创建一个 Context 对象,然后使用这个对象提供的 Provider 组件来包裹你的应用中的一部分。然后,任何在这个 Provider 下…...

【数据结构】栈的应用

目录 0 引言 1 栈在括号匹配中的应用 2 栈在表达式求值中的应用 2.1 算数表达式 2.2 中缀表达式转后缀表达式 2.3 后缀表达式求值 3 栈在递归中的应用 3.1 栈在函数调用中的作用 3.2 栈在函数调用中的工作原理 4 总结 0 引言 栈&#xff08;Stack&#xff09;是一…...

Opencv基本操作

Opencv基本操作 导入并使用opencv进行图像与视频的基本处理 opencv读取的格式是BGR import cv2 #opencv读取的格式是BGR import numpy import matplotlib.pyplot as plt %matplotlib inline图像读取 通过cv2.imread()来加载指定位置的图像信息。 img cv2.imread(./res/ca…...

2779. 数组的最大美丽值

简单翻译一下题目意思&#xff1a; 对于每个 nums[i] 都可以被替换成 [nums[i]-k, nums[i]k] 区间中的任何数&#xff0c;区间左右是闭的。在每个数字可以替换的前提下&#xff0c;返回数组中最多的重复数字的数量。 第一想法是用一个哈希表&#xff0c;Key 是可以被替换的数…...

数据库修复实例(航线修复)

修复目标 修复回音群岛 (Echo Isles) 到 赞达拉港 (Port of Zandalar) 的航线 SET TRANSPORT_GUID : 32; SET TRANSPORT_ENTRY : 272677; SET CGUID : 850000;-- Adjust transports DELETE FROM transports WHERE guid TRANSPORT_GUID; INSERT INTO transports (guid, entry…...

视频网站下载利器yt-dlp参数详解

yt-dlp 是一个强大的命令行工具&#xff0c;用来下载 YouTube 和其他网站上的视频和音频。它拥有丰富的参数&#xff0c;可以定制下载行为&#xff0c;满足各种需求。本文将详细介绍 yt-dlp 的参数使用。 一、基本参数 -f, –format FORMAT: 指定下载格式&#xff0c;可以用视…...

可解析PHP的反弹shell方法

这里拿vulnhub-DC-8靶场反弹shell&#xff0c;详情见Vulnhub-DC-8 命令执行 拿nc举例 <?php echo system($_POST[cmd]); ?>利用是hackbar&#xff0c;POST提交cmdnc -e /bin/sh 192.168.20.128 6666, 直接反弹shell到kali。 一句话木马 <?php eval($_POST[&qu…...

AMSR-MODIS 边界层水汽 L3 每日 1 度 x 1 度 V1、V2 版本数据集

AMSR-MODIS Boundary Layer Water Vapor L3 Daily 1 degree x 1 degree V1 (AMDBLWV) at GES DISC AMSR-MODIS Boundary Layer Water Vapor L3 Daily 1 degree x 1 degree V2 (AMDBLWV) at GES DISC 简介 该数据集可估算均匀云层下的海洋边界层水汽。AMSR-E 和 AMSR-2 的微波…...

Oracle备份失败处理,看这一篇就够了!

作者&#xff1a;IT邦德 中国DBA联盟(ACDU)成员&#xff0c;10余年DBA工作经验&#xff0c; Oracle、PostgreSQL ACE CSDN博客专家及B站知名UP主&#xff0c;全网粉丝10万 擅长主流Oracle、MySQL、PG、高斯及Greenplum备份恢复&#xff0c; 安装迁移&#xff0c;性能优化、故障…...

后端中缓存的作用以及基于Spring框架演示实现缓存

缓存的作用及演示 现在我们使用的程序都是通过去数据库里拿数据然后展示的 长期对数据库进行数据访问 这样数据库的压力会越来越大 数据库扛不住了 创建了一个新的区域 程序访问去缓存 缓存区数据库 缓存里放数据 有效降低数据访问的压力 我们首先进行一个演示 为了演示…...

Python:基础爬虫

Python爬虫学习&#xff08;网络爬虫&#xff08;又称为网页蜘蛛&#xff0c;网络机器人&#xff0c;在FOAF社区中间&#xff0c;更经常的称为网页追逐者&#xff09;&#xff0c;是一种按照一定的规则&#xff0c;自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字…...

机器人运动学笔记

一、建模 参考资料&#xff1a;https://zhuanlan.zhihu.com/p/137960186 1、三维模型和连杆、关节定义 2、设置z轴 SDH和MDH会不一样&#xff0c;主要的区别在于SDH中坐标系在连杆末端&#xff0c;MDH中坐标系在连杆首端。虽然这里只是给出z轴&#xff0c;但是由于后面原点位…...

电子商务网站建设培训小结/网络营销的八大职能

有个统计需求&#xff0c;需要对IP进行分类统计&#xff0c;Mysql提供了INET_ATON(expr)给出一个作为字符串的网络地址的点地址表示&#xff0c;返回一个代表该地址数值的整数。地址可以是4或8比特地址。mysql> select inet_ntoa(3507806248);-----------------------| inet…...

网站引入百度地图/网络推广怎么推广

一.管理输入和输出 在系统中利用普通用户执行命令’find /etc -name passwd’&#xff0c;由于普通用户权限问题&#xff0c;将会出现两种输出&#xff1a;正确输出和错误输出 因为student用户权限问题会有以下输出find: ‘/etc/pki/CA/private’: Permission denied ##没有进…...

代理下单网站开发/国外网站推广

翻译&#xff1a;张睿毅&#xff1b;校对&#xff1a;王威力本文约4000字&#xff0c;建议阅读8分钟。本文为你介绍超级数据科学家的13大基本技能。&#xff08;链接&#xff1a;https://www.linkedin.com/feed/update/urn:li:activity:6531492123240431616 &#xff09;好的数…...

网站做树状结构有什么作用/微信广告推广如何收费

1. 在托管程序的.config文件里&#xff0c;启用legacyCorruptedStateExceptionsPolicy这个属性&#xff0c;即简化的.config文件类似下面的文件&#xff1a; App.config: <?xml version"1.0"?> <configuration> <startup> <supportedRun…...

城市形象设计vi手册/百度seo新规则

gpart 分区工具 查看已经连接的设备rootlsgxbsd:~ # camcontrol devlist 1. 删除ad0上所有分区# gpart destroy -F /dev/da1注: 没有数据情况才可以这样 2. 创建gpt分区信息表# gpart create -s GPT /dev/da1 创建新的GPT分区表# gpart create -s MBR /dev/da1 创建新的MBR分区…...

网站导航栏怎么做/seo技术分享免费咨询

最近学习了 BlockingQueue&#xff0c;发现 java 的 BlockingQueue 并不是每一个实现都按照 BlockingQueue 的语意来的&#xff0c;其中有不少坑。 直接上代码吧&#xff1a; 1、关于PriorityBlockingQueue&#xff0c;以下代码运行结果是什么&#xff08;答案往下拉&#xff0…...