有人可以帮我理解这个: -
以下是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"是什么意思?请解释
维基百科文章Call stack中的这个图表可能有所帮助:
GDB info frame对应于在运行时在程序中调用的函数.从输出中,我们可以推断出有关堆栈框架布局的信息:
base::func()call前一帧中的指令推送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是返回地址.如果你尝试查找包含该功能0x804869a用info 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设置为帧指针.