代码编织梦想

前言

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)

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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zhaiminlove/article/details/128762694

linux 中的 dtrace :bpf 进入 4.9 内核_weixin_34342207的博客-爱代码爱编程

随着 BPF 追踪系统(基于时间采样)最后一个主要功能被合并至 Linux 4.9-rc1 版本的内核中,现在 Linux 内核拥有类似 DTrace 的原生追踪功能。DTrace 是 Solaris 系统中的高级追踪器。对于长期使用 DTrace 的用户和专家,这将是一个振奋人心的里程碑!现在在 Linux 系统上,你可以在生产环境中使用安全的、低

深入理解 linux ebpf:一个完整阅读清单(转载)_宋宝华的博客-爱代码爱编程

linux eBPF是3.17内核开始引入的一个全新设计,代码目录主要在kernel/bpf 下,它的全称是 extended BPF(eBPF), 目前关于eBPF的资料还比较乱,很难得看到一篇对ebpf总结的那么全的文章

【转】bpf详解-爱代码爱编程

原文地址:https://linux.cn/article-9507-1.html 什么是 BPF? BPF,及伯克利包过滤器Berkeley Packet Filter,最初构想提出于 1992 年,其目的是为了提供一种过滤包的方法,并且要避免从内核空间到用户空间的无用的数据包复制行为。它最初是由从用户空间注入到内核的一个简单的字节码构成,它在那个位

bcc Reference Guide 中文翻译-爱代码爱编程

bcc Reference Guide 文章目录 bcc Reference GuideBPF CEvents & Arguments1、kprobes2、kretprobes3、Tracepoint4、uprobes5、uretprobes6、USDT probes7、Raw Tracepoints8、system call trace

【kernel doc】【trace】ftrace - Function Tracer-爱代码爱编程

原文链接: Function Tracer 介绍   Ftrace是一个内部的tracer,用以帮助系统开发者和设计者来知道内核正在做什么。它可以用来调试或者分析用户空间的延迟和性能问题。   尽管 ftrace 通常只被认为是函数tracer,但它实际上是多个跟踪实用程序的框架。   在检测中断禁用和启用之间,以及抢占和从任务被唤醒到任务实际调度的时

“土法”排查与修复一个 Linux 内核 Bug-爱代码爱编程

最近有幸捡了个漏,修了个有13 年历史的 Linux 内核 bug,相关修复已经合并到 Linux 主线版本 5.14-rc3。发现新的 Linux 内核 bug 的机会不总是有,在客户现场进行调试和诊断往往会受到各种限制以致于不得不使用一些“土法”,因此写个博客日志一下,以供备忘与交流。 我们在一个用户环境中首次发现了这个bug:用户使用我们的产品后,发

【译】eBPF 概述:第 5 部分:跟踪用户进程-爱代码爱编程

本系列导航: eBPF 概述:第 1 部分:介绍eBPF 概述:第 2 部分:机器和字节码eBPF 概述:第 3 部分:软件开发生态eBPF概述:第 4 部分:在嵌入式系统运行SeBPF概述:第 5 部分:追踪用户进程原文地址:https://www.collabora.com/news-and-blog/blog/2019/05/14/an-ebpf-

Ftrace debugfs接口详细使用说明-爱代码爱编程

文章目录 Ftrace debugfs接口详细使用说明1. 概述2. 实现原理及代码3. Function 跟踪3.1 Trace文件系统3.2 Tracers3.3 Error conditions3.4 tracer使用的示例3.4.1 Output format3.4.2 Latency trace format3.4.3 trace opt

《vim 实用技巧必知必会》学习笔记day11-爱代码爱编程

如果存在一个或多个匹配项,Vim 会跳转到第一个匹配的位置。下面我列举一下其他相关的常用命令: :tnext(缩写 :tn)跳转到下一个标签匹配位置:tNext(缩写 :tN)或 :tprevious(缩写 :tp)跳转到上一个标签匹配位置:tfirst 或 :trewind 跳转到第一个标签匹配位置:tlast 跳转到最后一个标签匹配位置:tselec

coolify系列02-从0到1超详细手把手教你上手coolify-爱代码爱编程

重启 如果由于某种原因,你的实例崩溃了,你可以用下面的命令重新启动它: wget -q https://get.coollabs.io/coolify/install.sh \ -O install.sh; sudo b

《真象还原》读书笔记——第二章 编写 mbr 主引导记录-爱代码爱编程

2.1 计算机的启动过程 开机后运行的第一个程序是 BIOS 。 BIOS 搬运 MBR 并 跳转运行 MBR… 2.2 软件接力第一棒 BIOS 全名 基本输入输出系统。 2.2.1 实模式下的 1MB 内存分布

openwrt软路由空间扩容-爱代码爱编程

文章目录 预备知识OpenWrt系统固件分类EXT4固件扩容方式新建分区扩容操作步骤 直接扩容操作步骤 SQUASHFS固件扩容方式新建分区扩容直接扩容 EFI引导固件的额外操作参考

使用 patchelf 修改 elf 文件的动态链接器路径-爱代码爱编程

最近尝试自己编写链接脚本生成可执行程序,但遇到了一些问题,生成的可执行程序在运行时报错,后来发现是因为生成的可执行程序中动态链接器的路径有问题,通过使用patchelf工具修改可执行程序的动态链接器路径后,程序运行正常。下面

《bpf( 伯克利数据包过滤器 ) performance tools》 第二章 技术背景_bpf performance tools-爱代码爱编程

MarkDown编辑语法 第1章简要介绍了BPF性能工具使用到的各种技术。本章会更加深入地阐述这些技术,涵盖了历史、接口、内部运作方式,以及如何使用BPF工具。本章的技术深度为整本书之最,为了篇幅尽量简短,这里假定你已经具