2013-10-23 70 views

回答

3

GDB设置断点function prologue后,像以前一样设置正确的东西也不能证明像局部变量的预期状态等

歇为此套断点和开幕后第一条指令的地址打印,而打印功能中打印实际第一条指令的地址。

你可以通过执行break * 0x8048344来设置一个断点到实际的第一条指令,然后在那里和序言之后观察局部变量的值。

4

该输出可以是不正确的,这将是,如果你做了一件为:

int func(void) { 
    int a = 10; 
    printf("%d\n", a); 
    return 1; 
} 

地装入GDB后:

(gdb) p func 
$1 = {int (void)} 0x4016b0 <func> 
(gdb) b func 
Breakpoint 1 at 0x4016b6: file file.c, line 4. 
(gdb) disassemble func 
Dump of assembler code for function func: 
    0x004016b0 <+0>:  push %ebp 
    0x004016b1 <+1>:  mov %esp,%ebp 
    0x004016b3 <+3>:  sub $0x28,%esp 
    0x004016b6 <+6>:  movl $0xa,-0xc(%ebp) 
    0x004016bd <+13>: mov -0xc(%ebp),%eax 
    0x004016c0 <+16>: mov %eax,0x4(%esp) 
    0x004016c4 <+20>: movl $0x405064,(%esp) 
    0x004016cb <+27>: call 0x403678 <printf> 
    0x004016d0 <+32>: mov $0x1,%eax 
    0x004016d5 <+37>: leave 
    0x004016d6 <+38>: ret 
End of assembler dump. 
(gdb) 

这里func点的确切第一条指令在功能上,push %ebp,但是当你设置一个断点时,gdb在堆栈帧初始化指令后设置它:

0x004016b0 <+0>:  push %ebp 
    0x004016b1 <+1>:  mov %esp,%ebp 
    0x004016b3 <+3>:  sub $0x28,%esp 

在函数的指令实际开始:

=> 0x004016b6 <+6>:  movl $0xa,-0xc(%ebp) 
    0x004016bd <+13>: mov -0xc(%ebp),%eax 
    0x004016c0 <+16>: mov %eax,0x4(%esp) 
    0x004016c4 <+20>: movl $0x405064,(%esp) 
    0x004016cb <+27>: call 0x403678 <printf> 
    0x004016d0 <+32>: mov $0x1,%eax 
    0x004016d5 <+37>: leave 
    0x004016d6 <+38>: ret 

这里指令:

movl $0xa,-0xc(%ebp) ; 0xa = 10 

是这一部分:

int a = 10;