【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机器人 在德克萨斯大学达拉斯分校的智能机器人和视觉实验室里,一个机器人在桌子上移动一包黄油玩具。通过达拉斯分校计算机科学家团队开发的新系统,机器人每推动一次,就能学会识别物体。 新系统允许机器人多次推动物体…...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !
我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...
6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础
第三周 Day 3 🎯 今日目标 理解类(class)和对象(object)的关系学会定义类的属性、方法和构造函数(init)掌握对象的创建与使用初识封装、继承和多态的基本概念(预告) &a…...
