C语言的那些小秘密之函数的调用关系.pdf

C 语言的那些小秘密之函数的调用关系语言的那些小秘密之函数的调用关系 显示函数的调用关系是调试器的必备功能 如果我们在程序的运行中出现了崩溃的情 况 通过函数的调用关系可以快速定位问题的根源 懂得函数调用关系的实现原理也可以扩 充自己的知识面 在没有调试器的情况下 我们也可以自己来实现显示函数的调用关系 在 我们自己动手写 backtrace 函数之前 先来看看 glibc 提供的 backtrace 函数的使用 代码 如下 include include include define MAX LEVEL 4 static void call2 int i 0 void buffer MAX LEVEL 0 int size backtrace buffer MAX LEVEL for i 0 i t sh t sh rm f t sh 输出结果为 home shiyan sss c 12 home shiyan sss c 27 home shiyan sss c 34 home shiyan sss c 40 接下来看看在栈中数据的结构 函数参数的压栈是从右向左的 即先压最后一个参数 在压倒数第二个 以此类推 最后才 压入第一个参数 为了加深大家的印象 下面我给出一个测试代码 include void turn int x int y int z printf x d at X n x printf y d at X n y printf z d at X n z int main int argc char argv turn 1 2 3 return 0 运行结果为 比较打印出来的地址可以看出参数 z 的地址是最大的 x 的地址最小 参数的压栈工作完成之后 接下来就依次是 EIP EBP 临时变量的压栈操作了 最后压入 的是被调用函数本身 并为它分配临时的变量空间 而对于不同版本的 gcc 的处理方式各 有不同 老版本的 gcc 第一个临时变量放在最高的地址 第二个其次 依次顺序分布 新 版本的 gcc 则与之相反 实现 backtrace 函数的调用关系 其步骤如下 1 获取当前函数的 EBP 2 通过 EBP 获得调用者得 EIP 3 通过 EBP 获得上一级的 EBP 4 重复这个过程 知道结束 自己实现的 backtrace 函数 代码如下 include define MAX LEVEL 4 define OFFSET 4 int backtrace void buffer int size int n 0 x23f int p int i 0 int ebp p 1 OFFSET int eip p 2 OFFSET for i 0 i size i buffer i void eip p int ebp ebp p 0 eip p 1 return size static void call2 int i 0 void buffer MAX LEVEL 0 int size backtrace buffer MAX LEVEL for i 0 i t sh t sh rm f t sh root ubuntu home shiyan tt awk print addr2line 3 e tt t sh t sh rm f t sh home shiyan bac c 32 home shiyan bac c 47 home shiyan bac c 54 home shiyan bac c 60 在此重点介绍下 backtrace 函数的实现原理 通过 int p 来获取第一个临时变量的位置 因为我使用的是新版本的 gcc 有 5 个临 时变量 所以 EIP 的值存放在 p 6 中 EBP 的的值存放在 p 5 通过 buffer i void eip 可以把 eip 的强制转换为可以指向任意类型的指针 接下来通过 p int ebp 来获得上一 个函数的 ebp 获得 ebp 之后由 ebp 和 eip 的位置关系可以得到 eip 由于 ebp 指向的单元 存储的是上一个函数的 ebp 所以用一个简单的 for 循环就能实现了 另外在头文件 execinfo h 中除了声明 backtrace 函数外 还有如下两个函数也用于获取当前线 程的函数调用堆栈 char backtrace symbols void const buffer int size backtrace symbols 将从 backtrace 函数获取的信息转化为一个字符串数组 参数 buffer 应 该是从 backtrace 函数获取的数组指针 size 是该数组中的元素个数 backtrace 的返回值 函数返回值是一个指向字符串数组的指针 它的大小同 buffer 相同 每个字符串包含了一个相 对于 buffer 中对应元素的可打印信息 它包括函数名 函数的偏移地址 和实际的返回地址 现在 只有使用 ELF 二进制格式的程序和苦衷才能获取函数名称和偏移地址 在其他系统 只 有 16 进制的返回地址能被获取 另外 你可能需要传递相应的标志给链接器 以能支持函数名 功能 比如 在使用 GNU ld 的系统中 你需要传递 rdynamic 该函数的返回值是通过 malloc 函数申请的空间 因此调用这必须使用 free 函数来释放指针 注意 如果不能为字符串获取足够的空间函数的返回值将会为 NULL Function void backtrace symbols fd void const buffer int size int fd backtrace symbols fd与backtrace symbols 函数具有相同的功能 不同的是它不会给调用 者返回字符串数组 而是将结果写入文件描述符为 fd 的文件中 每个函数对应一行 它不需要 调用 malloc 函数 因此适用于有可能调用该函数会失败的情况 还是那句话 以上内容难免有误 如有错误 请纠正

c语言的那些小秘密pdf下载,C语言的那些小秘密之函数的调用关系.pdf相关推荐

  1. c语言入门自学免费app,C语言入门学习最新版下载-C语言入门学习app手机版v1.0.2 安卓版-腾飞网...

    C语言入门学习app手机版是一款c语言编程自学软件,零基础也可以学习,里面有海量教学视频,针对c语言不同程度的讲解都囊括其中.随时随地学习编程都可以,不用担心自己没有基础.还支持在手机上敲代码编程哦. ...

  2. 安卓下的c语言ide,C语言编译器IDE安卓版下载-C语言编译器IDE下载v1.7 最新版-腾牛安卓网...

    C语言编译器IDE安卓版下载,一款专业实用的C语言编程工具,C语言编译器IDE帮助更多小伙伴们创建C语言项目,进行高效便捷的代码编辑,有需要就来下载. C语言编译器IDE介绍 C语言编译器IDE,是一 ...

  3. c语言程序设计安卓,C语言编程宝典最新版下载-C语言编程宝典appv1.7.1 安卓版-腾牛安卓网...

    C语言编程宝典app是一款用来学习变成的软件,里面大量的教学视频,用户可以在线学习,还提供超多相关资料和习题,让用户轻松掌握知识点.小伙伴们快快下载吧! 软件简介: 这是一款学习C语言的神器 根据知名 ...

  4. alin的学习之路:C语言篇(一)(内存四区模型,宏函数,调用惯例,内存存储方式)

    @TOC(内存四区模型,宏函数,调用惯例,内存存储方式) 1. 内存四区及其使用注意 内存四区:代码区,全局静态区,栈区,堆区 代码区 代码区存放的是CPU执行的二进制指令 特点: 只读 共享 栈区 ...

  5. c+语言基础教程pdf下载,C语言基础教程.PDF

    目錄 Introduction 1.1 入门教程 1.2 helloworld 1.2.1 数值 .字符与字符串 1.2.2 运算符及表达式 1.2.3 选择结构与循环结构 1.2.4 函数基本概念及 ...

  6. c语言设计项目化pdf下载,C语言程序设计项目化教程pdf(附答案)电子版

    通过了C语言入门的学习,很多朋友已经掌握了一定的C语言知识,那么想要进一步深入了解,就可以开始学习这本C语言程序设计项目化教程了,让你深入了解项目开发,感兴趣的朋友快来下载使用吧. C语言介绍 C语言 ...

  7. c语言进制转换pdf下载,C语言实现任意进制转换.doc

    C语言实现任意进制转换.doc includestdio.h#includemath.h#includestring.hvoid dtox(double num,int jz)char xnum100 ...

  8. c语言基础知识pdf下载,C语言主基础知识.pdf

    C语言主基础知识 泰山学院CSDN 俱乐部 C 语言主要基础内容 1.预处理命令 预处理的概念:在编译之前进行的处理.预处理命令以符号"#"开头. 2 .关于#include 在编 ...

  9. 背口诀14天精通c语言pdf下载,C语言必背18个经典程序

    C语言必背18个经典程序 1./*输出9*9口诀.共9行9列,i控制行,j控制列.*/ #include "stdio.h" main() {int i,j,result; for ...

最新文章

  1. 干掉Spring Cloud,这个框架是微服务的未来!
  2. 提升PHP性能使用细节
  3. 美国汽车协会实测:行人检测系统都是渣渣,包括特斯拉
  4. mybatis学习2之ResultMap结果集映射
  5. GdiPlus[30]: IGPPen: 线帽
  6. mongodb添加创建修改时间_MongoDB数据库插入、更新和删除操作详解
  7. redux-thunk使用_Redux Thunk用示例解释
  8. stream对多个字段分组_java8 stream 如何按多字段分组,并对一个字段求和
  9. python image模块需要安装吗_python Image模块安装
  10. protoc 命令 java_用proto命令生成java文件
  11. PPT 如何做好关卡设计
  12. 春节见闻之北京前门步行街
  13. Redis--blpop命令使用
  14. 整理农行面试软开最常问到的题---------框架
  15. 应用wps对证件照进行更改颜色,更换只需三步。
  16. JavaScript入门案例
  17. WIFI手机使用正常电脑使用卡顿解决方案
  18. 一文读懂DeFi衍生品市场六大方向及底层发展逻辑 |链捕手
  19. matlab 球坐标绘图,在Matlab中绘制球坐标系
  20. 关于计算机的英语论文1500字,计算机英语论文3000字

热门文章

  1. java8 collect 类型转换_Java 8 新特性 Stream类的collect方法
  2. jQuery 表格自动增加
  3. php 数组压入,PHP 2、array_push和[]
  4. k8s往secret里导入证书_Rancher 修改Kubernetes Ingress默认ssl证书
  5. mysql 账户管理_Mysql账户管理_MySQL
  6. 继电器触点粘连分析_真空充气包装机的继电器触点有哪几种类型?
  7. Java 启动和停止界面_IntelliJ IDEA 2019.3 发布,启动更快,性能更好(新特性解读)...
  8. 计算机网络的体系结构与协议基本概念,计算机网络技术基础-第3章网络体系结构与协议.ppt...
  9. c语言 goto 跳出循环,goto语句可以跳出循环.ppt
  10. 微信小程序rpx作为高度单位时,在 ios 出现异常