专做民宿的网站,深圳三合一建设网站,360浏览器免费网站,王烨当兵小说上一篇文章学习了如何使用GDB数据断点进行内存监测#xff1a;【软件开发底层知识修炼】十五 快速学习GDB调试三 使用GDB的数据断点监测变量是否改变本篇文章继续上一篇文章的学习#xff1a;如何使用GDB进行函数调用栈的查看 文章目录1 backtrace和frame2 使用GDB进行函数调… 上一篇文章学习了如何使用GDB数据断点进行内存监测【软件开发底层知识修炼】十五 快速学习GDB调试三 使用GDB的数据断点监测变量是否改变本篇文章继续上一篇文章的学习如何使用GDB进行函数调用栈的查看 文章目录1 backtrace和frame2 使用GDB进行函数调用栈的查看的实际代码案例3 总结 1 backtrace和frame
一般来说查看函数调用栈主要是为了研究函数的调用过程。
一般使用下面的命令进行查看 backtrace 查看函数的调用顺序函数调用栈的信息 frame N 切换到栈编号为N的上下文中具体栈编号是什么在下面的实际案例中会有 info frame 查看当前函数调用栈帧的信息 至于什么是栈帧信息大概就是下图的样子这里不再多介绍后面还会有文章学习函数栈帧的概念或者推荐大家去阅读程序员的自我修养。
上面有一个info frame命令我们在前几篇文章已经学习过info的几个命令。下面再介绍几个下图中的info命令 2 使用GDB进行函数调用栈的查看的实际代码案例
我们还是给出以下代码作为这次调试的代码
frame.c
#include stdio.hint sum(int n)
{int ret 0;if( n 0 ){ret n sum(n-1);}return ret;
}int main()
{int s 0;s sum(10);printf(sum %d\n, s);return 0;
}上述代码很简单sum函数是一个递归的求解过程最终求得123…n 开始进行调试 首先将程序编译并打开gdb调试这在前几篇文章已经做过很多次大概如下图所示的步骤 然后我们再sum函数处打一个断点并给出条件当n0的时候断点成立 break sum if n0 查看断点是否打上info breakpoints 运行程序continue 运行上述几个步骤后程序运行到sum函数并在sum函数递归调用到n0的时候停止 此时函数调用被中断我们现在来使用backtrace命令来查看之前sum函数的调用栈的顺序左侧的#0 #1…就是栈的编号 此时程序运行到n0本应该继续运行sum函数但是却被我们的断点中断了。所以此时停在最后一层的sum函数递归调用上。且是停在sum函数中的第6行 我们连续输入两次next并且查看当前程序的栈信息 程序运行到13行停下来了这一行是本该return的。此时的函数栈中 n0ret0,这个ret就差返回给上一层函数调用了。 现在我们来使用info registers查看当前的函数调用过程的各个寄存器的值并使用info frame查看当前函数调用过程的函数栈帧的详细信息 如上图寄存器比较多这里我们只关心一个寄存器ebpebp寄存器保存的是调用这个函数的函数也就是上一个函数在这里是#1号栈对应的函数栈帧基地址old_ebp。可以看到此时的函数栈帧中的ebp地址为0xbffff088。注意你自己运行的话地址可能与我的不一样。这个地址中保存的是上一个函数其实就是1号栈的基地址。我们使用以下命令来查看该地址处的内容 x /1bx 0xbffff088 //显示结果为 如上图红框内的内容就是#1号栈的基地址。当然我们可以验证连续输入两个next命令程序就会把返回值返回给#1号栈的函数调用。那么此时再输入info argsn就等于1因为此时位于#1号栈中。然后在输入info registers命令查看#1号栈的寄存器值信息如下 如上图#1号栈中的ebp值为0xbffff0b8与我们上面在#0号栈中查询的值是一样的。这与函数栈帧的理论也是完全相符的。 上面的调试内容非常简单我们并没有调试什么bug而是通过上述内容学习一些调试的技巧。
3 总结
本节内容学习如何使用GDB查看函数的调用栈信息。 本文章参考狄泰软件学院相关课程 想学习的可以加狄泰软件学院群 群聊号码199546072 学习探讨加个人可以免费帮忙下载CSDN资源 qq1126137994 微信liu1126137994 学习交流资源分享qq群962535112