考虑一下:
[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)中打印,而调试器在其他位置停止?
答案 0 :(得分:2)
调用函数时,调用函数执行一些操作,然后发出指向被调用函数的call
指令。
然后被调用者自己做了很多样板 - 保存寄存器,移动堆栈指针为堆栈变量分配空间等等。
当你要求gdb在一个函数的开头处断开时,它会在你的实际代码开头的那个样板之后打开 - 所以函数的地址将比gdb中断点更早。
答案 1 :(得分:0)
“main
”的地址确实是0x08048368
- 设置断点的源代码行5的地址就在标准的函数启动样板之后,就在代码准备printf
的参数并调用它(以便n
执行printf
- 调用语句,例如)。