gdb调试整数打印信息

时间:2013-12-20 22:31:17

标签: c debugging gdb disassembly

我试图找出如何打印整数值(我看到它是x / d),但我遗漏了一些东西。

所以,我的代码是以下

 1  #include <stdio.h>
 2  main(){
 3    int a;
 4    int b;
 5    int c;
 6    int d;
 7    int multiplied;
 8    a = 5;
 9    b = 6;
10    c = 7;
11    d = adding(a,b,c);
12    multiplied = multiply(a,b,c);
13    printf("The value of d is %d \n",d);
14    printf("The multiplied values are %d \n", multiplied);
15  }
16  int adding(a,b,c){
17    int e;
18    e = a+b+c;
19    return e;
20  }
21  int multiply(a,b,c){
22    int f = a*b*c;
23    return f;
24  }

//我用-q编译,我想打印变量的值(来自他们的地址)所以......

(gdb) disassemble main
0x080483ed <+9>:    mov    DWORD PTR [esp+0x2c],0x5
0x080483f5 <+17>:   mov    DWORD PTR [esp+0x28],0x6
0x080483fd <+25>:   mov    DWORD PTR [esp+0x24],0x7
0x08048405 <+33>:   mov    eax,DWORD PTR [esp+0x24] <code>

我在main / multiply / adds中添加了一些断点,然后我尝试执行以下操作。

我用过 print $esp+0x24  和 (gdb) x/4d 0xbffff47c但我没有得到正确答案。

我使用4d是因为我认为整数是4个字节(或者可能再次缺少某些东西),但结果不显示值5。 你能帮我么?谢谢,抱歉gdb的输出/格式不好..严重我不明白什么是错的

(gdb) print $esp+0x2c
$2 = (void *) 0xbffff494
(gdb) print $esp+0x28
$3 = (void *) 0xbffff490
(gdb) print $esp+0x24
$4 = (void *) 0xbffff48c
(gdb) x/d 0xbffff494
0xbffff494: -1208180748
(gdb) x/d 0xbffff490
0xbffff490: -1208179932
(gdb) x/d 0xbffff48c
0xbffff48c: 134513881

此次发生在main的第一个断点之后,实际上相同的值一直在所有断点中出现(除了main之前的那个...)

我发现的另一个有趣的事情是以下......我确信第一个值是垃圾。但是为什么它应该在打印实际值时将0x5视为地址?

Breakpoint 1, main () at functioncalling.c:10
10  a = 5;
(gdb) x/s a
0xb7fc9ff4: "|M\025"
(gdb) cont
Continuing.
Breakpoint 3, adding (a=5, b=6, c=7) at functioncalling.c:21
21  e = a+b+c;
(gdb) x/s a
0x5:    <Address 0x5 out of bounds>

1 个答案:

答案 0 :(得分:1)

我用-g编译你的程序而没有优化,并在第11行之前设置了一个断点。我的堆栈地址与你的有点不同,考虑到各种各样的系统,这并不奇怪。

(gdb) print $esp+0x2c
$2 = (void *) 0xbffff44c

这是打印a的地址。确认:

(gdb) print &a
$4 = (int *) 0xbffff44c

使用x/wd显示十进制的4字节整数。

(gdb) x/wd $esp+0x2c
0xbffff44c: 5

x/4d将显示从地址开始的4个值(4是重复计数)。如果在此省略大小字母w,则x命令将默认为先前使用的大小。

(gdb) x/4d $esp+0x2c
0xbffff44c: 5   134513856   0   -1073744680

有你的5.至于其他3个数字,它们是堆栈中的东西。

(gdb) x/4a $esp+0x2c
0xbffff44c: 0x5 0x80484c0 <__libc_csu_init> 0x0 0xbffff4d8

你的下一个问题:

  

我发现的另一个有趣的事情是以下......我确信第一个值是垃圾。但是为什么它应该在打印实际值时将0x5视为地址?

Breakpoint 3, adding (a=5, b=6, c=7) at functioncalling.c:21
21  e = a+b+c;
(gdb) x/s a
0x5:    <Address 0x5 out of bounds>

x命令,当程序的变量作为其参数时,检索其值并将其用作地址。 x/s a表示检索a中的值并将其用作NUL终止字符串的起始地址。如果a类型为char *且包含合适的值,则x/s将打印合理的输出。要打印a的实际值,请为x命令指定参数&a

(gdb) x/wd &a
0xbffff44c: 5

这似乎违反直觉。只需考虑x命令就像C语句printf(fmt, *(argument))那样操作。 x命令的参数几乎总是一个文字内存地址或涉及堆栈指针,基址指针或pc寄存器的地址表达式。