gdb 使用啥机制来知道在哪里“完成”函数调用?

Posted

技术标签:

【中文标题】gdb 使用啥机制来知道在哪里“完成”函数调用?【英文标题】:What mechanism does gdb use to know where to "finish" a function call?gdb 使用什么机制来知道在哪里“完成”函数调用? 【发布时间】:2016-10-09 10:03:12 【问题描述】:

在gdb中,在函数内部调试时,我们可以使用“finish”命令运行到函数的末尾。

我的问题是:gdb 如何知道函数的结束位置,尤其是在没有调试符号匹配源代码“”的情况下?

我猜gdb在x86下寻找“leave”或者“mov %rbp, %rsp,pop %rbp”来判断它是否已经到了函数的末尾。

但问题是,

(1) 根据源代码和 ABI 结构,仍有一些额外的寄存器需要在函数调用的开始/结束时推送/弹出。

(2)需要push/pop的寄存器数量是在编译阶段决定的,恐怕这个“数字”信息不可用throw二进制可执行文件。

那么,gdb 是如何判断一个函数调用的结束在哪里,以便“finish”命令可以跳转到它呢?

谢谢!

【问题讨论】:

【参考方案1】:

gdb 不会尝试分析机器代码。相反,它展开堆栈,找到调用者的 PC,并在那里设置一个临时断点。然后它让下层运行直到断点被命中。

由于 gdb 的展开器的设计方式,它也会自动处理来自内联函数的finish(尽管因此代码中仍有一些特殊情况)。

【讨论】:

以上是关于gdb 使用啥机制来知道在哪里“完成”函数调用?的主要内容,如果未能解决你的问题,请参考以下文章

gdb 搜索核心转储内存

第一部分牛刀小试:启动GDB开始调试

gdb中的nexti和stepi有啥区别?

gdb调试程序函数名为问号,啥原因?

main函数执行以前还会执行啥代码

gdb 不显示函数调用的名称