通过实例了解uprobe及其对性能的影响

2023-05-16

前言

uprobe是用户空间探针的意思,可以用来给用户程序的任何地方下探针,不仅仅是函数粒度层级的。所以异常灵活。
如果不熟悉ftrace、uprobe, 可参考以下文档:
https://www.kernel.org/doc/Documentation/trace/ftrace.txt
https://www.kernel.org/doc/Documentation/trace/uprobetracer.txt
市面上有很多关于uprobe用法及原理的讨论,但是关于其性能方面的还比较少,本文就通过一个例子简单讲讲,同时读者也能从中直观的看到如何使用uprobe.

试验

#include<unistd.h>
#include <stdio.h>
#include <time.h>

long Fibon(int n)
{
        long f1 = 1;
        long f2 = 1;
        long f3 = 1;

        for(int i=2; i<n; i++)
        {
                f3 = f1+f2;
                f1 = f2;
                f2 = f3;
        }
        return f3;
}

clock_t start,stop;
double duration;

int main()
{
        printf("beginning...\n");
        start=clock();
        int n=90;
        for(int j=0; j<10000; j++){
                for(int i=1;i<n;i++){
                        Fibon(i);
                }
        }
        stop=clock();
        duration=((double)(stop-start));
        printf("ending..., cost=%f\n", duration);
        getchar();
}

gcc fibon.c -o fibon
运行90*10000次Fibon函数,如果不启用uprobe,需要
ending…, cost=168160.000000, 单位不管。

下面启用uprobe:

cd /sys/kernel/debug/tracing
echo 'p:fib /root/perf-tools/bin/fibon:0x666 %di' > uprobe_events
echo 1 > events/uprobes/enable
echo 1 > tracing_on
cat trace_pipe

0x616是函数Fibon相对于fibon二进制文件的偏移(偏移可以是任何地方,此处定为Fibon函数的起始位置, 也可以用Fibon代替),%di是Fibon函数的第一个参数。
trace_pipe的输出:

<...>-1212121 [000] d... 51234725.814331: fib: (0x400666) arg1=0x1
<...>-1212121 [000] d... 51234725.814332: fib: (0x400666) arg1=0x2
<...>-1212121 [000] d... 51234725.814333: fib: (0x400666) arg1=0x3
<...>-1212121 [000] d... 51234725.814334: fib: (0x400666) arg1=0x4
...

花费的时间:

# ./fibon
beginning...
ending..., cost=1216286.000000

168160 VS 1216286
大概慢了7倍。也就是探针花费的时间大概相当于6个Fibon函数自身的时间。
uprobe的原理大概是:
executable+offset处的代码会被替换成int3 -> 执行到此会触发SIGTRAP -> 转向内核处理中断 -> 转向用户态执行uprobe代码-> 继续执行原来的代码。内核与用户态的转换比较耗时。

executable+offset处的代码会被替换成int3(0xCC):

(gdb) disass Fibon
Dump of assembler code for function Fibon:
   0x0000000000400666 <+0>:     *int3*
   0x0000000000400667 <+1>:     mov    %rsp,%rbp
   0x000000000040066a <+4>:     mov    %edi,-0x24(%rbp)
   0x000000000040066d <+7>:     movq   $0x1,-0x8(%rbp)

关闭uprobe后,指令恢复:

(gdb) disass Fibon
Dump of assembler code for function Fibon:
   0x0000000000400666 <+0>:     push   %rbp
   0x0000000000400667 <+1>:     mov    %rsp,%rbp
   0x000000000040066a <+4>:     mov    %edi,-0x24(%rbp)

如果于0x667处下探针:

(gdb) disass Fibon
Dump of assembler code for function Fibon:
   0x0000000000400666 <+0>:     push   %rbp
   0x0000000000400667 <+1>:     int3
   0x0000000000400668 <+2>:     mov    %esp,%ebp
   0x000000000040066a <+4>:     mov    %edi,-0x24(%rbp)

好了,春节期间,简单写写。

上面用的是Ftrace,简单补充一个bpftrace的写法:

bpftrace -e 'uprobe:/root/perf-tools/bin/fibon:Fibon {printf("arg1=0x%x\n", reg("di"));}'

bpftrace语法简单功能强大,但是要求比较高:内核版本4.1及以上。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过实例了解uprobe及其对性能的影响 的相关文章

随机推荐

  • 控制教程 —— 介绍篇:3.PID控制器设计

    承接上一篇 控制教程 介绍篇 xff1a 2 系统分析 介绍完系统建模和基本的系统分析后 xff0c 我们已经了解了被控对象的特性 xff0c 这时 xff0c 就需要用一个合理的控制器 xff0c 让这个被控对象在该控制器下按照指定的给定
  • FreeRTOS —— 4.队列管理

    4 1 本章介绍与适用范围 队列 提供了任务到任务 xff0c 任务到中断以及中断到任务的通信机制 范围 本章旨在使读者更好地理解 xff1a 如何创建队列 队列如何管理其包含的数据 如何将数据发送到队列 如何从队列接收数据 阻塞队列意味着
  • LSTM一般最多堆叠多少层

    一 LSTM一般最多堆叠多少层 在大规模翻译任务的经验中 简单的堆叠LSTM层最多可以工作4层 很少工作6层 超过8层就很差了 Redisual connection有助于梯度的反向传播 xff0c 能够帮助lstm堆叠更多层 xff0c
  • 华为机试在线训练-牛客网(23)判断两个IP是否属于同一子网

    题目描述 子网掩码是用来判断任意两台计算机的IP地址是否属于同一子网络的根据 子网掩码与IP地址结构相同 xff0c 是32位二进制数 xff0c 其中网络号部分全为 1 和主机号部分全为 0 利用子网掩码可以判断两台主机是否中同一子网中
  • APISIX Dashboard中文文档(二)

    2022年7月6日14 31 51 APISIX Dashboard中文文档 一 APISIX Dashboard中文文档 二 APISIX Dashboard中文文档 三 基本部署 在 Linux 上安装 Apache APISIX Da
  • FreeRTOS 任务调度原理(基于cortexM内核)

    目录 默认FreeRTOS调度策略 xff08 单核 xff09 FreeRTOS调度策略的实现 任务创建 任务调度的4种情景 xff1a 1 第一次启动任务调度器 2 任务主动触发调度 3 SystemTick时钟触发调度 4 因为中断而
  • Centos7命令行安装图形用户界面

    安装完成Centos7后 xff0c 重启后发现是命令行界面 xff0c 于是就想改成图形用户界面 安装了图形用户界面的话 xff1a 1 查看系统里是否已经安装了图形用户界面 使用ctrl 43 alt 43 fx xff0c x为123
  • STM32G070 DMA+SPI+LCD显示

    SPI HandleTypeDef hspi1 DMA HandleTypeDef hdma spi1 tx 描述 xff1a LCD的SPI引脚初始化 参数 xff1a 无 返回 xff1a 无 void LCD SPI Init voi
  • Linux 开启VNCSERVER

    尽管我们可以使用 SSH连接远程通过字符界面来操作Linux xff0c 但是对于更多熟悉图形人来说是很不方便的 xff0c 因此开启Linux的远程桌面还是很有必要的 目前有两种比较流行的方式 xff1a XDM X display ma
  • Ubuntu 代号引发的“崩溃”

    写这篇文章主要是因为在前几天 xff0c 因为向来不关心ubuntu代号的我而引发的一次 崩溃 xff08 人崩溃 xff09 xff0c 正如我们所知Ubuntu 每半年都会更新一个版本 xff0c 每两年都会发布一个TLS xff08
  • Prometheus(二)部署Prometheus和node_exporter

    软件包列表 Prometheus安装 解压部署 rm rf prometheus 2 28 1 linux amd64 tar xvf prometheus 2 28 1 linux amd64 tar gz rm usr local pr
  • Python学习之路_day_02(编程语言介绍及变量)

    一 编程语言介绍 1 机器语言 直接用二进制编程 xff0c 直接控制硬件 xff0c 需要掌握硬件的操作细节 优点 xff1a 执行效率高 缺点 xff1a 开发效率低 2 汇编语言 xff1a 用英文标签取代二进制指令去编写程序 xff
  • 解决linux系统read only system 解决办法

    首先确认系统属于非硬盘物理坏道引起 其次确认是否有root权限 下面我要阐述一个恢复实例 xff1a 一现象 xff1a 1 没有root权限 2 由于磁盘空间满溢导致分区表损坏 xff08 非物理坏道引起 xff09 3 重启后已经无法进
  • 哈希查找效率及应用场景

    数组的特点是 xff1a 寻址容易 xff0c 插入和删除困难 xff1b 而链表的特点是 xff1a 寻址困难 xff0c 插入和删除容易 那么我们能不能综合两者的特性 xff0c 做出一种寻址容易 xff0c 插入删除也容易的数据结构
  • 四位比较器

    四位比较器 一 xff0c 实验目的 通过使用比较四位二进制判断它的相对大小 二 xff0c 实验内容 四位比较器的实验 三 xff0c 实验代码 module Comp 2 str output A gt B A lt B A eq B
  • 程序员玩游戏之三--天天爱消除非暴力脚本

    评论 xff1a 此款游戏成功在其好友排名上 好友的分数超过了你无疑会增加你的斗志 中级策略 xff1a 七手八脚多人一起点 这相当于多个CPU处理一个大任务了 xff0c 哈哈 终极策略 xff1a 自动化 机器总是比人快的多 你两个人一
  • 程序员玩游戏之四--娱网棋牌大连打滚子记牌器

    话说大连人都爱打滚子 xff0c 所以本人就做了一个打滚子记牌器 基本原理同 程序员玩游戏之一 自动对对碰 xff0c 故此处不再赘述 xff0c 只留下一张截图吧 代码请见资源地址 xff1a http download csdn net
  • 为SIGSEGV设置handler有用吗?

    背景 最近几天看到先辈们30年前留下了一块代码 xff0c 为SIGSEGV设置了handler xff0c 所以心中有了两个疑问 xff1a 为SIGSEGV设置handler有没有用 xff1f 能否跳过引起崩溃的那一句指令 xff1f
  • GDB调试技巧实战--为优化版release版本的函数寻找参数值

    在上一篇 GDB调试技巧实战 为release版本的函数寻找参数值 中 xff0c 我们探讨了一种为函数找参数的办法 xff0c 但是 xff0c 那是最理想的情况 编译时没有使用 fomit frame pointer 编译时没有开启优化
  • 通过实例了解uprobe及其对性能的影响

    前言 uprobe是用户空间探针的意思 xff0c 可以用来给用户程序的任何地方下探针 xff0c 不仅仅是函数粒度层级的 所以异常灵活 如果不熟悉ftrace uprobe 可参考以下文档 xff1a https www kernel o