调试器如何跟踪堆栈?
How debuggers can trace the stack?
我正在尝试使用堆栈指针实现堆栈跟踪器; RSP 和 RBP,但我认为调试器使用完全不同的方式来获取 return 地址,或者我可能遗漏了一些东西。我可以抓到最后一个栈帧的return地址,但是我抓不到其他的,因为我不知道其他栈帧的大小,所以我不知道应该走多少字节从堆栈帧返回,以获取 return 地址。有谁知道调试器使用哪种方式来跟踪堆栈?
当代码使用帧指针时,可以跟踪堆栈。在这种情况下,ebp/rbp
用作帧指针,函数以 prologs 开始,以 epilogs 结束。
典型的序言如下所示:
push rbp ; save previous frame pointer
mov rbp, rsp ; initialize this functions frame pointer
典型的结语如下所示:
mov rsp, rbp ; restore the value of rsp
pop rbp ; restore previous frame pointer value from stack
retn
因此在函数中的每个地方rbp
都指向保存前一帧指针的堆栈位置,rbp+8
包含保存的return地址。
要获得调用的函数,调试器应该读取 [rbp+8]
值并找到该地址所属的函数。这可以通过搜索调试符号来完成。
接下来它应该读取 [rbp]
值以获取调用函数的帧指针。继续这个过程,直到找到顶层函数。这通常是启动线程的系统库函数。
我正在尝试使用堆栈指针实现堆栈跟踪器; RSP 和 RBP,但我认为调试器使用完全不同的方式来获取 return 地址,或者我可能遗漏了一些东西。我可以抓到最后一个栈帧的return地址,但是我抓不到其他的,因为我不知道其他栈帧的大小,所以我不知道应该走多少字节从堆栈帧返回,以获取 return 地址。有谁知道调试器使用哪种方式来跟踪堆栈?
当代码使用帧指针时,可以跟踪堆栈。在这种情况下,ebp/rbp
用作帧指针,函数以 prologs 开始,以 epilogs 结束。
典型的序言如下所示:
push rbp ; save previous frame pointer
mov rbp, rsp ; initialize this functions frame pointer
典型的结语如下所示:
mov rsp, rbp ; restore the value of rsp
pop rbp ; restore previous frame pointer value from stack
retn
因此在函数中的每个地方rbp
都指向保存前一帧指针的堆栈位置,rbp+8
包含保存的return地址。
要获得调用的函数,调试器应该读取 [rbp+8]
值并找到该地址所属的函数。这可以通过搜索调试符号来完成。
接下来它应该读取 [rbp]
值以获取调用函数的帧指针。继续这个过程,直到找到顶层函数。这通常是启动线程的系统库函数。