【Linux调试技术】查看数据

简介: 作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ 本文首先以一个二叉树插入算法的实现作为例子说明GDB查看程序数据的相关方法,代码如下:   1: //  bintree.

作者:gnuhpc
出处:http://www.cnblogs.com/gnuhpc/

本文首先以一个二叉树插入算法的实现作为例子说明GDB查看程序数据的相关方法,代码如下:

  1: //  bintree.c:  routines to do insert and sorted print of a binary tree

 

  2:

 

  3: #include

 

  4: #include

 

  5:

 

  6: struct node {

 

  7:    int val;             // stored value

 

  8:    struct node *left;   // ptr to smaller child

 

  9:    struct node *right;  // ptr to larger child

 

 10: };

 

 11:

 

 12: typedef struct node *nsp;

 

 13:

 

 14: nsp root;

 

 15:

 

 16: nsp makenode(int x)

 

 17: {

 

 18:    nsp tmp; 

 

 19:

 

 20:    tmp = (nsp) malloc(sizeof(struct node)); 

 

 21:    tmp->val = x; 

 

 22:    tmp->left = tmp->right = 0;

 

 23:    return tmp;

 

 24: }

 

 25:

 

 26: void insert(nsp *btp, int x)

 

 27: {

 

 28:    nsp tmp = *btp;

 

 29:

 

 30:    if (*btp == 0) {

 

 31:       *btp = makenode(x);

 

 32:       return;

 

 33:    }

 

 34:

 

 35:    while (1)

 

 36:    {

 

 37:       if (x < tmp->val) {

 

 38:

 

 39:          if (tmp->left != 0) {

 

 40:             tmp = tmp->left;

 

 41:          } else {

 

 42:             tmp->left = makenode(x);

 

 43:             break;

 

 44:          }

 

 45:

 

 46:       } else {

 

 47:

 

 48:          if (tmp->right != 0) {

 

 49:             tmp = tmp->right;

 

 50:          } else {

 

 51:             tmp->right = makenode(x);

 

 52:             break;

 

 53:          }

 

 54:

 

 55:       }

 

 56:    }

 

 57: }

 

 58:

 

 59:

 

 60: void printtree(nsp bt)

 

 61: {

 

 62:    if (bt == 0) return;

 

 63:    printtree(bt->left);

 

 64:    printf("%d/n",bt->val);

 

 65:    printtree(bt->right);

 

 66: }

 

 67:

 

 68:

 

 69: int main(int argc, char *argv[])

 

 70: {

 

 71:    root = 0;

 

 72:    for (int i = 1; i < argc; i++)

 

 73:       insert(&root, atoi(argv[i]));

 

 74:    printtree(root);

 

 75: }

 

在调试这个二叉树插入程序的时候,我们会非常关心insert方法的执行情况,在进入那个while(1)循环后,我们可能会做以下的操作:

(gdb) p tmp->val
$1=12
(gdb) p tmp->left
$2 = (struct node *) 0x8049698
(gdb) p tmp->right
$3 = (struct node *) 0x0

这个操作显得累赘又麻烦,我们可以有以下的改进措施:

1.直接打印结构体tmp

(gdb) p *tmp
$4 = {val = 12, left = 0x8049698, right = 0x0}

2.使用display命令:我们在#37设置断点,然后运行程序,待程序运行至该断点停下后使用display = disp 命令对某一个变量进行监视(之所以这样做是因为这个变量必须存在在该栈帧上,也就是说调试的时候这个变量的确被创建并且没有被销毁),程序以后只要一停止就打印这个变量的值在屏幕上:

(gdb) disp *tmp
1: *tmp = {val = 12, left = 0x8049698, right = 0x0}
(gdb) c
Continuing.
Breakpoint 1, insert (btp=0x804967c, x=5) at bintree.c:37
37 if (x < tmp->val) {
1: *tmp = {val = 8, left = 0x0, right = 0x0}

也可以使用dis disp 1使这个监视动作失效(enable disp 1则恢复),undisp 1为删除。info display为查看当前所有自动打印点相关的信息

3.使用命令列表:在上篇中已经叙述,在此不再赘述。

4.使用call命令:我们在代码中已经有了一个打印整个树的函数printtree,使用call命令我们可以直接利用代码中的方法进行变量监视,在每次insert完成的时候调用printtree对二叉树进行打印:

(gdb) commands 2
Type commands for when breakpoint 2 is hit, one per line.
End with a line saying just "end".
>printf "*********** current tree ***********"
>call printtree(root)
>end

5.使用DDDData Window图形化表示:单击右键在root这个变量上然后选择display *root,每次在#37行停下时,在Data Window内对整个树的都有图形化表示,在左右子树上,你可以使用右键单击然后选择Display *()来显示。(Tips:你可以以--separate参数启动DDD,这样每个Window都是独立的,你可以获得更大的视野)。

补充:

1.打印数组:p *pointer@number_of_elements,其中number_of_elements表示显示pointer这个变量中的几个成员。另外一种方式是类型转换,例如下列程序:

  1: int *x;

 

  2: main()

 

  3: {

 

  4:    x = (int *) malloc(25*sizeof(int));

 

  5:    x[3] = 12;

 

  6: }

 

除了可以使用:

(gdb) p *x@25
$1 = {0, 0, 0, 12, 0 }

我们还可以使用:

(gdb) p (int [25]) *x
$2 = {0, 0, 0, 12, 0 }

2.打印本地变量info locals,会打印当前栈帧的本地变量。

3.以不同形式打印变量p/paramenters variable  parameters 可以是 x 表示打印变量以十六进制表示,f为浮点,ccharactersstring

4.打印历史查看过的变量:使用$number,而只使用$表示上一个变量。

(gdb) p tmp->left
$1 = (struct node *) 0x80496a8
(gdb) p *(tmp->left)
$2 = {val = 5, left = 0x0, right = 0x0}
(gdb) p *$1
$3 = {val = 5, left = 0x0, right = 0x0}

(gdb) p tmp->left
$1 = (struct node *) 0x80496a8
(gdb) p *$
$2 = {val = 5, left = 0x0, right = 0x0}

5.修改被调试程序运行时的变量值set x = 12

6.利用自定义变量方便调试:例如,

  1: int w[4] = {12,5,8,29};

 

  2: main()

 

  3: {

 

  4:    w[2] = 88;

 

  5: }

 

我们设置i,然后利用这个变量对这个数组进行遍历:

(gdb) set $i = 0
(gdb) p w[$i++]
$1=12
(gdb)
$2=5
(gdb)
$3=88
(gdb)
$4=29

7.强制类型打印

p {type}address:address指定的内存解释为type类型(类似于强制转型,更加强)

8.设置一些常见选项

·        1) set print array:打开数组显示,打开后当数组显示时,每个元素占一行,如果不打开的话,每个元素则以逗号分隔。默认关闭

·        2) set print elements num-of-elements:设置GDB打印数据时显示元素的个数,缺省为200,设为0表示不限制(unlimited)

·        3) set print null-stop:设置GDB打印字符数组的时候,遇到NULL时停止,缺省是关闭的

·        4) set print pretty:设置GDB打印结构的时候,每行一个成员,并且有相应的缩进,缺省是关闭的

·        5) set print object:设置GDB打印多态类型的时候,打印实际的类型,缺省为关闭

·        6) set print static-members:设置GDB打印结构的时候,是否打印static成员,缺省是打开的

·        7) set print vtblGDB将用比较规整的格式来显示虚函数表,缺省是关闭的

参考文献:
Art of Debugging

Linux® Debugging and Performance Tuning: Tips and Techniques

 

作者:gnuhpc
出处:http://www.cnblogs.com/gnuhpc/


               作者:gnuhpc
               出处:http://www.cnblogs.com/gnuhpc/
               除非另有声明,本网站采用知识共享“署名 2.5 中国大陆”许可协议授权。


分享到:

相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
目录
相关文章
|
8月前
|
Linux
在线对Linux进行磁盘扩容的技术指南。
综上所述,Linux磁盘扩容的过程,重要的不仅是技术,更是对每一步骤的深刻理解和投入的爱心。只要手握正确的工具,我们不仅能满足"孩子"的成长需求,还能享受其中的乐趣和成就。
524 10
|
9月前
|
关系型数据库 MySQL Linux
在Linux环境下备份Docker中的MySQL数据并传输到其他服务器以实现数据级别的容灾
以上就是在Linux环境下备份Docker中的MySQL数据并传输到其他服务器以实现数据级别的容灾的步骤。这个过程就像是一场接力赛,数据从MySQL数据库中接力棒一样传递到备份文件,再从备份文件传递到其他服务器,最后再传递回MySQL数据库。这样,即使在灾难发生时,我们也可以快速恢复数据,保证业务的正常运行。
443 28
|
缓存 NoSQL Linux
Linux调试
本文介绍了Linux调试、性能分析和追踪的培训资料,涵盖调试、性能分析和追踪的基础知识及常用工具。
916 63
Linux调试
|
10月前
|
监控 Shell Linux
Android调试终极指南:ADB安装+多设备连接+ANR日志抓取全流程解析,覆盖环境变量配置/多设备调试/ANR日志分析全流程,附Win/Mac/Linux三平台解决方案
ADB(Android Debug Bridge)是安卓开发中的重要工具,用于连接电脑与安卓设备,实现文件传输、应用管理、日志抓取等功能。本文介绍了 ADB 的基本概念、安装配置及常用命令。包括:1) 基本命令如 `adb version` 和 `adb devices`;2) 权限操作如 `adb root` 和 `adb shell`;3) APK 操作如安装、卸载应用;4) 文件传输如 `adb push` 和 `adb pull`;5) 日志记录如 `adb logcat`;6) 系统信息获取如屏幕截图和录屏。通过这些功能,用户可高效调试和管理安卓设备。
|
安全 大数据 Linux
云上体验最佳的服务器操作系统 - Alibaba Cloud Linux | 飞天技术沙龙-CentOS 迁移替换专场
本次方案的主题是云上体验最佳的服务器操作系统 - Alibaba Cloud Linux ,从 Alibaba Cloud Linux 的产生背景、产品优势以及云上用户使用它享受的技术红利等方面详细进行了介绍。同时,通过国内某社交平台、某快递企业、某手机客户大数据业务 3 大案例,成功助力客户实现弹性扩容能力提升、性能提升、降本增效。 1. 背景介绍 2. 产品介绍 3. 案例分享
311 1
|
安全 Linux KVM
Linux虚拟化技术:从Xen到KVM
Xen和KVM是Linux平台上两种主要的虚拟化技术,各有优缺点和适用场景。通过对比两者的架构、性能、安全性、管理复杂性和硬件依赖性,可以更好地理解它们的适用场景和选择依据。无论是高性能计算、企业虚拟化还是云计算平台,合理选择和配置虚拟化技术是实现高效、稳定和安全IT环境的关键。
787 8
|
运维 监控 Linux
BPF及Linux性能调试探索初探
BPF技术从最初的网络数据包过滤发展为强大的系统性能优化工具,无需修改内核代码即可实现实时监控、动态调整和精确分析。本文深入探讨BPF在Linux性能调试中的应用,介绍bpftune和BPF-tools等工具,并通过具体案例展示其优化效果。
590 14
|
存储 NoSQL Linux
linux之core文件如何查看和调试
通过设置和生成 core 文件,可以在程序崩溃时获取详细的调试信息。结合 GDB 等调试工具,可以深入分析 core 文件,找到程序崩溃的具体原因,并进行相应的修复。掌握这些调试技巧,对于提高程序的稳定性和可靠性具有重要意义。
6288 6
|
弹性计算 Linux 数据库
阿里云国际版如何迁移Linux云服务器系统盘中的数据
阿里云国际版如何迁移Linux云服务器系统盘中的数据
|
Linux 虚拟化
Vmware 傻瓜式安装(不可不知道的Linux基础知识和技术 01)
本文介绍了VMware虚拟机的下载与安装步骤。首先,通过提供的网盘链接下载VMware安装包。接着,详细描述了安装流程,包括接受协议、选择安装路径(建议避免系统C盘)、取消更新选项等。最后,输入许可证密钥完成安装,并展示了打开虚拟机后的主界面。整个过程简单易懂,适合新手操作。
450 1