构造调用堆栈,如gdb所示

时间:2012-10-27 10:06:25

标签: operating-system gdb

我想了解如何构建一个调用堆栈,就像gdb在运行backtrace命令时所做的那样。这是在一次采访中被问到的,我根据我对调用堆栈和堆栈框架的了解来回答这个问题。我认为这是使用堆栈指针,调用者的返回地址/指令并将其映射到可执行/汇编指令来完成的。我一直在寻找它是如何实际完成的,或者是对这个堆栈步行的一个很好的解释。我在google搜索中找到的所有信息都与微软API以编程方式相关,我正在寻找如何构建调用堆栈的通用解释。

2 个答案:

答案 0 :(得分:1)

谷歌搜索引导我here

考虑使用帧指针的非常简单的ix86调用约定。每次调用例程时,下一条指令的地址都会被压入堆栈。在进入后立即调用例程执行push %ebp; mov %esp,%ebp指令。然后,您将完全按照上面的页面布局。

假设您从常规foo停止,从bar调用,从baz调用,从main调用。

您检查%ebp指向的两个单词。第一个单词是%ebp的前一个值(我们称之为prev_ebp,第二个是返回地址 - 指令指针bar内的某个位置。

您现在检查prev_ebp指向的两个单词。第一个是prev_prev_ebp,第二个是返回地址 - 指令指针在baz内的某处。

重复直到你到达main,你已经大致执行了GDB使用的程序。

有许多实际的复杂情况,例如不使用帧指针的帧,但您不应该理解: - )

答案 1 :(得分:0)

我不知道它是如何在gdb中完成的,但是这里有一个想法,如果你可以将所有jmp/call指令及其目标地址保存在一个堆栈中,那么在任何时候你都会有一个完整的调用跟踪