• 上一篇文章学习了如何使用GDB数据断点进行内存监测:【软件开发底层知识修炼】十五 快速学习GDB调试三 使用GDB的数据断点监测变量是否改变
  • 本篇文章继续上一篇文章的学习:如何使用GDB进行函数调用栈的查看

文章目录

  • 1 backtrace和frame
  • 2 使用GDB进行函数调用栈的查看的实际代码案例
  • 3 总结

1 backtrace和frame

一般来说,查看函数调用栈,主要是为了研究函数的调用过程。

一般使用下面的命令进行查看:

  • backtrace

    • 查看函数的调用顺序(函数调用栈的信息)
  • frame N

    • 切换到栈编号为N的上下文中(具体栈编号是什么在下面的实际案例中会有)
  • info frame

    • 查看当前函数调用栈帧的信息

至于什么是栈帧信息,大概就是下图的样子,这里不再多介绍,后面还会有文章学习函数栈帧的概念,或者推荐大家去阅读程序员的自我修养。

  • 上面有一个info frame命令,我们在前几篇文章已经学习过info的几个命令。下面再介绍几个下图中的info命令:

2 使用GDB进行函数调用栈的查看的实际代码案例

我们还是给出以下代码,作为这次调试的代码:

frame.c

#include <stdio.h>int 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函数是一个递归的求解过程,最终求得1+2+3+…+n

  • 开始进行调试:
  • 首先将程序编译,并打开gdb调试,这在前几篇文章已经做过很多次,大概如下图所示的步骤:

  • 然后我们再sum函数处打一个断点,并给出条件,当n==0的时候断点成立

  • break sum if n==0

  • 查看断点是否打上:info breakpoints

  • 运行程序:continue

  • 运行上述几个步骤后,程序运行到sum函数,并在sum函数递归调用到n==0的时候停止:

  • 此时,函数调用被中断,我们现在来使用backtrace命令来查看之前sum函数的调用栈的顺序(左侧的#0 ,#1…就是栈的编号):

  • 此时程序运行到n==0,本应该继续运行sum函数,但是却被我们的断点中断了。所以此时停在最后一层的sum函数递归调用上。且是停在sum函数中的第6行:

  • 我们连续输入两次next,并且查看当前程序的栈信息:

  • 程序运行到13行停下来了,这一行是本该return的。此时的函数栈中 n==0,ret==0,这个ret就差返回给上一层函数调用了。

  • 现在我们来使用info registers查看当前的函数调用过程的各个寄存器的值,并使用info frame查看当前函数调用过程的函数栈帧的详细信息:

  • 如上图,寄存器比较多,这里我们只关心一个寄存器,ebp,ebp寄存器保存的是调用这个函数的函数(也就是上一个函数,在这里是#1号栈对应的函数)栈帧基地址(old_ebp)。可以看到,此时的函数栈帧中的ebp地址为0xbffff088。注意你自己运行的话地址可能与我的不一样。这个地址中保存的是上一个函数,其实就是1号栈的基地址。我们使用以下命令来查看该地址处的内容:

  • x /1bx 0xbffff088 //显示结果为:

  • 如上图,红框内的内容,就是#1号栈的基地址。当然我们可以验证:连续输入两个next命令,程序就会把返回值返回给#1号栈的函数调用。那么此时再输入info args,n就等于1,因为此时位于#1号栈中。然后在输入info registers命令查看#1号栈的寄存器值信息,如下:

  • 如上图,#1号栈中的ebp值为0xbffff0b8,与我们上面在#0号栈中查询的值是一样的。这与函数栈帧的理论也是完全相符的。

上面的调试内容,非常简单,我们并没有调试什么bug,而是通过上述内容,学习一些调试的技巧。

3 总结

  • 本节内容学习如何使用GDB查看函数的调用栈信息。
  • 本文章参考狄泰软件学院相关课程 想学习的可以加狄泰软件学院群, 群聊号码:199546072

  • 学习探讨加个人(可以免费帮忙下载CSDN资源):

  • qq:1126137994

  • 微信:liu1126137994

  • 学习交流资源分享qq群:962535112

【软件开发底层知识修炼】十七 快速学习GDB调试四 使用GDB进行函数调用栈的查看相关推荐

  1. 【软件开发底层知识修炼】十八 快速学习GDB调试五 使用GDB进行调试的一些小技巧

    上一篇文章学习了如何使用GDB进行函数调用栈的查看:[软件开发底层知识修炼]十六 快速学习GDB调试四 使用GDB进行函数调用栈的查看 本篇文章是GDB调试快速学习系列的最后一篇.将综合前几篇文章做一 ...

  2. 【软件开发底层知识修炼】十六 快速学习GDB调试三 使用GDB的数据断点监测变量是否改变

    上一篇文章我们学习了如何使用GDB进行软件断点调试和硬件断点调试:[软件开发底层知识修炼]十五 快速学习GDB调试二 使用GDB进行断点调试 本篇文章继续上一篇文章的学习,如何使用GDB的数据断点监测 ...

  3. 【软件开发底层知识修炼】十五 快速学习GDB调试二 使用GDB进行断点调试

    上一篇文章我们学习了使用GDB的最基本方法:[软件开发底层知识修炼]十四 快速学习GDB调试一 入门使用 本篇文章将学习GDB的断点调试.断点调试是一种非常重要的调试方法. 文章目录 1 断点类型 2 ...

  4. 【软件开发底层知识修炼】十四 快速学习GDB调试一 入门使用

    前面几篇文章学习了链接器相关的内容.现在开始来学习GDB调试.我们的目的是通过这几篇文章将GDB调试完全学会. 文章目录 1 为什么需要GDB 2 GDB 的常规应用 3 GDB调试程序实例 4 总结 ...

  5. 【软件开发底层知识修炼】十九 GDB调试从入门到熟练掌握超级详细实战教程学习目录

    本文记录之前写过的5篇关于GDB快速学习的文章,从第一篇开始学习到最后一篇,保证可以从入门GDB调试到熟练掌握GDB调试的技巧. 学习交流加 个人qq: 1126137994 个人微信: liu112 ...

  6. 【软件开发底层知识修炼】二十七 C/C++中的指针与数组是不同的

    上几篇文章学习了ABI-应用程序二进制接口:[软件开发底层知识修炼]二十六 ABI-应用程序二进制接口 学习总结文章目录 本篇文章就指针与数组的联系与区别来学习学习 文章目录 1 疑问 2 指针与数组 ...

  7. 【软件开发底层知识修炼】二十六 ABI-应用程序二进制接口 学习总结文章目录

    前面学习了ABI的知识,感觉受益良多.对底层与编译器有更加深刻的认识,为此这里将前面写过的关于ABI 的文章给列出来,方便学习与翻阅. [软件开发底层知识修炼]二十一 ABI-应用程序二进制接口一 [ ...

  8. 【软件开发底层知识修炼】二十八 C/C++中volatile的作用

    上一篇文章学习了C/C++中的指针与数组的区别,点击链接进行查看:[软件开发底层知识修炼]二十七 C/C++中的指针与数组是不同的 本篇文章将学习volatile关键字在C/C++中的作用 文章目录 ...

  9. 【软件开发底层知识修炼】二十五 ABI之函数调用约定二之函数返回值为结构体时的约定

    上一篇文章学习了几种函数调用约定的区别,点击链接查看上一篇文章:[软件开发底层知识修炼]二十四 ABI之函数调用约定 本篇文章继续学习函数调用约定中,关于函数返回值的问题.当函数返回值为结构体时,函数 ...

最新文章

  1. Python 抖音机器人,论如何在抖音上找到漂亮小姐姐?
  2. adb 显示手机分辨率
  3. 6_分布式训练框架Horovod使用(20190111)
  4. vc++基于颜色直方图的图像检索,含代码
  5. 计算机软件员证书用途,软考证书的五大好处(详解)
  6. mysql通配符查询 性能_使用mysql5.7新特性解决前通配符查询性能问题
  7. 为 Angular service 注册 provider 的三种方式
  8. FPGA时钟激励编写(方法三)
  9. 游戏角色坐标的保存间隔_游戏岗位看这里鸭——
  10. multipart/form-data与application/octet-stream的区别、application/x-www-form-urlencoded
  11. C语言程序实验01,广西科技大学理学院《C语言程序设计与算法语言》实验01: 熟悉开发环境.pdf...
  12. 电源大师课笔记 1.2
  13. 动易 当前服务器不允许上传文件,动易网站详细安说明及常见疑难解答.doc
  14. 联想微型计算机m910q,联想ThinkCentre M910x迷你台式机 获最佳创新产品奖
  15. 编写函数:笛卡尔坐标系(Append Code)
  16. [Fabric] 第11章 Fabric CA应用与配置
  17. windows环境下anaconda-navigaotr出现adding featured channels一直打不开的情况
  18. Vlc.DotNet C#音视频播放器使用说明及简单实例
  19. android会中病毒吗,安卓手机浏览网页中病毒几率多大
  20. 关于unity区域截图像素越界解决办法

热门文章

  1. 用strtotime()和date()函数算出2019年9月的周日日期
  2. Apache的虚拟主机
  3. codeforces-1176 (div3)
  4. 常见排序查询算法Java代码实现
  5. PyAutoIt 安装(Windows 版)
  6. SQL多列查询最大值
  7. 简单使用CXF实现webserver(rs的独立发布)
  8. python 一句话校验软件 hash值
  9. JAVA求集合中的组合
  10. 写一个简单控制台启动的mcv服务