【Linux】工具Gdb调试轻度使用(C++)

news2025/2/25 15:11:32

目录

一、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

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

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

相关文章

idea报错“Static methods in interface require -target:jvm-1.8”

如题&#xff0c;在 idea 中跑 java 、scala 混编代码时&#xff0c;出现上面的错误。 问题的原因很明显是 idea 中的 jdk 版本设置有问题&#xff0c;针对性作如下排查&#xff1a; 检查项目的 java 版本 在File-> Project Settings中&#xff0c;检查检查idea的 java 版本…

SQL Server 跨库/服务器查询

这里写目录标题 1 SQL Server 跨库/服务器查询1.1 跨库查询1.2 跨服务器查询1.2.1 创建链接服务器1.2.2 跨库查询 1.3 拓展&#xff1a;SQL Server 中所有权和用户与架构的分离 1 SQL Server 跨库/服务器查询 1.1 跨库查询 在同一服务器下的跨库查询较为简单&#xff0c;示例…

QT Creator更改主题和编辑器风格(附几款黑色主题)

适用于qtcreator 一、使用自带主题与编辑器风格 打开Qt选择"工具"->"选项"&#xff1b; 2. 选择"环境"->"Theme"切换不同的主题风格 这里切换的是外边框的风格&#xff0c;如果编辑器中有同名的风格&#xff0c;编辑器的风格也…

【计算机基础知识9】前端设计模式与常见类型

目录 一、前言 二、设计模式的基本概念和原则 三、创建型设计模式 四、结构型设计模式 五、行为型设计模式 六、MVC和MVVM框架中的设计模式 七、实际应用案例分析 一、前言 在软件开发领域&#xff0c;设计模式是一种解决常见问题的最佳实践&#xff0c;它可以帮助开发…

手敲Cocos简易地图编辑器:人生地图是一本不断修改的书,每一次编辑都是为了克服新的阻挡

引言 本系列是《8年主程手把手打造Cocos独立游戏开发框架》&#xff0c;欢迎大家关注分享收藏订阅。 在上一篇文章&#xff0c;笔者给大家讲解了在Cocos独立游戏开发框架中&#xff0c;如何自定义实现Tile地图管理器&#xff0c;成功地在游戏中优化加载一张特大的地图。接下来…

持久层框架之Mybatis

概述 MyBatis是apache的一个开源项目iBatis,2010年改名为MyBatis,2013年11月迁移到GithubMyBatis是一款优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注SQL本身而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结…

软件设计模式系列之二——抽象工厂模式

1 抽象工厂模式的定义 抽象工厂模式是一种创建型设计模式&#xff0c;它提供了一种创建一组相关或相互依赖对象的方式&#xff0c;而无需指定它们的具体类。该模式以一组抽象接口为核心&#xff0c;包括抽象工厂接口和一组抽象产品接口&#xff0c;每个具体工厂类负责创建特定…

More Effective C++学习笔记(5)

目录 条款25&#xff1a;将构造函数和非成员函数虚化条款26&#xff1a;限制某个类所能产生的对象数量条款27&#xff1a;要求&#xff08;或禁止&#xff09;对象产生于heap&#xff08;堆&#xff09;之中条款28&#xff1a;智能指针条款29&#xff1a;引用计数条款30&#x…

uview indexList 按字母跳转不了

点击字母跳转不到位的问题&#xff1a;在<u-index-list>添加方法select“clickSelect“ 锚点要加id&#xff0c;用对应的字母做为id值&#xff0c; <u-index-anchor :id"key" :index"key"/> <template><view><view class&qu…

法国新法案强迫 Firefox 等浏览器审查网站

导读Mozilla 基金会已发起了一份请愿书&#xff0c;旨在阻止法国政府强迫 Mozilla Firefox 等浏览器审查网站。 据悉&#xff0c;法国政府正在制定一项旨在打击网络欺诈的 SREN 法案 (“Projet de loi Visant scuriser et reguler lespace numrique”)&#xff0c;包含大约 2…

将本地jar包手动添加到Maven仓库依赖处理

一、起因 在日常开发中&#xff0c;经常会遇到一些情况&#xff0c;就是在更新Maven时&#xff0c;从网上下载jar包的时候网络不稳定或者其他原因导致jar包数据缺失而导致的依赖无法正常引入的情况. 还有一些其他情况如个人jar包一类的。 二、解决 以前以上这些情况&#x…

三维模型3DTile格式轻量化压缩处理效率提高的技术方浅析

三维模型3DTile格式轻量化压缩处理效率提高的技术方浅析 随着三维模型在各个领域的广泛应用&#xff0c;对于其格式的轻量化压缩处理和效率提高的需求也越发迫切。本文将介绍一些技术方法&#xff0c;帮助实现三维模型3DTile格式的轻量化压缩处理并提高处理效率。 首先&#x…

手写Spring:第14章-自动扫描Bean对象注册

文章目录 一、目标&#xff1a;自动扫描Bean对象注册二、设计&#xff1a;自动扫描Bean对象注册三、实现&#xff1a;自动扫描Bean对象注册3.0 引入依赖3.1 工程结构3.2 Bean生命周期中自动加载包扫描注册Bean对象和设置占位符属性类图3.3 主力占位符配置3.4 定义拦截注解3.4.1…

从零到MySQL性能优化大师

一.MySQL架构 二.优化与执行 执行计划是MySQL优化器为了优化查询而生成的一种数据结构&#xff0c;它记录了数据库系统执行查询时所采取的操作流程&#xff0c;即对查询语句的各部分如何进行处理以最终得到查询结果的过程。执行计划通常被表示为一棵树状结构&#xff0c;节点代…

编程语言的类型划分

汇编语言 低级语言&#xff0c;通过汇编器翻译成机器语言 MOV、PUSH、ADD等 特点&#xff1a; 对机器友好、执行效率高、移植性差。 人类操作不太方便&#xff0c;需要专业人员。 高级语言 C、C、Java、Python、Golang等 最终还是会转化成为机器语言。 执行过程划分 编译型 ●…

华为云云耀云服务器L实例评测|使用Linux系统与Docker部署.net/c#项目

目录 前言 如何在CentOS运行项目 登录CentOS 使用Rider打包 使用Visual Studio打包 项目运行 后台运行 开放端口 如何在Docker中运行项目 项目运行 前言 本章详细介绍&#xff0c;.net Core项目从打包到部署上华为云云耀云服务器L实例的过程与一些细节问题。在这里…

XFF漏洞利用([SWPUCTF 2021 新赛]Do_you_know_http)

原理 常见的存在HTTP头注入的参数 User-Agent&#xff1a;使得服务器能够识别客户使用的操作系统&#xff0c;浏览器版本等.&#xff08;很多数据量大的网站中会记录客户使用的操作系统或浏览器版本等存入数据库中&#xff09; Cookie&#xff1a;网站为了辨别用户身份进行se…

前端js下载zip文件异常问题解决

目录 一&#xff0c;本文解决问题如下 二&#xff0c;原下载代码 1&#xff0c;ajax get 下载文件 2&#xff0c;下载异常图&#xff1a; 三&#xff0c;成功下载的 1&#xff0c; JQuery 实现文件下载xhr 2&#xff0c;图例 引言&#xff1a; 本人使用的ajax 下载&…

量化:基于支持向量机的择时策略

文章目录 参考机器学习简介策略简介SVM简介整体流程收集数据准备数据建立模型训练模型测试模型调节参数 参考 Python机器学习算法与量化交易 利用机器学习模型&#xff0c;构建量化择时策略 机器学习简介 机器学习理论主要是设计和分析一些让计算机可以自动“学习”的算法。…

Mybatis日期检索格式报错

问题复现 org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: java.lang.IllegalArgumentException: invalid comparison: java.util.Date and java.lang.String ##…