【Linux】工具Gdb调试轻度使用(C++)
目录
一、Gdb背景
二、Gdb基本命令
【2.1】list | l
【2.2】break | b
【2.5】delete | d
【2.6】disable
【2.7】enable
【2.3】info
【2.4】info locals
【2.6】run | r
【2.7】next | n
【2.8】step | s
【2.9】 continue | c
【2.10】bt
【2.11】finish
三、Gdb查看变量
【3.1】p
【3.2】display
【3.2】undisplay
【3.3】until
【3.4】set var
一、Gdb背景
-
程序的发布方式有两种,debug模式和release模式。
-
Linux gcc/g++出来的二进制程序,默认是release模式。
-
要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 -g 选项 。

// 查看可执行程序的指令:
readelf -S progressBar
readelf -S progressBar | grep debug
二、Gdb基本命令
【2.1】list | l
显示当前函数中的代码。
列出当前函数中代码。// 命令:
list [函数名]
l [函数名]
(gdb) list 0 // 显示行命令.
1 #include "ProgressBar.h"
2
3 int main(){
4 ProgressBar(); // 进度条函数调用.
5 return 0;
6 }
(gdb)
-----------------------------------------------------------------------------------------
(gdb) list ProgressBar // 显示指定函数.
1 #include "ProgressBar.h"
2
3 // 进度条函数实现.
4 void ProgressBar(){
5 // 进度条存储区.
6 char arrBar[NUM];
7 // 进度条存储区初始化.
8 memset(arrBar, '\0', sizeof(arrBar));
9 const char* flag = "|\\-/";
10 char style[STYLE_NUM] = {'+', '=', '*', '>', '#'};
(gdb) // 回车继续显示
11
12 for(int i = 0; i <= 100; i++){
13 printf("[%-100s][%2d%%][%c]\r", arrBar, i, flag[i % 4]);
14 fflush(stdout); // 立即打印刷新.
15
16 arrBar[i] = style[N]; // 存入打印风格的字符.
17 usleep(10000); // 休眠以微妙为单位.
18 }
19 printf("\n");
20 }
【2.2】break | b
设置断点。
// 命令:
break 行号
b 行号(gdb) b 6 // Main.c中main函数第6行打断点
Breakpoint 4 at 0x40066b: file Main.c, line 6.
(gdb) b 7 // ProgressBar.c中ProgressBar函数第7行打断点
Breakpoint 5 at 0x400684: file ProgressBar.c, line 7.(gdb) info b // 查看已设置的断点
Num Type Disp Enb Address What
4 breakpoint keep y 0x000000000040066b in main at Main.c:6
5 breakpoint keep y 0x0000000000400684 in ProgressBar at ProgressBar.c:7
【2.5】delete | d
删除断点。
// 命令:
delete [断点编号] // 删除断点
d [断点编号] // 删除断点(gdb) info break // 查看断点
Num Type Disp Enb Address What
1 breakpoint keep y 0x000000000040066b in main at Main.c:6
2 breakpoint keep y 0x0000000000400684 in ProgressBar at ProgressBar.c:7
(gdb) d 1 // 删除编号为1的断点
(gdb) info break // 查看断点
Num Type Disp Enb Address What
2 breakpoint keep y 0x0000000000400684 in ProgressBar at ProgressBar.c:7
(gdb) delete 2 // 删除编号为2的断点
(gdb) info break // 查看断点
No breakpoints or watchpoints.// 下面直接输入d删除所有的断点
(gdb) info b // 查看断点
Num Type Disp Enb Address What
5 breakpoint keep y 0x000000000040066b in main at Main.c:6
6 breakpoint keep y 0x0000000000400684 in ProgressBar at ProgressBar.c:7
(gdb) d // 删除所有的断点
Delete all breakpoints? (y or n) y
(gdb) info b // 查看断点
No breakpoints or watchpoints.
【2.6】disable
禁用断点。
// 命令:
disable [断点编号](gdb) info b // 显示所有设置的断点
Num Type Disp Enb Address What
1 breakpoint keep y 0x000000000040066b in main at Main.c:6
2 breakpoint keep y 0x0000000000400684 in ProgressBar at ProgressBar.c:7
(gdb) disable 1 // 禁用断点
(gdb) info b // 显示所有设置的断点 Enb 变成了n
Num Type Disp Enb Address What
1 breakpoint keep n 0x000000000040066b in main at Main.c:6
2 breakpoint keep y 0x0000000000400684 in ProgressBar at ProgressBar.c:7
【2.7】enable
启动断点。
// 命令:
enable [断点编号](gdb) info b // 显示所有设置的断点
Num Type Disp Enb Address What
1 breakpoint keep n 0x000000000040066b in main at Main.c:6
2 breakpoint keep y 0x0000000000400684 in ProgressBar at ProgressBar.c:7
(gdb) enable 1 // 使能断点
(gdb) info b // 显示所有设置的断点 Enb 变成了y
Num Type Disp Enb Address What
1 breakpoint keep y 0x000000000040066b in main at Main.c:6
2 breakpoint keep y 0x0000000000400684 in ProgressBar at ProgressBar.c:7
【2.3】info
查看断点。
// 命令:
info break // 查看断点
info b // 查看断点(gdb) info b // 显示已设置的断点
Num Type Disp Enb Address What
1 breakpoint keep y 0x000000000040066b in main at Main.c:6
2 breakpoint keep y 0x0000000000400684 in ProgressBar at ProgressBar.c:7
(gdb) info break // 显示已设置的断点
Num Type Disp Enb Address What
1 breakpoint keep y 0x000000000040066b in main at Main.c:6
2 breakpoint keep y 0x0000000000400684 in ProgressBar at ProgressBar.c:7
【2.4】info locals
显示当前堆栈局部变量的值。
// 命令:info locals// -- 在ProgressBar()函数中
(gdb) info locals
bar = "####", '\000' <repeats 46 times>, "##", '\000' <repeats 48 times>
cnt = 52
style = "+=>#."
lable = 0x4007c0 "|\\-/"
【2.6】run | r
运行。
// 指定:
run // 直接运行
r // 直接运行(gdb) r // 运行程序
Starting program: /home/shaxiang/CodeDemo/Linux/ProgressBar/progressBar
Missing separate debuginfos, use: debuginfo-install glibc-2.17-326.el7_9.x86_64
[####################################################################################################][100%][|]
[Inferior 1 (process 16045) exited normally]
(gdb) run // 运行程序
Starting program: /home/shaxiang/CodeDemo/Linux/ProgressBar/progressBar
[####################################################################################################][100%][|]
[Inferior 1 (process 16091) exited normally]
【2.7】next | n
逐过程调试。
// 指令:
next // 逐过程运行
n // 逐过程运行Breakpoint 7, main () at Main.c:6
6 ProgressBar(); // 在断点处停下来
(gdb) n // 逐过程运行
Breakpoint 8, ProgressBar () at ProgressBar.c:7
7 memset(bar, '\0', sizeof(bar));
(gdb) n // 逐过程运行
9 int cnt = 0;
(gdb) n // 逐过程运行
11 const char* lable = "|\\-/";
(gdb) n // 逐过程运行
12 while(cnt <= 100)
(gdb) n // 逐过程运行
14 printf("[%-100s][%2d%%][%c]\r", bar, cnt, lable[cnt % 4]);
【2.8】step | s
逐语句调试。
// 指令:
step // 逐语句运行
s // 逐语句运行Breakpoint 7, main () at Main.c:6
6 ProgressBar(); // 在断点处停下来
(gdb) s // 逐语句运行
Breakpoint 8, ProgressBar () at ProgressBar.c:7
7 memset(bar, '\0', sizeof(bar));
(gdb) s // 逐语句运行
9 int cnt = 0;
(gdb) s // 逐语句运行
11 const char* lable = "|\\-/";
(gdb) s // 逐语句运行
12 while(cnt <= 100)
(gdb) s // 逐语句运行
14 printf("[%-100s][%2d%%][%c]\r", bar, cnt, lable[cnt % 4]);
【2.9】 continue | c
运行到下一个断点。
// 指令:
continue // 运行到下一个断点
c // 运行到下一个断点12 while(cnt <= 100)
(gdb) s // 逐语句运行
14 printf("[%-100s][%2d%%][%c]\r", bar, cnt, lable[cnt % 4]);
(gdb) s // 逐语句运行
15 fflush(stdout); // 将数据立马刷新到缓冲区
(gdb) s // 逐语句运行
17#### bar[cnt++] = style[S]; ][ 5%][\]
(gdb) s // 逐语句运行
18 usleep(50000);
(gdb) c // 运行到下一个断点
Continuing.
[####################################################################################################][100%][|]
[Inferior 1 (process 17750) exited normally]
【2.10】bt
查看堆栈。
// 命令:
bt // 查看堆栈(gdb) r // 运行
Starting program: /home/shaxiang/CodeDemo/Linux/ProgressBar/progressBar
Breakpoint 7, main () at Main.c:6
6 ProgressBar(); // 在断点处停下来
(gdb) s // 逐语句运行
Breakpoint 8, ProgressBar () at ProgressBar.c:7
7 memset(bar, '\0', sizeof(bar));
(gdb) bt // 查看堆栈
#0 ProgressBar () at ProgressBar.c:7
#1 0x0000000000400675 in main () at Main.c:6
【2.11】finish
直接运行完函数。
// 命令:
finish // 运行完函数(gdb) r // 运行程序
Starting program: /home/shaxiang/CodeDemo/Linux/ProgressBar/progressBar
Breakpoint 7, main () at Main.c:6
6 ProgressBar(); // 在断点处停下来
(gdb) s // 逐语句运行
Breakpoint 8, ProgressBar () at ProgressBar.c:7
7 memset(bar, '\0', sizeof(bar));
(gdb) finish // 运行到函数后,直接运行完当前的函数
Run till exit from #0 ProgressBar () at ProgressBar.c:7
[####################################################################################################][100%][|]
main () at Main.c:8
8 return 0;
三、Gdb查看变量
【3.1】p
查看变量的值。
p [变量名] // 查看该变量的值12 while(cnt <= 100) // while循环中运行
(gdb) s
14 printf("[%-100s][%2d%%][%c]\r", bar, cnt, lable[cnt % 4]);
(gdb) s
15 fflush(stdout); // 将数据立马刷新到缓冲区
(gdb) s
17 bar[cnt++] = style[S]; ][ 1%][\]
(gdb) s
18 usleep(50000);
(gdb) s
12 while(cnt <= 100)
(gdb) s
14 printf("[%-100s][%2d%%][%c]\r", bar, cnt, lable[cnt % 4]);
(gdb) s
15 fflush(stdout); // 将数据立马刷新到缓冲区
(gdb) s
17# bar[cnt++] = style[S]; ][ 2%][-]
(gdb) s
18 usleep(50000);
(gdb) p cnt // 查看p的值
$2 = 3
【3.2】display
跟踪查看变量的值。
// 命令:
display [变量名](gdb) display cnt // 跟踪cnt这个变量监控值的变化 (display &cnt 这样可以查看地址)
1: cnt = 5
(gdb) s
12 while(cnt <= 100)
1: cnt = 5
(gdb) s
14 printf("[%-100s][%2d%%][%c]\r", bar, cnt, lable[cnt % 4]);
1: cnt = 5
(gdb) s
15 fflush(stdout); // 将数据立马刷新到缓冲区
1: cnt = 5
(gdb) s
17#### bar[cnt++] = style[S]; ][ 5%][\]
1: cnt = 5
(gdb) s
18 usleep(50000);
1: cnt = 6
【3.2】undisplay
取消跟踪查看变量的值。
// 命令:
undisplay [变量名](gdb) undisplay 1 // 取消跟踪cnt这个变量监控值的变化
(gdb) s
12 while(cnt <= 100)
(gdb) s
14 printf("[%-100s][%2d%%][%c]\r", bar, cnt, lable[cnt % 4]);
(gdb) s
15 fflush(stdout); // 将数据立马刷新到缓冲区
(gdb) s
17##### bar[cnt++] = style[S]; ][ 6%][-]
(gdb) s
18 usleep(50000);
【3.3】until
跳转指定行。
// 指令:
until [行号] // 跳转行号12 while(cnt <= 100) // 循环运行
(gdb) s
14 printf("[%-100s][%2d%%][%c]\r", bar, cnt, lable[cnt % 4]);
(gdb) s
15 fflush(stdout); // 将数据立马刷新到缓冲区
(gdb) s
17###### bar[cnt++] = style[S]; ][ 9%][\]
(gdb) s
18 usleep(50000);
(gdb) s
12 while(cnt <= 100) // 循环运行
(gdb) s
14 printf("[%-100s][%2d%%][%c]\r", bar, cnt, lable[cnt % 4]);
(gdb) s
15 fflush(stdout); // 将数据立马刷新到缓冲区
(gdb) s
17###### bar[cnt++] = style[S]; ][10%][-]
(gdb) s
18 usleep(50000);
(gdb) until 20 // 跳转到指定的行
ProgressBar () at ProgressBar.c:20###################################################################][100%][|]
20 printf("\n");
【3.4】set var
设定指定的值。
// 指定
set var [变量名] // 设定指定的变量的值。12 while(cnt <= 100)
2: cnt = 4
(gdb) s
14 printf("[%-100s][%2d%%][%c]\r", bar, cnt, lable[cnt % 4]);
2: cnt = 4
(gdb) s
15 fflush(stdout); // 将数据立马刷新到缓冲区
2: cnt = 4
(gdb) s
17### bar[cnt++] = style[S]; ][ 4%][|]
2: cnt = 4
(gdb) set var cnt=50 // 设定指定的变量值!!!!!!
(gdb) s
18 usleep(50000);
2: cnt = 51
(gdb) s
12 while(cnt <= 100)
2: cnt = 51
(gdb) s
14 printf("[%-100s][%2d%%][%c]\r", bar, cnt, lable[cnt % 4]);
2: cnt = 51
(gdb) s
15 fflush(stdout); // 将数据立马刷新到缓冲区
2: cnt = 51
(gdb) s
17### bar[cnt++] = style[S]; ][51%][/]
2: cnt = 51
(gdb) s
18 usleep(50000);
2: cnt = 52相关文章:
【Linux】工具Gdb调试轻度使用(C++)
目录 一、Gdb背景 二、Gdb基本命令 【2.1】list | l 【2.2】break | b 【2.5】delete | d 【2.6】disable 【2.7】enable 【2.3】info 【2.4】info locals 【2.6】run | r 【2.7】next | n 【2.8】step | s 【2.9】 continue | c 【2.10】bt 【2.11】finish 三…...
linux xhost命令
xhost命令 XHOST 用于管理允许访问系统上 X Server 的主机和用户列表,这些主机和用户都可以从其他主机和同一系统上的其他用户访问。 通常,远程访问将被禁用,因为它会带来安全风险。 但是,如果我们需要在远程计算机上运行 GUI &…...
linux在线源码阅读网站
下面的网站可以在线阅读linux源码,提供了类似github上分析工具,自动具备符号关联的作用,可以方便的供用户分析代码。除了可以分析linux源码外,该网站还可以分析一些其它源码,例如qt等 这个网站有许多功能,…...
css中只使用vue的变量
参考:https://blog.csdn.net/FellAsleep/article/details/130617163 1、必须作用在用一个div上 2、变量必须有双横杠“–” <spanclass"bb" :style"spanStyle">11</span>data() {return {spanStyle: {"--color": #bfa /…...
华为云云耀云服务器L实例评测 | 由于自己原因导致MySQL数据库被攻击 【更新中。。。】
目录 引出起因(si因)解决报错诶嘿,连上了 不出意外,就出意外了打开数据库what??? 找华为云求助教训:备份教训:密码 解决1.改密码2.新建一个MySQL,密码设置复杂…...
如何查询成绩或工资
为什么每次查询成绩或者工资的时候都觉得麻烦又耗时呢?在过去,我们可能需要去学校或公司的相关部门,填写繁琐的表格,然后等待工作人员进行查询和处理。这不仅浪费了我们宝贵的时间,还可能出现查询结果不准确或者遗漏的…...
FPGA原理与结构——时钟IP核的使用与测试
一、前言 本文介绍xilinx的时钟IP核 Clocking Wizard v6.0的具体使用与测试过程,在学习一个IP核的使用之前,首先需要对于IP核的具体参数和原理有一个基本的了解,具体可以参考: FPGA原理与结构——时钟IP核原理学习https://blog.c…...
手搓消息队列【RabbitMQ版】
什么是消息队列? 阻塞队列(Blocking Queue)-> 生产者消费者模型 (是在一个进程内)所谓的消息队列,就是把阻塞队列这样的数据结构,单独提取成了一个程序,进行独立部署~ --------&…...
Oracle VM VirtualBox 安装 Ubuntu Linux
Virtual Box VirtualBox是一个强大的、面向个人用户或者企业用户的虚拟机产品,其支持x86以及AMD64/Intel64的计算架构,功能特性丰富、性能强劲,支持GPL开源协议,其官方网址是www.virtualbox.org,由Oracle开源…...
3D WEB轻量化引擎HOOPS Commuicator技术概览(一):数据导入与加载
HOOPS Communicator是一款功能强大的SDK,适用于基于Web的高级工程应用程序,代表HOOPS Web平台的Web开发组件。使用HOOPS Communicator,您可以构建一个在 Web浏览器中提供3D模型的Web应用程序。 HOOPS Communicator可以本地加载多种模型格式。…...
.net 7 隐藏swagger的api
1.写一个隐藏接口特性表示 using Microsoft.AspNetCore.Mvc.ApiExplorer; using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen;using System.Web.Http.Description;namespace JiaTongInterface.Filter {public class SwaggerApi : Swashbuckle.AspNet…...
Maven插件的作用
插件-maven-compiler-plugin <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <sourc…...
C++(三)——运算符重载
运算符重载 重定义或重载大部分 C 内置的运算符就能使用自定义类型的运算符。重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。不能为了重载而重…...
【Springcloud】elk分布式日志
【Springcloud】elk分布式日志 【一】基本介绍【二】Elasticsearch【1】简介【2】下载【3】安装【4】启动 【三】Logstash【1】简介【2】下载【3】安装【4】启动 【四】Kibana【1】简介【2】下载【3】安装【4】启动 【五】切换中文【六】日志收集 【一】基本介绍 (…...
面试半个月后的一些想法
源于半个月面试经历后的一些想法,刚开始想的是随便写写,没想到居然写了这么多。 找不到目标找不到意义亦或是烦躁的时候,就写写文章吧,把那些困扰你很久的问题铺开来 花时间仔细想想,其实真正让我们生气懊恼࿰…...
基于FPGA的图像二值化处理,包括tb测试文件和MATLAB辅助验证
1.算法运行效果图预览 将FPGA的数据导入到matlab进行显示 2.算法运行软件版本 Vivado2019.2 matlab2022a 3.部分核心程序 timescale 1ns / 1ps ............................................................................. module test_image;reg i_clk; reg i_rst; r…...
文件操作(个人学习笔记黑马学习)
C中对文件操作需要包含头文件<fstream > 文件类型分为两种: 1.文本文件:文件以文本的ASCII码形式存储在计算机中 2.二进制文件:文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们 操作文件的三大类: 1.ofstream: 写操作 …...
Android Studio新版本New UI及相关设置丨遥遥领先版
1、前言 俗话说工欲善其事必先利其器嘛,工具用不好怎么行呢,借着Android Studio的更新,介绍一下新版本中的更新内容,以及日常开发中那些好用的设置。 2、关于新版本 2.1、最新正式版本 Android Studio Giraffe | 2022.3.1 Pat…...
新型人工智能技术让机器人的识别能力大幅提升
原创 | 文 BFT机器人 在德克萨斯大学达拉斯分校的智能机器人和视觉实验室里,一个机器人在桌子上移动一包黄油玩具。通过达拉斯分校计算机科学家团队开发的新系统,机器人每推动一次,就能学会识别物体。 新系统允许机器人多次推动物体…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...
LangFlow技术架构分析
🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...
