【Linux系统编程】代码调试工具gdb--2

简介: 【Linux系统编程】代码调试工具gdb--2

【Linux系统编程】代码调试工具gdb--1 https://developer.aliyun.com/article/1424715

 当设置完断点后可使用 info b 指令查看我们设置的所有断点。具体的解释如下:


//使用b n 在第n行设置断点,设置完之后可观察到断点的地址、文件的来源和设置的行数
(gdb) b 5     
Breakpoint 1 at 0x4007e5: file code.cpp, line 5.     
(gdb) b 8
Breakpoint 2 at 0x4007f5: file code.cpp, line 8.
(gdb) b 11
Breakpoint 3 at 0x40081d: file code.cpp, line 11.
(gdb) info b
//显示所有有关断点的信息
/*Num表示断点的编号。Type表示设置类型,这里是断点。 Enb表示断点的功能的开闭,y是yes的意思,表示断点的功能正常,n是no的意思,表示断点的功能关闭,但断点还存在。Address表示断点的地址。What表示断点在哪个函数、哪个文件、哪一行中。*/
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004007e5 in main() at code.cpp:5
2       breakpoint     keep y   0x00000000004007f5 in main() at code.cpp:8
3       breakpoint     keep y   0x000000000040081d in main() at code.cpp:11


       delete(简写:d)是删除断点的指令。使用方法:d n 删除编号为n的断点。注意,这里的n代表编号,不是行数。这里可使用info b指令查看Num中的标号。


(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004007e5 in main() at code.cpp:5
2       breakpoint     keep y   0x00000000004007f5 in main() at code.cpp:8
3       breakpoint     keep y   0x000000000040081d in main() at code.cpp:11
(gdb) d 1       //删除编号1的断点
(gdb) info b
Num     Type           Disp Enb Address            What
2       breakpoint     keep y   0x00000000004007f5 in main() at code.cpp:8
3       breakpoint     keep y   0x000000000040081d in main() at code.cpp:11
(gdb) d 2       //删除编号2的断点
(gdb) info b
Num     Type           Disp Enb Address            What
3       breakpoint     keep y   0x000000000040081d in main() at code.cpp:11
(gdb) d 3        //删除编号3的断点
(gdb) info b
No breakpoints or watchpoints.    //显示断点已删除完毕

 


       当我们设置完断点时,默认断点的功能是打开的。当我们使用 disable n(这里的n表示断点的编号) 指令时,可将编号为n的断点功能失效,但不删除。当使用 enable n(这里的n表示断点的编号) 指令时,可将编号为n的断点功能打开,与disable功能相反。


       这里要说明的是,使用disable/enable后,由于调试断点的设置已被更改,当使用 r(run) 运行程序时,系统可能会提醒是否重新生成程序运行。


(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004007e5 in main() at code.cpp:5
2       breakpoint     keep y   0x00000000004007f5 in main() at code.cpp:8
3       breakpoint     keep y   0x000000000040081d in main() at code.cpp:11
(gdb) disable 2
(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004007e5 in main() at code.cpp:5
2       breakpoint     keep n   0x00000000004007f5 in main() at code.cpp:8
3       breakpoint     keep y   0x000000000040081d in main() at code.cpp:11
(gdb) enable 2
(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004007e5 in main() at code.cpp:5
2       breakpoint     keep y   0x00000000004007f5 in main() at code.cpp:8
3       breakpoint     keep y   0x000000000040081d in main() at code.cpp:11

逐过程和逐语句:


       逐语句是一行一行进行分析,它将会进入函数内部。逐过程是一次直接执行一个过程,它将一次直接执行完一个函数,不会进行函数内部分析。


       在gdb调试中,逐过程的指令是next,简写:n。逐语句的指令是step,简写:s。当在使用一次逐过程/逐语句后,下面直接按 “回车” 键即可继续往下面运行,也可不断使用n/s往下面运行,而在此过程中,我们可使用 p [变量](print的简写) 查看变量的内容,如:p n 查看数据中n的值,p &s 查看变量s的地址。这里需注意,p指令使用无法一直显示数据,当再次进行操作时,变量的内容将会消失。display [变量] 将会永久的显示数据。undisplay n(这里的n代表编号) 将会把编号为n的显示内容删除。


(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004007f3 in main() at code.cpp:6
2       breakpoint     keep y   0x0000000000400839 in main() at code.cpp:13
3       breakpoint     keep y   0x00000000004008fd in main() at code.cpp:20
4       breakpoint     keep y   0x0000000000400a15 in main() at code.cpp:30
(gdb) r
.........
(gdb) n   //逐过程分析
8            cout << "兔子" << endl;
(gdb)    //回车继续运行
兔子
main () at code.cpp:9
9            i++;
.........
//使用p指令显示一次数据的内容
(gdb) p i   
$1 = 5
(gdb) p n
$2 = 10
(gdb) p &i
$3 = (int *) 0x7fffffffe4dc
//可发现p指令不能永久显示
(gdb) n
8            cout << "兔子" << endl;
//使用display指令永久显示数据内容
(gdb) display i
1: i = 6    //i变量编号1
(gdb) display n
2: n = 10  //n变量编号2
//逐过程继续运行还会看到数据内容
(gdb) n
兔子
9            i++;
2: n = 10
1: i = 6
//使用undisplay指令删除指定数据内容,注意,这里要输入编号
(gdb) undisplay n   //输入变量,出现错误
warning: bad display number at or near 'n'
(gdb) undisplay 2  //输入编号2,删除编号2变量的内容
(gdb) n
8            cout << "兔子" << endl;
1: i = 8

范围式查找:


       范围式调试常用指令有以下:


           continue(简写:c):从一个断点运行到下一个断点或程序结束。它通常用来范围查找。


           bt:查看当前函数的堆栈信息,根据函数栈帧发现问题。


           finish:运行当前所在的函数,将当前所在的一个函数运行结束后就停止。但是,它不会            将主函数一次运行完。


           until n(n代表行号):直接将程序运行到第n行,若中间出现死循环,在运行中将会出现死            循环问题。


       以上几个指令都是在源代码基础上进行局部分析,但在调试中,我们可能会想测试源代码中某些变量改变后的情况。通常,使用 set var [改变内容] 指令即可完成。如:set var flag=0 查看将源代码中变量flag的值变为0时的测试情况。


注意:


       1,使用set var指令改变内容时,要改变的变量必须已经在内部存储过,即程序已经运行到这部分时才可改变。


       2,set var改变内容只是在测试中改变,不会影响源代码的内容,在测试时可放心使用。


(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004007f3 in main() at code.cpp:6
2       breakpoint     keep y   0x0000000000400855 in main() at code.cpp:14
3       breakpoint     keep y   0x00000000004008fd in main() at code.cpp:20
4       breakpoint     keep y   0x0000000000400a15 in main() at code.cpp:30
(gdb) r       //run的简写,直接运行到编号1断点的位置
.............
(gdb) c      //continue的简写,从当前断点位置运行到编号2断点的位置
.............
(gdb) bt
#0  main () at code.cpp:14   //主函数栈帧
(gdb) until 18    //将程序从当前位置直接运行到第18行
.............
(gdb) set var i=6    //改变变量i的值
(gdb) p i    //查看i已经改变过
$1 = 6
(gdb) finish   //直接运行完一个函数(方法),这里程序在主函数中,因此不能正常运行
"finish" not meaningful in the outermost frame.


相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
相关文章
|
3天前
|
Linux C语言 调度
|
3天前
|
Linux API
Linux系统编程之文件编程常用API回顾和文件编程一般步骤
Linux系统编程之文件编程常用API回顾和文件编程一般步骤
Linux系统编程之文件编程常用API回顾和文件编程一般步骤
|
3天前
|
NoSQL Java Unix
Linux:调试器 - gdb
Linux:调试器 - gdb
17 1
|
3天前
|
NoSQL Linux 编译器
【Linux】开始使用gdb吧!
这篇文章我们来学习 gdb 的使用方法。我们在Windows端编写代码时有宇宙最强编译器VS2022帮助我们调试,那Linux端有没有一款强大的调试工具呢???
52 17
【Linux】开始使用gdb吧!
|
3天前
|
存储 算法 网络协议
【探索Linux】P.26(网络编程套接字基本概念—— socket编程接口 | socket编程接口相关函数详细介绍 )
【探索Linux】P.26(网络编程套接字基本概念—— socket编程接口 | socket编程接口相关函数详细介绍 )
13 0
|
3天前
|
安全 Linux Python
Volatility3内存取证工具安装及入门在Linux下的安装教程
Volatility3内存取证工具安装及入门在Linux下的安装教程
Volatility3内存取证工具安装及入门在Linux下的安装教程
|
3天前
|
NoSQL Linux C语言
【Linux】Linux调试器-gdb使用
【Linux】Linux调试器-gdb使用
8 0
|
3天前
|
数据可视化 小程序 Linux
【Linux】自动化构建工具make/Makefile和git介绍
【Linux】自动化构建工具make/Makefile和git介绍
17 0
|
3天前
|
缓存 Linux
linux性能分析之内存分析(free,vmstat,top,ps,pmap等工具使用介绍)
这些工具可以帮助你监视系统的内存使用情况、识别内存泄漏、找到高内存消耗的进程等。根据具体的问题和需求,你可以选择使用其中一个或多个工具来进行内存性能分析。注意,内存分析通常需要综合考虑多个指标和工具的输出,以便更好地理解系统的行为并采取相应的优化措施。
32 6