【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

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DHTMLX Gantt 8.0.5 Crack -甘特图

8.0.5 2023 年 9 月 1 日。错误修复版本 修复 修复通过gantt.getGanttInstance配置启用扩展而触发的错误警告修复启用skip_off_time配置时gantt.exportToExcel()的不正确工作示例查看器的改进 8.0.4 2023 年 7 月 31 日。错误修复版本 修复 修复数据处理器不跟踪资源数据…

MNIST手写数字辨识-cnn网路 (机器学习中的hello world,加油)

用PyTorch实现MNIST手写数字识别(非常详细) - 知乎 (zhihu.com) 参考来源&#xff08;这篇文章非常适合入门来看&#xff0c;每个细节都讲解得很到位&#xff09; 一、模块函数用法-查漏补缺&#xff1a; 1.关于torch.nn.functional.max_pool2d()的用法&#xff1a; 上述示例…

优化VUE Element UI的上传插件

默认ElmentUI的文件列表只有一个删除按钮&#xff0c;我需要加预览、下载、编辑等&#xff0c;就需要优化显示结果。 优化后没用上传进度条&#xff0c;又加了一个进度条效果 代码 <template><div><el-uploadclass"upload-demo"action"/"…

OPPO/真我手机ColorOS13系统解账户锁-移除手机密码图案锁方法

在搞机之前&#xff0c;请确定自己的手机不是非法获取&#xff0c;本文只讲叙ColorOS13系统解锁方法&#xff0c;仅为个人测试研究出来的经验&#xff0c;未对官方系统进行任何修改。只推荐专业维修师傅从维修的角度进行解锁&#xff0c;不推荐个人用户对非自己的手机进行非法破…

传输层-TCP 的安全机制和高效策略

可靠性&#xff1a; 之前我们在UDP中谈到了&#xff0c;UDP不可靠但是简单&#xff0c;TCP可靠但是也要做更多的工作&#xff0c;那这些工作具体是什么呢&#xff1f;接下来让我们详细了解一下。 确认应答机制&#xff08;ACK机制&#xff09; 序号&#xff1a;我们可以把TCP…

如何按文件名称自动归类,助您轻松管理文件

在日常工作和生活中&#xff0c;我们经常会遇到大量的文件需要管理。如果这些文件没有得到良好的归类和整理&#xff0c;不仅会浪费我们的时间和精力&#xff0c;还会给我们带来困扰和混乱。今天我们一起来看看怎么按文件名称来自动归类&#xff0c;批量整理文件&#xff0c;让…

云数据库知识学习——概述

一、云计算是云数据库兴起的基础 云计算是分布式计算、并行计算、效用计算、网络存储、虚拟化、负载均衡等计算机和网络技术发展融合的产物。云计算是由一系列可以动态升级和被虚拟化的资源组成的&#xff0c;用户无需掌握云计算的技术&#xff0c;只要通过网络就可以访问这些资…

图床项目性能测试

文章目录 一、FastDFS文件性能测试1.1 上传文件测试1.2 下载测试1.3 删除文件测试1.4 如何提高 二、图床项目wrklua性能测试2.1 wrk2.2 MySQL索引优化2.2 注册测试2.2.1 无索引性能2.2.2 有索引性能 2.3 登录测试2.3.1 无索引性能2.3.2 有索引性能 2.4 读取文件测试2.4.1 无索引…

异步编程 - 13 高性能线程间消息传递库 Disruptor

文章目录 Disruptor概述Disruptor中的核心术语Disruptor 流程图 Disruptor的特性详解基于Disruptor实现异步编程 Disruptor概述 Disruptor是一个高性能的线程间消息传递库&#xff0c;它源于LMAX对并发性、性能和非阻塞算法的研究&#xff0c;如今构成了其Exchange基础架构的核…

C#事件event

事件模型的5个组成部分 事件拥有者&#xff08;event source&#xff09;&#xff08;类对象&#xff09;&#xff08;有些书将其称为事件发布者&#xff09; 事件成员&#xff08;event&#xff09;&#xff08;事件拥有者的成员&#xff09;&#xff08;事件成员就是事件本身…

山西电力市场日前价格预测【2023-09-09】

日前价格预测 预测明日&#xff08;2023-09-09&#xff09;山西电力市场全天平均日前电价为372.85元/MWh。其中&#xff0c;最高日前电价为435.72元/MWh&#xff0c;预计出现在18: 45。最低日前电价为342.46元/MWh&#xff0c;预计出现在04: 00。 价差方向预测 1&#xff1a; 实…

关于HarmonyOS元服务的主题演讲与合作签约

一、感言 坚持中&#xff0c;总会有很多意想不到的收获。 前几次参与HDC时更多的是观众、开发者、专家的身份&#xff0c;以参观、学习、交流为主。 通过几年的努力&#xff0c;和HarmonyOS功能成长&#xff0c;在2023年的HDC大会中&#xff0c;有了我的演讲&#xff0c;并带领…