【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机器人 在德克萨斯大学达拉斯分校的智能机器人和视觉实验室里,一个机器人在桌子上移动一包黄油玩具。通过达拉斯分校计算机科学家团队开发的新系统,机器人每推动一次,就能学会识别物体。 新系统允许机器人多次推动物体…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
快刀集(1): 一刀斩断视频片头广告
一刀流:用一个简单脚本,秒杀视频片头广告,还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农,平时写代码之余看看电影、补补片,是再正常不过的事。 电影嘛,要沉浸,…...
Vite中定义@软链接
在webpack中可以直接通过符号表示src路径,但是vite中默认不可以。 如何实现: vite中提供了resolve.alias:通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...
云安全与网络安全:核心区别与协同作用解析
在数字化转型的浪潮中,云安全与网络安全作为信息安全的两大支柱,常被混淆但本质不同。本文将从概念、责任分工、技术手段、威胁类型等维度深入解析两者的差异,并探讨它们的协同作用。 一、核心区别 定义与范围 网络安全:聚焦于保…...
