打印函數堆棧幀信息
例子
#include <stdio.h>
int func(int a, int b)
{
int c = a * b;
printf("c is %d\n", c);
}
int main(void)
{
func(1, 2);
return 0;
}
技巧
使用gdb調試程序時,可以使用“i frame
”命令(i
是info
命令縮寫)顯示函數堆棧幀信息。以上面程序為例:
Breakpoint 1, func (a=1, b=2) at a.c:5
5 printf("c is %d\n", c);
(gdb) i frame
Stack level 0, frame at 0x7fffffffe590:
rip = 0x40054e in func (a.c:5); saved rip = 0x400577
called by frame at 0x7fffffffe5a0
source language c.
Arglist at 0x7fffffffe580, args: a=1, b=2
Locals at 0x7fffffffe580, Previous frame's sp is 0x7fffffffe590
Saved registers:
rbp at 0x7fffffffe580, rip at 0x7fffffffe588
(gdb) i registers
rax 0x2 2
rbx 0x0 0
rcx 0x0 0
rdx 0x7fffffffe688 140737488348808
rsi 0x2 2
rdi 0x1 1
rbp 0x7fffffffe580 0x7fffffffe580
rsp 0x7fffffffe560 0x7fffffffe560
r8 0x7ffff7dd4e80 140737351863936
r9 0x7ffff7dea560 140737351951712
r10 0x7fffffffe420 140737488348192
r11 0x7ffff7a35dd0 140737348066768
r12 0x400440 4195392
r13 0x7fffffffe670 140737488348784
r14 0x0 0
r15 0x0 0
rip 0x40054e 0x40054e <func+24>
eflags 0x202 [ IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(gdb) disassemble func
Dump of assembler code for function func:
0x0000000000400536 <+0>: push %rbp
0x0000000000400537 <+1>: mov %rsp,%rbp
0x000000000040053a <+4>: sub $0x20,%rsp
0x000000000040053e <+8>: mov %edi,-0x14(%rbp)
0x0000000000400541 <+11>: mov %esi,-0x18(%rbp)
0x0000000000400544 <+14>: mov -0x14(%rbp),%eax
0x0000000000400547 <+17>: imul -0x18(%rbp),%eax
0x000000000040054b <+21>: mov %eax,-0x4(%rbp)
=> 0x000000000040054e <+24>: mov -0x4(%rbp),%eax
0x0000000000400551 <+27>: mov %eax,%esi
0x0000000000400553 <+29>: mov $0x400604,%edi
0x0000000000400558 <+34>: mov $0x0,%eax
0x000000000040055d <+39>: callq 0x400410 <printf@plt>
0x0000000000400562 <+44>: leaveq
0x0000000000400563 <+45>: retq
End of assembler dump.
可以看到執行“i frame
”命令後,輸出了當前函數堆棧幀的地址,指令寄存器的值,局部變量地址及值等信息,可以對照當前寄存器的值和函數的彙編指令看一下。
參見gdb手冊.
貢獻者
nanxiao