您的位置:首页 > 其它

学习GDB(二)

2016-03-12 00:00 197 查看
摘要: 通过《软件调试艺术》一书,学习GDB

二、检查和设置变量

1、变量的高级检查和设置

输出一个结构体中三个变量的值:

[code=plain](gdb)p tmp->val
$1 = 12
(gdb)p tmp->left
$2 = (struct node *)0x8049098
(gdb)p tmp->right
$3 = (struct node *)0x0

键入3个print命令很费力,代替来做相同事情的方法:

-第一个改进:输出完整结构

[code=plain](gdb)p *tmp
$4 = {val = 12,left = 0x8049098,right = 0x0}

tmp指向一个结构,那么*tmp就是这个结构本身,GDB向我们显示了完整的内容。

-第二个改进:使用GDB的display命令

这个命令要求GDB在执行中每次有暂停(由于有断点,使用next或step命令等)时就输出指定条目。

-第三个改进:使用GDB的commands命令

-第四个改进:使用GDB的call命令

[code=plain](gdb) commands 1
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>printf "***********current tree************"
>call printttree(root)
>end

可以动态地修改给定断点的指令集,或者通过简单地重新定义一个空集合来取消命令集。

[code=plain](gdb) commands 1
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>end

2、检查动态数组

2.1 GDB中输出数组

如数组:int x[25]; 输出整个数组是:

[code=plain](gdb)p x

2.2 GDB输出动态数组

GDB中可以通过创建一个人工数组(artifical array)来解决这个问题。

[code=plain]#include <stdio.h>
#include <stdlib.h>

int *x ;

int main()
{
x = (int*)malloc(25*sizeof(int));
x[3] = 12;
return 0;
}

可以如下执行:

[code=plain](gdb) b 4
Breakpoint 1 at 0x8048426: file test.c, line 4.
(gdb) r
Starting program: /home/mimiasd/mimiasd2/test

Breakpoint 1, main () at test.c:8
8      x = (int*)malloc(25*sizeof(int));
(gdb) n
9      x[3] = 12;
(gdb) n
10      return 0;
(gdb) p *x@25
$1 = {0, 0, 0, 12, 0 <repeats 21 times>}

可以看到一般格式为:*point@number_of_elements ;

GDB还可以使用适当的强制类型转换,如:

[code=plain](gdb) p (int [25])*x
$2 = {0, 0, 0, 12, 0 <repeats 21 times>}

-ptype ;方便快速浏览了类或结构(struct)的结构(structure)。

3、监视局部变量

-info locals ;得将到当前栈帧中的所有局部变量的值列表

-p/x var ;以十六进制格式显示变量var。默认是十进制。/c用字符显示,/s用字符串,/f用浮点数。

-info disp ;列出dispaly条目。

-dis disp display_list_number
7fe0
;临时禁止显示列表中的条目display_list_number;

-enable disp display_list_number ;重启条目。

-undisp display_list_number ;完全删除显示的条目。

4、GDB中设置变量

-set var = variable ; 把变量var设置为variable。

-info args ;检查当前函数参数。设置这些参数如下:

[code=plain](gdb)set args 1 2 3 4 ...;

5 、GDB自己的变量

GDB的print命令输出值被标记为$1,$2等,这些值被统称为值历史。将来执行print时使用这些值历史会比较方便:

[code=plain](gdb) p/f x
$6 = 3.99292288e-34
(gdb) p $6
$7 = (int *) 0x804b008

如果没有进行方便输出,则可以使用特殊历史变量$:

[code=plain](gdb) p $6
$7 = (int *) 0x804b008
(gdb) p $
$8 = (int *) 0x804b006

6、方便变量

GDB中可以设置根据规则的改变量,称作方便量(convenience variable)。如下:

[code=plain](gdb)set $q = p

从那时起执行的命令如下:

[code=plain](gdb)p *$q

这里的变量$q就是方便变量。例如下面代码:

[code=plain]#include <stdio.h>
#include <stdlib.h>

int x[4] = {1,2,3,4};
int main()
{
x[2] = 88;
return 0;
}

在GDB中可能做一些类似如下所示的事情:

[code=plain](gdb) b 4
Breakpoint 1 at 0x80483f0: file test1.c, line 4.
(gdb) r
Starting program: /home/mimiasd/mimiasd2/test1

Breakpoint 1, main () at test1.c:7
7      x[2] = 88;
(gdb) n
8      return 0;
(gdb) set $i = 0
(gdb) p x[$i++]
$1 = 1
(gdb)
$2 = 2
(gdb)
$3 = 88
(gdb)
$4 = 4

可以看出方便变量$i在不断的增加。方便变量不能为$1,$2这种值历史保留的名称,如果是汇编语言也不能使用寄存器名称。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: