【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机器人 在德克萨斯大学达拉斯分校的智能机器人和视觉实验室里,一个机器人在桌子上移动一包黄油玩具。通过达拉斯分校计算机科学家团队开发的新系统,机器人每推动一次,就能学会识别物体。 新系统允许机器人多次推动物体…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...

大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...