GDB +核心文件转储

Dew*_*Dew 2 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
Run Code Online (Sandbox Code Playgroud)

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

sco*_*ttt 5

维基百科文章Call stack中的这个图表可能有所帮助:堆栈框架布局

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

  • 0xb75f7388:此处开始的4个字节存储旧的EBP0xb75f73a8.函数序言推送的第一个值base::func()
  • 0xb75f738c:此处开始的4个字节存储返回地址0x804869a.按call前一帧中的指令推送
  • 0xb75f7390:4个字节开始在这里存储的隐含this参数base::func(),00000000.

我将info frame逐行解释输出:

Stack level 0, frame at 0xb75f7390:
Run Code Online (Sandbox Code Playgroud)

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

 eip = 0x804877f in base::func() (testing.cpp:16); saved eip 0x804869a
Run Code Online (Sandbox Code Playgroud)

EIP是x86指令指针.saved eip是返回地址.如果你尝试查找包含该功能0x804869ainfo symbol 0x804869a,它应该指向的函数调用里面base::func().

 called by frame at 0xb75f73b0
Run Code Online (Sandbox Code Playgroud)

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

 source language c++.

 Arglist at 0xb75f7388, args: this=0x0
 Locals at 0xb75f7388, Previous frame's sp is 0xb75f7390
Run Code Online (Sandbox Code Playgroud)

x86 ABI在堆栈上传递参数.base::func()只有一个隐含的this参数.事实上,这0x0就是NULL预示着不适.在一个侧面说明,Arglist并且Locals似乎总是在相同的值info frame在x86和x86-64.

 Saved registers:
  ebp at 0xb75f7388, eip at 0xb75f738c
Run Code Online (Sandbox Code Playgroud)

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

push %ebp
movl %esp, %ebp
Run Code Online (Sandbox Code Playgroud)

在最乞讨时base::func(),将EBP设置为帧指针.