解决问题!

时间:2010-07-01 04:32:19

标签: c++ c

考虑一下:

[mdstest:~/onkar/test]$cat test.c
#include<stdio.h>

int main(int argc,char **argv)
{
        printf("%p\n",main);
        return 0;
}
[mdstest:~/onkar/test]$make
gcc -g -Wall -o test test.c
[mdstest:~/onkar/test]$./test
0x8048368 ------------------------------------- (1) 
[mdstest:~/onkar/test]$gdb test
:::::::::::
:::::::::::
(gdb) b main
Breakpoint 1 at 0x8048384: file test.c, line 5.
(gdb) r
Starting program: /home/mdstest/onkar/test/test
[Thread debugging using libthread_db enabled]

Breakpoint 1, main (argc=1, argv=0xbffff2d4) at test.c:5
5               printf("%p\n",main);
(gdb) disassemble
Dump of assembler code for function main:
   0x08048368 <+0>:     push   %ebp
   0x08048369 <+1>:     mov    %esp,%ebp
   0x0804836b <+3>:     sub    $0x8,%esp
   0x0804836e <+6>:     and    $0xfffffff0,%esp
   0x08048371 <+9>:     mov    $0x0,%eax
   0x08048376 <+14>:    add    $0xf,%eax
   0x08048379 <+17>:    add    $0xf,%eax
   0x0804837c <+20>:    shr    $0x4,%eax
   0x0804837f <+23>:    shl    $0x4,%eax
   0x08048382 <+26>:    sub    %eax,%esp
=> 0x08048384 <+28>:    sub    $0x8,%esp -----------------------------(2) 
   0x08048387 <+31>:    push   $0x8048368
   0x0804838c <+36>:    push   $0x8048480
   0x08048391 <+41>:    call   0x80482b0 <printf@plt>
   0x08048396 <+46>:    add    $0x10,%esp
   0x08048399 <+49>:    mov    $0x0,%eax
   0x0804839e <+54>:    leave
   0x0804839f <+55>:    ret
End of assembler dump.

为什么(1)和(2)地址不同?那就是为什么其他一些地址 在(1)中打印,而调试器在其他位置停止?

2 个答案:

答案 0 :(得分:2)

调用函数时,调用函数执行一些操作,然后发出指向被调用函数的call指令。

然后被调用者自己做了很多样板 - 保存寄存器,移动堆栈指针为堆栈变量分配空间等等。

当你要求gdb在一个函数的开头处断开时,它会在你的实际代码开头的那个样板之后打开 - 所以函数的地址将比gdb中断点更早。

答案 1 :(得分:0)

main”的地址确实是0x08048368 - 设置断点的源代码行5的地址就在标准的函数启动样板之后,就在代码准备printf的参数并调用它(以便n执行printf - 调用语句,例如)。