【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
相关文章
|
1月前
|
Linux 网络安全 数据安全/隐私保护
Linux 超级强大的十六进制 dump 工具:XXD 命令,我教你应该如何使用!
在 Linux 系统中,xxd 命令是一个强大的十六进制 dump 工具,可以将文件或数据以十六进制和 ASCII 字符形式显示,帮助用户深入了解和分析数据。本文详细介绍了 xxd 命令的基本用法、高级功能及实际应用案例,包括查看文件内容、指定输出格式、写入文件、数据比较、数据提取、数据转换和数据加密解密等。通过掌握这些技巧,用户可以更高效地处理各种数据问题。
107 8
|
8天前
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
61 13
|
2月前
|
监控 Java Linux
Linux系统之安装Ward服务器监控工具
【10月更文挑战第17天】Linux系统之安装Ward服务器监控工具
68 5
Linux系统之安装Ward服务器监控工具
|
2月前
|
JSON JavaScript Linux
Linux系统之安装cook菜谱工具
【10月更文挑战第15天】Linux系统之安装cook菜谱工具
45 2
Linux系统之安装cook菜谱工具
|
1月前
|
Ubuntu Linux Shell
Linux 系统中的代码类型或脚本类型内容
在 Linux 系统中,代码类型多样,包括 Shell 脚本、配置文件、网络配置、命令行工具和 Cron 定时任务。这些代码类型广泛应用于系统管理、自动化操作、网络配置和定期任务,掌握它们能显著提高系统管理和开发的效率。
|
1月前
|
缓存 监控 Linux
Linux性能分析利器:全面掌握perf工具
【10月更文挑战第18天】 在Linux系统中,性能分析是确保软件运行效率的关键步骤。`perf`工具,作为Linux内核自带的性能分析工具,为开发者提供了强大的性能监控和分析能力。本文将全面介绍`perf`工具的使用,帮助你成为性能优化的高手。
156 1
|
1月前
|
缓存 监控 Linux
掌握Linux性能分析:深入探索perf工具
【10月更文挑战第26天】
69 1
|
1月前
|
运维 监控 Shell
深入理解Linux系统下的Shell脚本编程
【10月更文挑战第24天】本文将深入浅出地介绍Linux系统中Shell脚本的基础知识和实用技巧,帮助读者从零开始学习编写Shell脚本。通过本文的学习,你将能够掌握Shell脚本的基本语法、变量使用、流程控制以及函数定义等核心概念,并学会如何将这些知识应用于实际问题解决中。文章还将展示几个实用的Shell脚本例子,以加深对知识点的理解和应用。无论你是运维人员还是软件开发者,这篇文章都将为你提供强大的Linux自动化工具。
|
26天前
|
NoSQL 编译器 C语言
C语言调试是开发中的重要技能,涵盖基本技巧如打印输出、断点调试和单步执行,以及使用GCC、GDB、Visual Studio和Eclipse CDT等工具。
C语言调试是开发中的重要技能,涵盖基本技巧如打印输出、断点调试和单步执行,以及使用GCC、GDB、Visual Studio和Eclipse CDT等工具。高级技巧包括内存检查、性能分析和符号调试。通过实践案例学习如何有效定位和解决问题,同时注意保持耐心、合理利用工具、记录过程并避免过度调试,以提高编程能力和开发效率。
42 1
|
4月前
|
NoSQL Linux C语言
Linux GDB 调试
Linux GDB 调试
69 10