通过实例了解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及其对性能的影响 的相关文章

随机推荐

  • Linux X-Window Error: Can‘t open display: :0

    问题过程描述 许多经常部署Oracle数据的管理员经常需要对数据库软件进行部署 xff0c 但大多数都是通过远程部署的方式进行部署 xff0c 使用远程部署有两种方式 xff0c 一种是通过脚本部署 xff0c 另一种就是通过图形化进行部署
  • maven打包生成war跳过单元测试

    maven将项目打包成war包的命令是 mvn install 或mvn package 每次生成war包时会进行所以的单元测试 xff0c 如果想跳过单元测试直接生成war包有以下3种方式 方法1 xff1a 在pom xml中加入如下代
  • 程序员每天工作多少个小时_程序员每天实际工作几个小时?

    程序员每天工作多少个小时 您如何看待 xff0c 程序员每天实际工作多长时间 xff1f 大多数人会说答案是8到9个小时 有人说他们每天工作12个小时或更长时间 尽管这是正确的 xff0c 但它并不是大多数程序员实际工作的数量 xff0c
  • ubuntu 显示缺少库文件 libcom_err.so.2 解决办法

    运行任何代码都显示 xff1a error while loading shared libraries libcom err so 2 cannot open shared object file No such file or dire
  • 记CVTE第一次面试

    首先说明一下博主是一个大三的学生 xff0c 专业计算机科学与技术 xff0c 主学的方向是Web后台开发 xff0c 主语言是Java 前几天看到CVTE有校园招聘实习生 xff0c 就报名参加了 xff0c 做了CVTE的笔试题 xff
  • Java Socket 编程那些事(1)

    前言 最近在准备面试和笔试的一些东西 xff0c 回去翻看了Java关于IO的基础 xff0c 发现很多基础还是没有记牢固 xff0c 现在回头重新学习 xff0c 就从socket通讯开始吧 xff0c 虽然说现在企业很少直接编写sock
  • Redis集群的原理和搭建

    前言 Redis 是我们目前大规模使用的缓存中间件 xff0c 由于它强大高效而又便捷的功能 xff0c 得到了广泛的使用 单节点的Redis已经就达到了很高的性能 xff0c 为了提高可用性我们可以使用Redis集群 本文参考了Rdis的
  • Java多线程爬虫爬取京东商品信息

    前言 网络爬虫 xff0c 是一种按照一定的规则 xff0c 自动地抓取万维网信息的程序或者脚本 爬虫可以通过模拟浏览器访问网页 xff0c 从而获取数据 xff0c 一般网页里会有很多个URL 爬虫可以访问这些URL到达其他网页 xff0
  • 关于js中的“Uncaught SyntaxError: Unexpected token

    我在js中为一个已经定义的数组重新定义新的一个维度的数组时 xff0c 调试器这样报错 只说结果 xff1a 肯定是在给已经定义的数组中的元素重新定义下一维度时 xff0c 多在前面加了一个 var 就像下面的这样 xff1a var gr
  • 学成在线--day03 CMS页面管理开发

    学成在线 第3天 讲义 CMS页面管理开发 1 自定义条件 1 1 需求分析 在页面输入查询条件 xff0c 查询符合条件的页面信息 查询条件如下 xff1a 站点Id xff1a 精确匹配 模板Id xff1a 精确匹配 页面别名 xff
  • Ubuntu下安装Inode后双击InodeClient无反映解决方法

    由于比较喜好linux编程环境 xff0c 所以准本一直使用linux 学校无线有时有有时没很不爽 xff0c 所以准本安装Inode xff0c 但是安装完Inode后双击是一直没反映 最后求助万能的百度 xff0c 谁知道百度的搜索不得
  • 使用GitHub托管网站,自定义域名

    1 如何使用GitHub托管 官网链接 xff1a 点击跳转 官网首页就有详细的搭建步骤 xff0c 总共5步便可搭建成功 访问 github用户名 github io 便可看到自己的网站 2 自定义域名的方法 1 申请一个域名 xff0c
  • ElasticsearchRestTemplate 基本使用

    随着数据量的增加和数据结构的复杂化 xff0c 传统的关系型数据库已经不能满足用户的需求 xff0c 而搜索引擎则成为了一种更加高效 可扩展的数据检索方案 而 Elasticsearch 则是一个流行的搜索引擎 xff0c 在 Java 生
  • Navcat无法连接mysql报错1449

    把mysql从5升级成8后第二次连接mysql就报错1449 不清楚什么原因 xff0c 反正肯定是升级数据库之后mysql用户被动了 xff0c 看了很多博客都没有用 xff0c 什么在navcat里新建用户 xff0c 数据库都连不上怎
  • Kafka —— java实现一生产者多消费者实例

    架构图 xff1a xff08 网图 xff0c 很通俗易懂了 xff0c 就不自己画了 xff0c 这里实现的是一个Producer 两个Consumer xff09 前提 xff1a 已经开启zookeeper 和kafka xff0c
  • 程序员玩游戏之三--天天爱消除非暴力脚本

    评论 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