首页 > 其他分享 >一文搞懂 Ftrace 的实现原理

一文搞懂 Ftrace 的实现原理

时间:2022-08-20 22:12:09浏览次数:60  
标签:Ftrace 一文 int request update bl ftrace blk 搞懂

arm64 栈帧结构

arm64 有31个通用寄存器 r0-r30,用法分别如下:

寄存器 意义
SP Stack Pointer: 栈指针
r30 Link Register: 在调用函数时候,保存下一条要执行指令的地址
r29 Frame Pointer:保存函数栈的基地址
r28...r19
r18
r17
r16
r15...r9 临时寄存器
r8 在一些情况下,返回值是通过 r8 返回的
r7...r0 在函数调用过程中传递参数和返回值
NZCV 状态寄存器:N(Negative)负数 Z(Zero) 零 C(Carry) 进位 V(Overflow) 溢出

下面以如下代码为例,说明它的栈帧结构:

int fun2(int c,int d)
{
   return0;
}
 
int fun1(int a,int b)
{
   int c = 1;
   int d = 2;
  
   fun2(c, d);
   return0;
}
 
int main(int argc,char **argv)
{
   int a = 0;
   int b = 1;
   fun1(a,b);
}

其反汇编后的结果和对应栈帧结构为:

image

其详细步骤如下:

  1. 每个函数在入口处首先会分配栈空间,且一次分配,确定栈顶,之后sp将不再变化;
  2. 每个函数的栈顶部存放的是caller的栈顶指针,即fun1的栈顶存放的是main栈顶指针;
  3. 对于最后一级callee函数,由于x29保存了上一级caller的栈顶sp指针,因此不在需要入栈保存,如示例中fun2执行时,此时x29指向fun1的栈顶sp

编译阶段

以 blk_update_request 为例,看下其开启 Ftrace 前后的反汇编代码:

image

可以看出,右图中多插入了一段【3f3c: 94000000 bl 0 <_mcount>】,那么是由谁何时插入的呢?

编译选项 -pg -mrecord-mcoun 会在编译时,在每个可 trace 的函数插入 bl 0 <_mcount>。

链接阶段

image

可以看出编译阶段的【3f3c: 94000000 bl 0 <_mcount>】,在链接阶段变成了【ffff8000104e43f4: 97ed1fde bl ffff80001002c36c <_mcount>】。

其中 _mcount 函数反汇编为:

ffff80001002c36c <_mcount>:
ffff80001002c36c:       d65f03c0        ret

运行阶段

ftrace_init 执行后的 blk_update_request

image

可见,内核在 start_kernel 执行时,会调用 ftrace_init,它会将所有可 trace 函数中的 _mcount 进行替换,如上可以看出链接阶段的 【bl ffff80001002c36c <_mcount>】 已经被替换为 【nop】 指令。

设定 trace 后的 blk_update_request

先执行如下命令来 trace 函数 blk_update_request:

$echo blk_update_request > /sys/kernel/debug/tracing/set_ftrace_filter

$echo function > /sys/kernel/debug/tracing/current_tracer

然后再来查看blk_update_request反汇编代码:

image

可以看到之前在 blk_update_request 的 【nop】 指令被替换成 【bl 0xffff80001002c370 <ftrace_caller>】。函数 ftrace_caller 将调用用户注册的 trace 函数。

总结

  1. 编译阶段。通过编译选项 -pg -mrecord-mcount 在每个支持 trace 的函数中插入 bl 0 <_mcount> 指令。
  2. 链接阶段。会根据重定位段将 bl 0 <_mcount> 指令地址重定位为 _mcount 函数地址。
  3. 运行阶段。
(1). ftrace_init:会将可 trace 函数中的 【bl      0 <_mcount>】 替换为 【nop】 指令;

(2). 执行 echo blk_update_request > set_ftrace_filter:会使能 blk_update_request 的钩子函数替换标记(nop 替换为 ftrace_caller);

(3). 执行 echo function > current_tracer:将 ftrace_caller 中 ftrace_call 被替换为 ftrace_ops_no_ops,最终会调用到 function_trace_call。

image

标签:Ftrace,一文,int,request,update,bl,ftrace,blk,搞懂
From: https://www.cnblogs.com/linhaostudy/p/16608888.html

相关文章

  • 一文带你认知定时消息发布RocketMQ
    摘要:DMS任意时间定时消息能力发布。DMS是华为云的分布式消息中间件服务。适用于解决分布式架构中的系统解耦、跨系统跨地域数据流通、分布式事务协调等难题,协助构建优雅的......
  • 一文搞懂EMAS Serverless小程序开发|电子书免费下载
    >>快来免费下载|电子书《五天玩转EMASServerless》<<点击免费下载《五天玩转EMASServerless》EMASServerless是什么EMASServerless是阿里云提供的基于Serv......
  • linux性能工具--ftrace框架
    对于ftrace架构,主要来了解下内核是如何实现的,其主要包括如下内容:ringbuffer的原理和代码分析tracer(function、function_graph、irq_off)原理和代码分析traceevent......
  • 一文搞懂│mysql 中的备份恢复、分区分表、主从复制、读写分离
    目录......
  • 一文看懂线性回归和非线性回归
    一文看懂线性回归和非线性回归           1.非线性回归           2.线性回归           3.总结1.非线性回归我们首先来看维基百......
  • 一文搞懂 Dubbo 入门理论
    RPC简介 ● RPC,RemoteProcedureCall,远程过程调用,是一种跨系统间服务调用的协议或框架 ● 在很多企业,在内部存在大量的业务子系统,这些子系统都承担独立的业务功......
  • 一文明白安卓64位和32位的区别,通俗明了。【思路篇】
    前言:自从2019年8月1日起,只要上架googleplay应用市场就必须提供64位版本的App才能上架。1、64位和32位有什么区别64位和32位指的是CPU处理器一次处理数据的能力是32位还......
  • 由浅入深!一文带你彻底明白堆排序
    本文中所有的代码全都是大根堆!实现语言是Java图片来源都是这位大神的,大神的文章也给了我很多启发数据结构之堆堆排序这个视频通俗易懂从什么是堆,什么是堆化,再到实现......
  • 一文说透kafka底层架构
    底层架构先停一下,学习之前,先看下如何学习,两篇不错的干货文章分享给你,一定要点开看下如何从普通程序员,进阶架构师!工作几年?如何快速晋升架构师!!6.1存储架构6.1.1......
  • 一文带你弄懂 JVM 三色标记算法!
    大家好,我是树哥。最近和一个朋友聊天,他问了我JVM的三色标记算法。我脑袋一愣发现竟然完全不知道!于是我带着疑问去网上看了几天的资料,终于搞清楚啥事三色标记算法,它是用......