【问题标题】:constructing call stack as shown by gdb构造调用堆栈,如 gdb 所示
【发布时间】:2012-10-27 10:06:25
【问题描述】:

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

【问题讨论】:

    标签: operating-system gdb


    【解决方案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 使用的过程。

    有很多实际的复杂情况,比如不使用帧指针的帧,但你不会理解的:-)

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-11-04
        • 2011-04-21
        • 2012-04-06
        • 1970-01-01
        • 2015-11-07
        • 1970-01-01
        • 1970-01-01
        • 2013-04-14
        相关资源
        最近更新 更多