Operating system 如gdb所示构造调用堆栈
我想了解如何像gdb在运行backtrace命令时那样构建调用堆栈。这是在一次采访中被问到的,我根据自己对调用堆栈和堆栈框架的了解回答了这个问题。我认为这是通过使用堆栈指针、调用方的返回地址/指令并将其映射到可执行/汇编指令来实现的。我一直在寻找它实际上是如何完成的,或者对这个堆栈行走的一个很好的解释。我在谷歌上找到的所有信息都与微软API有关,我正在寻找一个关于如何构建调用堆栈的通用解释 我不知道它在gdb中是如何实现的,但有一个想法,如果你能将所有Operating system 如gdb所示构造调用堆栈,operating-system,gdb,Operating System,Gdb,我想了解如何像gdb在运行backtrace命令时那样构建调用堆栈。这是在一次采访中被问到的,我根据自己对调用堆栈和堆栈框架的了解回答了这个问题。我认为这是通过使用堆栈指针、调用方的返回地址/指令并将其映射到可执行/汇编指令来实现的。我一直在寻找它实际上是如何完成的,或者对这个堆栈行走的一个很好的解释。我在谷歌上找到的所有信息都与微软API有关,我正在寻找一个关于如何构建调用堆栈的通用解释 我不知道它在gdb中是如何实现的,但有一个想法,如果你能将所有jmp/call指令及其目标地址保存在一个堆
jmp/call
指令及其目标地址保存在一个堆栈中,那么在任何时候你都会有一个完整的调用跟踪。我不知道它在gdb中是如何实现的,但有一个想法,如果你能把所有的jmp/call
指令和它们的目标地址放在一个堆栈中,那么在任何时候你都会有一个完整的调用跟踪
考虑使用帧指针的非常简单的ix86
调用约定。每次调用例程时,下一条指令的地址都会被推送到堆栈上。被调用的例程在进入时立即执行push%ebp;mov%esp,%ebp
说明。然后,您完全可以使用上面页面中的布局
假设您在例程foo
中停止,从bar
调用,从baz
调用,从main
调用
您检查了由%ebp
指向的两个单词。第一个字是%ebp
的前一个值(我们称之为prev\u ebp
),第二个字是返回地址--条内某处的指令指针
现在检查prev\u ebp
指向的两个单词。第一个单词是prev\u ebp
,第二个单词是返回地址--baz
内某处的指令指针
重复此步骤,直到到达main,并且大致执行了GDB使用的过程
有许多实际的复杂情况,例如不使用帧指针的帧,但您不应该理解:-)谷歌搜索引导了我
考虑使用帧指针的非常简单的ix86
调用约定。每次调用例程时,下一条指令的地址都会被推送到堆栈上。被调用的例程在进入时立即执行push%ebp;mov%esp,%ebp
说明。然后,您完全可以使用上面页面中的布局
假设您在例程foo
中停止,从bar
调用,从baz
调用,从main
调用
您检查了由%ebp
指向的两个单词。第一个字是%ebp
的前一个值(我们称之为prev\u ebp
),第二个字是返回地址--条内某处的指令指针
现在检查prev\u ebp
指向的两个单词。第一个单词是prev\u ebp
,第二个单词是返回地址--baz
内某处的指令指针
重复此步骤,直到到达main,并且大致执行了GDB使用的过程
有许多实际的复杂情况,例如不使用帧指针的帧,但您不需要理解:-)