就程序而言,堆栈只是一堆内存。 backtrace函数如何确定哪些堆栈字节是指令指针的返回地址,而不是那些仅是函数参数的地址,等等?
答案 0 :(得分:2)
就程序而言,堆栈只是一堆内存。
是正确的。如果您对程序的结构一无所知,您将无法解开其堆栈。
最简单的展开结构是保留一个“帧指针”寄存器以始终指向当前帧,并且该帧在已知偏移量处包含 previous 帧指针。 / p>
这是在i*86
上使用了很长时间的机制,现在仍然在许多RISC计算机上使用。它使堆栈退卷变得容易且非常快速,但是在缺乏寄存器的机器(例如i*x86
以及较低程度的x86_64
)上效率不高,因为可以在其他地方更好地使用该帧寄存器。 / p>
解决方案是创建扩充数据,该数据描述如何在给定当前寄存器和存储器内容集的情况下查找当前帧(例如“当前帧与$rsp
的偏移量为NN”) ,或“距$rbp
偏移MM”,“先前帧距当前帧偏移J”等)
实际上就是.eh_frame
。从二进制文件中删除它,将无法展开堆栈。
此机制也比简单的帧指针遍历慢得多,需要复杂的代码,并且容易出错(不保证编译器会发出正确的展开描述符,并且手工编码的汇编程序可能根本没有它们)。 / p>
有other solutions可以使撤消快速而轻松,但是它们需要不同的调用约定。