[转] GDB调试器源代码分析系列--Inferior call的实现与分析(1) (2011-10-11 20:41)
标签: 分析 分类: 调试器

先说说几个概念:

(1)     什么是inferior

GDB表示一个程序执行的状态叫inferior。一个Inferior通常情况下是和一个进程相关,但它也应用于没有进程概念的target。每次运行一个可执行的程序就会创建一个新的inferiro。

(2)     什么叫inferior call

在调试状态下,当我们想要判断一个函数的输出结果是否和预期结果相同的时候。我们可以在GDB中使用p fun(arg) 或者call fun(arg)等方式来让函数在目标端执行,执行完毕之后输出程序执行结果,并保持目标系统和调用这个函数之前的状态一致。

本文将针对sparc v8平台对GDB中inferior call 的实现进行分析。

通过对GDB-7.3中inferior call实现的跟踪分析,其主要实现函数为call_function_by_hand,该函数主要做了如下几件事情:

(1)     将断点链表保存起来

(2)     保存调用者的寄存器和与inferior相关的其它状态,以便于inferior call返回之后能恢复到调用之前的状态。

(3)     变换堆栈指针以便为inferior call做准备。这部分涉及到具体目标平台和相关OS ABI约定。

1>     在一台RISC架构的机器上,调用一个没有参数和没有返回值的参数所形成的栈通常情况下是不会push任何东西的,这样使得其SP和FP的值相等。

2>     在SPARC中,叶子函数可能由于编译器的优化,将会使用调用者的堆栈,这样使得FP和SP没有变化。如何1> 和2>情况下所说的函数产生一系列调用将形成一连串相似的栈。这样调试器在进行栈展开的时候可能陷入无限循环

为了避免上述所说情况的发生,我们通常会增长一些栈空间,并让SP满足此时OS ABI要求的对齐要求。

(4)     根据符号表找到inferior call函数的前两条地址,其目的是为了将其分别赋值给pc 和npc

(5)     紧接着要做的事情就是按照OS ABI以及目标平台处理器的一些约定,调整SP的值,开辟栈空间保存调用一个函数要做的事情。下面根据SPARC处理器的函数调用约定,展示调用一个函数,它的栈的是如何布局的。

图1 用户栈布局

下面对上图做一些解释:

1.       上图适用于被优化的叶子函数调用之外的所有的函数调用。

2.        SPARC V8平台中每个函数调用栈都要分配空间

1>     六个字的空间

为了给被调用者传递参数

2>     一个字的空间

这是用于当调用者期待被调用者返回一个聚合数据。

3>     16个字的空间

用于保存caller的 in 和 local 寄存器

3.       根据需要在编译的时候分配栈空间

1>     Caller传递给callee的参数超过六个的时候需要的额外空间

2>     Callee中所有自动数据、自动变量等

3>     编译器产生的临时值

4>     浮点寄存器保存的地方,加入在callee中用到了浮点指令

4.       通过c库里alloca动态分配的空间

(6)     在(5)调整的过程中改变寄存器的一些值,将计算出来的call-pc值写入寄存器o7

将参数的值写入O0,O1….等寄存器

存储参数的值到栈空间对应的地址中

调整pc和npc的值分别为要执行的函数的第一条和第二条地址

在栈中存放断点的地方写入ta 1

(7)     然后就是调试器执行恢复程序运行,遇到断点停下来之后,恢复(1) (2)中保存的值

总结:inferior call的实现原理还是比较简单的,关键要根据目标平台的一些约定,开辟好调用一个函数所需要的栈空间,并将相关值写入相关寄存器和指定内存处即可

转自 http://blog.chinaunix.net/uid-20912808-id-2951159.html

GDB调试器源代码分析系列--Inferior call的实现与分析(1)相关推荐

  1. Linux调试——gdb调试器的简单使用调试coredump文件

    文章目录 一.背景 二.gdb的指令与使用 1.gdb的基本指令. 2.gdb指令的简单使用 1.进入gdb模式 2.实例说明 三.调试coredump文件 前提:本质上是在调试程序崩溃之后的内存镜像 ...

  2. [转载].gdb调试器快速入门

    调试在我们编写程序时占有重要的地位.在linux下如何使用gdb调试器?下面采用FQA的方式让你快速了解gdb调试器. 1.如何启动gdb调试器呢? 在终端输入 gdb 程序文件名 即可.注意gdb调 ...

  3. 【Linux学习】GDB调试器基本命令必知必会(一)

    本文介绍Linux下GDB调试器常用的基本命令. 测试均在Ubuntu12.10下完成. 先看看GDB调试的效果图: 对应的源代码: //插入排序,GDB调试测试代码 #include <std ...

  4. linux卸载gdb命令,【Linux学习】GDB调试器基本命令必知必会(一)

    本文介绍Linux下GDB调试器常用的基本命令. 测试均在Ubuntu12.10下完成. 先看看GDB调试的效果图: 对应的源代码: //插入排序,GDB调试测试代码 #include int x[1 ...

  5. Linux系列学习(二) - Vim编辑器的介绍及使用、文件编译的过程、Makefile工具、Gdb调试器

    目录 引言: 基本命令补充: cat命令: man命令: head命令: tail命令: find命令: grep命令: ​​​​​​​grep命令与管道"|" 的结合使用: ta ...

  6. GDB调试器——GDB调试器简介

    以下内容源于C语言中文网的学习与整理,如有侵权,请告知删除. 一.程序调试器的含义 程序中的错误主要分为 2 类,分别为语法错误和逻辑错误. 程序中出现的语法错误可以借助编译器解决:但逻辑错误则只能靠 ...

  7. 调试器工作原理系列一: 基础篇

    调试器工作原理系列一: 基础篇 本文是一系列探究调试器工作原理的文章的第一篇.我还不确定这个系列需要包括多少篇文章以及它们所涵盖的主题,但我打算从基础知识开始说起. 关于本文 我打算在这篇文章中介绍关 ...

  8. GDB调试器使用手册

    GDB调试器使用手册     使用GDB:     本文描述GDB,GNU的原代码调试器.(这是4.12版1994年一月,GDB版本4.16) * 目录: * 摘要:                  ...

  9. GCC编译器和GDB调试器常用选项

    GCC编译器 gcc hello.c -o hello                   #将hello.c编译成hello可执行文件 gcc -E hello.c -o hello.i       ...

最新文章

  1. Java【快速排序、插入排序、简单选择排序...】【八大排序-综合实验】
  2. mysql服务器多线程模型_mysql-线程模型
  3. RFC and session issue - why we should use DESTINATION NONE?
  4. LDAP命令介绍---import-ldif
  5. twisted系列教程十六–twisted守护进程
  6. mysql查询有数据但返回null_Mybatis查不到数据查询返回Null问题
  7. Python一课一练(网站项目做单元测试)
  8. Scrapy框架的介绍和基本使用
  9. 海康威视h5无插件播放解决方案
  10. 低压电气控制技能实训装置
  11. dict后缀_词根词缀法记单词之dict
  12. oppo升级android,OPPO Real R807升级Android4.0教程
  13. NoteExpress 学校集团版本 校园网导入EI题录
  14. html转PDF并添加水印
  15. C:\Users\用户名\AppData\Roaming里面的文件可以删除吗?
  16. 【目标检测适用】Pascal Voc(07+12)联合训练并在07上测试
  17. 让你重新爱上 Windows 的小众软件
  18. js实现进度条组件(Progress)
  19. 让游戏通过红蓝立体眼镜展现立体效果
  20. Android8-Settings-BlueTooth

热门文章

  1. IIS 发生意外错误 0x8ffe2740
  2. 联想G40-70固态安装教程(实际操作经验)
  3. 超简单详细小白双系统安装教程Win10+deepin
  4. 使用Swift模拟Window-LFU
  5. 【UVM基础】两种启动 sequence 的方式
  6. 数据防泄漏 | 禁止PrintScreen键
  7. aes hex 加密
  8. 深圳中学高考2021成绩查询,2020深圳高中高考数据对比,明年考多少分能上好高中?...
  9. 关于流程图设计,你需要Get的几点必备知识
  10. 关于微信公众号开发【微信JS-SDK】报错:config invalid url domian