GDB:从零开始入门GDB

news2025/4/8 11:28:06

目录

        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 listsize

PS:可简写为 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 break

PS:可简写为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指令继续运行程序

continue

PS:可简写为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命令执行下一行代码(当遇到函数时,将跳转至函数体内):

step

PS:可简写为s

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

finsh

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

next

PS:可简写为n

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

unit

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

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

相关文章

【每日刷题】Day65

【每日刷题】Day65 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. LCR 175. 计算二叉树的深度 - 力扣(LeetCode) 2. 序列找数_牛客题霸_牛客网…

超详解——Python 字典详解——小白篇

目录 1. 创建字典 示例: 2. 访问字典中的元素 示例: 3. 修改字典元素 示例: 4. 删除字典元素 示例: 5. 查找元素是否是字典的键 示例: 6. 标准类型操作符 获取字典长度 合并两个字典 7. 常用内置函数 k…

mysql 8 创建用户,并对用户授权

创建用户: 对MySQL创建新用户。命令如下: create user devuser% identified by 123456; 授予权限 grant all privileges on joolun_ry.* to devuser% with grant option; 参数说明: joolun_ry:表明对那个库进行授权&#xf…

SpringCloud跨服务远程调用

随着项目的使用者越来越多,项目承担的压力也会越来越大,为了让我们的项目能服务更多的使用者,我们不得不需要把我们的单体项目拆分成多个微服务,就比如把一个商城系统拆分成用户系统,商品系统,订单系统&…

Type-C接口显示器:C口高效连接与无限可能 LDR

Type-C显示器C接口的未来:高效连接与无限可能 随着科技的飞速发展,我们的日常生活和工作中对于高效、便捷的连接方式的需求日益增加。在这样的背景下,Type-C接口显示器凭借其卓越的性能和广泛的兼容性,正逐渐崭露头角&#xff0c…

RIP路由协议汇总(华为)

#交换设备 RIP路由协议汇总 一、原理概述 当网络中路由器的路由条目非常多时,可以通过路由汇总(又称路由汇聚或路由聚合)来减少路由条目数,加快路由收敛时间和增强网络稳定性。路由汇总的原理是,同一个自然网段内的不…

C++11默认成员函数控制

默认成员函数有 如果自己不显示声明,那么默认编译器会自己生成一个 如果有一个构造函数被声明了,那其他的默认函数编译器就不会再生成 这样的有时又不生成,容易造成混乱,于是C11让程序员可以控制是否需要编译器生成。 显式缺省函…

MEMS:Lecture 16 Gyros

陀螺仪原理 A classic spinning gyroscope measures the rotation rate by utilizing the conservation of angular momentum. 经典旋转陀螺仪通过利用角动量守恒来测量旋转速率。 Coriolis Effect and Coriolis Force 科里奥利效应是一种出现在旋转参考系中的现象。它描述了…

多线程中run()和start()的区别

我们知道,在多线程中 Thread thread new Thread(runnable); thread.start();以及 thread.run();都可以执行runnable中run方法下的代码,但是二者又有所不同 下面给出一段代码用以体现二者的区别: 以下代码中,通过thread.start()启…

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

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

2024全新仿麻豆视频苹果cms源码v10影视模板

下载地址:2024全新仿麻豆视频苹果cms源码v10影视模板 高端大气的设计,适合做电影、连续剧、综艺、动漫、微电影、纪录片、海外剧等视频网站

Leetcode419. 甲板上的战舰

Every day a Leetcode 题目来源:419. 甲板上的战舰 解法1:一次遍历 战舰的个数,等于战舰「头部」的个数。 具体来说,如果位于 (i, j) 的格子是战舰的头部,那么左边和上边的相邻格子不能是 X。 代码: …

OrangePi AIpro 机器人仿真与人工智能应用测评

系列文章目录 前言 本篇文章分为2个部分,第一部分主要搭建了机器人的仿真环境(ROS2 MuJoCo等),运行了机械臂及移动机器人相关示例程序;第二部分运行了OrangePi AIpro系统自带的示例程序及昇腾社区官方的示例程序&#…

MySQL 使用 MyFlash 快速恢复误删除、误修改数据

一、MyFlash MyFlash 是由美团点评公司技术工程部开发并维护的一个开源工具,主要用于MySQL数据库的DML操作的回滚。这个工具通过解析binlog日志,帮助用户高效、方便地进行数据恢复。MyFlash的优势在于它提供了更多的过滤选项,使得回滚操作变…

一文了解Spark引擎的优势及应用场景

Spark引擎诞生的背景 Spark的发展历程可以追溯到2009年,由加州大学伯克利分校的AMPLab研究团队发起。成为Apache软件基金会的孵化项目后,于2012年发布了第一个稳定版本。 以下是Spark的主要发展里程碑: 初始版本发布:2010年开发…

mysql报错Access denied for user ‘root‘,navicat可以连接mysql,spring不能连mysql

首先修改配置文件跳过验证,编辑你自己挂载的配置文件的位置 #查找my.cnf位置 sudo find / -name "my.cnf"编辑mysql配置文件 vim /opt/soft/mysql/conf/my.cnf #在[mysqld]下面添加 skip_grant_tables#重启mysql docker restart mysql#进入容器 docke…

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

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

快速数据处理:软件功能简介及下载

目录 1 功能介绍 1.1 封面 1.2 可定制功能 1.3 支持的操作系统和CPU 1.4 数据上报 1.5 数据接收 1.5 附带的测试数据 1.6 关于内置python的说明 2 软件下载 3 待开发功能 发布这个程序的原因是,前面写的这个专题的几篇文章,我原以为一点用也没…

代码随想录算法训练营第三十六天| 452. 用最少数量的箭引爆气球, 435. 无重叠区间 ,763.划分字母区间

452. 用最少数量的箭引爆气球 - 力扣&#xff08;LeetCode&#xff09; class Solution {public int findMinArrowShots(int[][] points) {if (points.length < 1) {return points.length;}Arrays.sort(points, (o1, o2) -> {if (o1[0] ! o2[0]) {return o1[0] < o2[0…

局域网监控软件有哪些:五款好用的网络监控神器分享(收藏篇)

在日益复杂的企业网络环境中&#xff0c;有效地监控局域网内的活动对于确保网络安全、提高工作效率和维护企业资产至关重要。 为此&#xff0c;精选了五款市场上广受好评的局域网监控软件&#xff0c;它们各自具备独特的功能和优势&#xff0c;能够满足不同规模企业的需求&…