GDB +核心文件转储

时间:2011-03-01 04:33:57

标签: gdb

有些人可以帮助我理解这一点: -

以下是gdb的摘录。我的程序崩溃后,我在gdb中打开了二进制和核心文件并发出了命令info frame

(gdb) info frame
Stack level 0, frame at 0xb75f7390:
 eip = 0x804877f in base::func() (testing.cpp:16); saved eip 0x804869a
 called by frame at 0xb75f73b0
 source language c++.
 Arglist at 0xb75f7388, args: this=0x0
 Locals at 0xb75f7388, Previous frame's sp is 0xb75f7390
 Saved registers:
  ebp at 0xb75f7388, eip at 0xb75f738c

“ebp”,“eip”,“Locals at”和“Previous Frame's sp”是什么意思?请解释

2 个答案:

答案 0 :(得分:5)

维基百科文章Call stack中的这个图表可能有所帮助:Stack frame layout

GDB的info frame对应于运行时程序中调用的函数。从输出中,我们可以推断出有关堆栈帧布局的信息:

  • 0xb75f7388 :此处开始的4个字节存储旧的 EBP 值, 0xb75f73a8 。由base::func()
  • 的函数序言推送的第一个值
  • 0xb75f738c :此处开始的4个字节存储返回地址 0x804869a 。由前一帧中的call指令推送
  • 0xb75f7390 :此处开始的4个字节将隐式this参数存储到base::func() 0x00000000

我将逐行解释info frame输出:

Stack level 0, frame at 0xb75f7390:

堆栈级别0表示这是最新帧。 frame at之后的地址称为规范帧地址(CFA)。在x86上,这被定义为在执行调用指令之前的前一帧的堆栈指针( ESP )的值。

 eip = 0x804877f in base::func() (testing.cpp:16); saved eip 0x804869a

EIP 是x86指令指针。 saved eip是返回地址。 如果您尝试使用info symbol 0x804869a查找包含 0x804869a 的函数,则应该指向调用base::func()的函数内部。

 called by frame at 0xb75f73b0

called by显示前一帧的规范帧地址。我们可以看到堆栈指针在两帧之间前进了32个字节(0xb75f73b0 - 0xb75f7390 = 32)。

 source language c++.

 Arglist at 0xb75f7388, args: this=0x0
 Locals at 0xb75f7388, Previous frame's sp is 0xb75f7390

x86 ABI在堆栈上传递参数。 base::func()只有一个隐式this参数。事实是0x0NULL预示着不适。在旁注中,ArglistLocals似乎在x86和x86-64上的info frame中始终具有相同的值。

 Saved registers:
  ebp at 0xb75f7388, eip at 0xb75f738c

Saved registers反映了在函数入口处保存的寄存器。它列出了旧寄存器值在堆栈中保存的位置。已保存的 EIP 是返回地址,因此,如果您使用x/a 0xb75f738c检查存储在 0xb75f738c 的地址,则应该提供 0x804869a 。此处列出 EBP 的事实意味着您的代码可能未使用-fomit-frame-pointer编译并具有标准函数序言:

push %ebp
movl %esp, %ebp

base::func()的乞讨时,设置 EBP 作为帧指针。

答案 1 :(得分:0)

要分析核心文件,请执行:

$ gdb可执行核心

gdb $ bt - backtrace

或gdb $ fr 0 - 运行时堆栈中最上面的帧    gdb $ fr 1&这样就会给你函数调用的顺序,这导致了Seg Fault。

这里,gdb $ info框架为您提供有关第0帧的信息。