GDB堆栈跟踪与汇编调试

摘要:
GDB堆栈跟踪和汇编调试堆栈跟踪源代码:用于预先编写的堆栈C文件,并使用CGDB来调试、跟踪堆栈,并了解代码堆栈的变化。在CGDB中,首先设置主断点,然后运行它。使用frameinfoframe查看当前堆栈帧的简要信息和堆栈帧的详细信息。当我们指定字节长度时,GDB将从指定内存中指定的内存地址开始,读取和写入指定的字节,并将其作为一个值。
GDB堆栈跟踪与汇编调试

堆栈跟踪

  • 源代码:
    GDB堆栈跟踪与汇编调试第1张

  • 对预先编写的 stack.c 文件进行编译,并且使用 CGDB 进行调试,对堆栈进行跟踪,了解该代码堆栈是如何变化的。
    GDB堆栈跟踪与汇编调试第2张

  • CGDB 中,先设置 main 断点,接着运行(run),使用 frameinfo frame 分别查看当前栈帧的简要信息,以及该栈帧的详细信息。其中:

    • frame 打印出的信息:栈的层编号,当前的函数名,函数参数值,函数所在文件及行号,函数执行到的语句。
    • info frame 打印出的信息:函数地址,调用函数的地址,被调用函数的地址,目前的函数是由什么样的程序语言写成的、函数参数地址及值、局部变量的地址等等。
      GDB堆栈跟踪与汇编调试第3张
  • 输入命令 disassemble ,显示出该代码(main())的汇编形式
    GDB堆栈跟踪与汇编调试第4张

  • info registers ,显示当前(main()处)寄存器值
    GDB堆栈跟踪与汇编调试第5张

  • 使用 s 单步运行程序:

    • 运行到 f1 函数内,观察此时堆栈情况
      GDB堆栈跟踪与汇编调试第6张

    • 运行到 g1 函数内,观察此时堆栈情况
      GDB堆栈跟踪与汇编调试第7张

    • 使用 updown ,跳转不同堆栈,查询其中的堆栈简要信息
      GDB堆栈跟踪与汇编调试第8张

  • 该代码中,共存在过3个堆栈,对每个堆栈查询其详细信息,观察堆栈变化:

    • main() 函数形成的堆栈(#2):
      GDB堆栈跟踪与汇编调试第9张

    • f1 函数形成的堆栈(#1):
      GDB堆栈跟踪与汇编调试第10张

    • g1 函数形成的堆栈(#0):
      GDB堆栈跟踪与汇编调试第11张

  • 根据3个堆栈的详细信息,画出大致的堆栈示图(此时,程序运行在 g1 ,还没有返回):
    GDB堆栈跟踪与汇编调试第12张

汇编调试

  • GDB 指令加上i就显示汇编代码,例如:n(ext)i、s(tep)i,其中:

    • (gdb)p/x i:打印变量名为 i 的十六进制值
    • (gdb) display /3i $pc:这是一种设置,设置好了调试过程中每一步都回显一次,这里是一次显示 3 行,3 在这里是指一次显示几行,不输入,缺省为1
    • (e)xamine:功能和display差不太多,区别就是display是一种设置,每次跳命令显示一次,x是主动显示:x/<n/f/u> <addr>
      • n选择从当前地址向后显示几个
      • f是显示格式,还有s字符串和i整型
      • u表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4个bytes。u参数可以用下面的字符来代替,b表示单字节,h表示双字节,w表示四字节,g表示八字节。当我们指定了字节长度后,GDB会从指内存定的内存地址开始,读写指定字节,并把其当作一个值取出来。
      • 例:x/3uh 0x54320表示,从地址0x54320读取,h表示以双字节为单位,3表示三个单位,u表示十六进制
  • mainf1g13个函数所对应的汇编代码

GDB堆栈跟踪与汇编调试第13张

GDB堆栈跟踪与汇编调试第14张

GDB堆栈跟踪与汇编调试第15张

  • 设置display ,每一步显示一行代码,查看当前 main() 断点处初始的寄存器值(主要观察%eax,%ebx,%esp,%eip)

GDB堆栈跟踪与汇编调试第16张

  • printf("%d ,f1(1)+6);转到fi函数地址处:

GDB堆栈跟踪与汇编调试第17张

  • int f1(int x){建立f1函数的堆栈,保存数据,更新信息:

GDB堆栈跟踪与汇编调试第18张

GDB堆栈跟踪与汇编调试第19张

GDB堆栈跟踪与汇编调试第20张

  • return g1(x);保存f1函数的数据,之后跳转到g1函数的地址:

GDB堆栈跟踪与汇编调试第21张

GDB堆栈跟踪与汇编调试第22张

GDB堆栈跟踪与汇编调试第23张

  • int g1(int x)建立g1函数的堆栈,保存数据,更新信息:

GDB堆栈跟踪与汇编调试第24张

GDB堆栈跟踪与汇编调试第25张

  • return x+5;,进行计算:

GDB堆栈跟踪与汇编调试第26张

GDB堆栈跟踪与汇编调试第27张

  • },销毁g1函数的堆栈,并且回到从f1函数跳出来的下一条指令:

GDB堆栈跟踪与汇编调试第28张

GDB堆栈跟踪与汇编调试第29张

  • },销毁f1函数的堆栈,并且回到从main函数跳出来的下一条指令:

GDB堆栈跟踪与汇编调试第30张

GDB堆栈跟踪与汇编调试第31张

  • printf("%d ,f1(1)+6);进行运算,并且转到执行 printf
    的代码处,使之打印出最终结果:

GDB堆栈跟踪与汇编调试第32张

GDB堆栈跟踪与汇编调试第33张

GDB堆栈跟踪与汇编调试第34张

GDB堆栈跟踪与汇编调试第35张

GDB堆栈跟踪与汇编调试第36张

栈帧变化

  • 其中,每条代码指令为正在执行的代码,所有后面的%esp、%ebp、%eax以及栈帧情况都是上一条指令的结果,在等待正在执行的指令完成后再更改
    GDB堆栈跟踪与汇编调试第37张

参考资料

免责声明:文章转载自《GDB堆栈跟踪与汇编调试》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Linux性能优化实战学习笔记:第五十一讲PyQt学习随笔:QTableWidget水平表头horizontalHeader、竖直表头verticalHeader的相关操作方法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

ubuntu12.04 gdb安装使用

参考文档:http://blog.csdn.net/haoel/article/details/2879 http://www.programlife.net/gdb-manual.html 【新手笔记】: 安装: 1、下载源码并解压: wget ftp://sourceware.org/pub/gdb/releases/gdb-7.8.tar.gz ta...

IDEA+PHP+XDebug调试配置

XDebug调试配置 临时需要调试服务器上的PHP web程序,因此安装xdebug,下面简单记录 安装xdebug 下载最新并解压 wget https://xdebug.org/files/xdebug-2.5.4.tgz tar zxvf xdebug-2.5.4.tgz cd xdebug-2.5.4/ 编译 按照README里的步骤安装 ./...

Xcode的控制台调试命令

XCode4.0以后,编译器换成了LLVM 编译器 2.0 与以前相比,更加强大:1.LLVM 编译器是下一带开源的编译技术.完全支持C, Objective-C, 和 C++.2.LLVM 速度比 GCC快两倍,建立的程序也会运行的更快. 因为它更好的利用现代的芯片的结构.3.LLVM和Xcode 4完全的整合在一起.包括关键字高亮,代码完整性等全都是由...

Eclipse+php插件+Xdebug搭建PHP完美开发/调试环境指南

 最近要开始使用Zend框架开发中型应用系统了,由于采用完全面向对象的框架思路开发程序,不光开发思想,先前的Editplus+Dreamweaver编辑器组合显然不能满足我的要求了。我的新环境初步定为Eclipse+PDT插件+Xdebug+apache(Unix平台最流行的WEB服务器平台)。   先前一直对dotNET、Java的IDE的代码自动嗅探、...

如何用VS进行程序调试

VS是一个强大的IDE,如果你现在只会简单地用它查看一下执行效果,那就太大材小用了。 1. CRT函数报错 首先来说说最常见的一个编译错误。微信里常常收到这个错误的截图提问。 CRT(C Runtime Library = C运行时间库)是windows平台下的一个概念。CRT函数准的C语言函数。例如:printf、scanf、strlen、fopen等函...

DevExpress源码编译总结

独家提供完整可编译sln文件,本篇文章内容包括基础知识(GAC、程序集强签名、友元程序集)、编译过程、注册GAC、添加工具箱、多语言支持、运行时和设计时调试 源码地址链接:http://pan.baidu.com/s/1miNCHug密码:rlyr关于编译源码,前前后后折腾了太久,自己折腾,到官网折腾,到DXPER折腾,今天,总算有个结局了 编译环...