uprobe 实战

news2024/11/16 18:09:33

观测数据源

目前按照我的理解,和trace相关的常用数据源–探针 大致分为四类。
内核
Trace point
kprobe
用户程序
USDT
uprobe

在用户程序中,USDT是所谓的静态Tracepoint。和内核代码中的Trace point类似。实现方式是在代码开发时,使用USDT的库和头文件。在代码中埋点。在运行时可以通过一些手段使能这些Tracepoint。而uprobe,是在kprobe的基础上沿袭下来。属于是动态探针。实现方式需要依托内核支持。在执行到此指令前或者后,进行代码注入。实现trace。

内核支持

引用参考文献


            Uprobe-tracer: Uprobe-based Event Tracing
            =========================================

           Documentation written by Srikar Dronamraju


Overview
--------
Uprobe based trace events are similar to kprobe based trace events.
To enable this feature, build your kernel with CONFIG_UPROBE_EVENTS=y.

Similar to the kprobe-event tracer, this doesn't need to be activated via
current_tracer. Instead of that, add probe points via
/sys/kernel/debug/tracing/uprobe_events, and enable it via
/sys/kernel/debug/tracing/events/uprobes/<EVENT>/enabled.

However unlike kprobe-event tracer, the uprobe event interface expects the
user to calculate the offset of the probepoint in the object.

6.6. Dynamic Tracing
For kernel analysis, I'm using CONFIG_KPROBES=y and CONFIG_KPROBE_EVENTS=y, to enable kernel dynamic tracing, and CONFIG_FRAME_POINTER=y, for frame pointer-based kernel stacks. For user-level analysis, CONFIG_UPROBES=y and CONFIG_UPROBE_EVENTS=y, for user-level dynamic tracing.

Kernel Config: 3.8.6
Here are some kernel CONFIG options for perf_events functionality:
# for perf_events:
CONFIG_PERF_EVENTS=y
# for stack traces:
CONFIG_FRAME_POINTER=y
# kernel symbols:
CONFIG_KALLSYMS=y
# tracepoints:
CONFIG_TRACEPOINTS=y
# kernel function trace:
CONFIG_FTRACE=y
# kernel-level dynamic tracing:
CONFIG_KPROBES=y
CONFIG_KPROBE_EVENTS=y
# user-level dynamic tracing:
CONFIG_UPROBES=y
CONFIG_UPROBE_EVENTS=y
# full kernel debug info:
CONFIG_DEBUG_INFO=y
# kernel lock tracing:
CONFIG_LOCKDEP=y
# kernel lock tracing:
CONFIG_LOCK_STAT=y
# kernel dynamic tracepoint variables:
CONFIG_DEBUG_INFO=y
You may need to build your own kernel to enable these. The exact set you need depends on your needs and kernel version, and list is likely to grow as new features are added to perf_events.

测试代码


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

static void
print_curr_state_one(void)
{
    printf("This is the print current state one function\n");
}


static void
print_curr_state_two(void)
{
    printf("This is the print current state two function\n");
}


int main() {
    while(1) {
        print_curr_state_one();
        sleep(1);
        print_curr_state_two();
    }
}

通过 perf 使用 uprobe

uprobe作为数据源,可以通过多种途径使用。不同的工具实现的功能可能有所差别。

# perf probe

 Usage: perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]
    or: perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]
    or: perf probe [<options>] --del '[GROUP:]EVENT' ...
    or: perf probe --list [GROUP:]EVENT ...
    or: perf probe [<options>] --funcs

    -a, --add <[EVENT=]FUNC[+OFF|%return] [[NAME=]ARG ...]>
                          probe point definition, where
                GROUP:  Group name (optional)
                EVENT:  Event name
                FUNC:   Function name
                OFF:    Offset from function entry (in byte)
                %return:        Put the probe at function return
                ARG:    Probe argument (kprobe-tracer argument format.)

    -D, --definition <[EVENT=]FUNC[+OFF|%return] [[NAME=]ARG ...]>
                          Show trace event definition of given traceevent for k/uprobe_events.
    -d, --del <[GROUP:]EVENT>
                          delete a probe event.
    -f, --force           forcibly add events with existing name
    -F, --funcs <[FILTER]>
                          Show potential probe-able functions.
    -k, --vmlinux <file>  vmlinux pathname
                          (not built-in because NO_DWARF=1)
    -L, --line <FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]>
                          Show source code lines.
                          (not built-in because NO_DWARF=1)
    -l, --list <[GROUP:]EVENT>
                          list up probe events
    -m, --module <modname|path>
                          target module name (for online) or path (for offline)
    -n, --dry-run         dry run
    -q, --quiet           be quiet (do not show any messages)
    -s, --source <directory>
                          path to kernel source
                          (not built-in because NO_DWARF=1)
    -V, --vars <FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT>
                          Show accessible variables on PROBEDEF
                          (not built-in because NO_DWARF=1)
    -v, --verbose         be more verbose (show parsed arguments, etc)
    -x, --exec <executable|path>
                          target executable name or path
        --cache           Manipulate probe cache
        --demangle        Enable symbol demangling
        --demangle-kernel
                          Enable kernel symbol demangling
        --externs         Show external variables too (with --vars only)
                          (not built-in because NO_DWARF=1)
        --filter <[!]FILTER>
                          Set a filter (with --vars/funcs only)
                        (default: "!__k???tab_* & !__crc_*" for --vars,
                         "!_*" for --funcs)
        --max-probes <n>  Set how many probe points can be found for a probe.
        --no-inlines      Don't search inlined functions
                          (not built-in because NO_DWARF=1)
        --range           Show variables location range in scope (with --vars only)
                          (not built-in because NO_DWARF=1)
        --symfs <directory>
                          Look for files with symbols relative to this directory
        --target-ns <pid>
                          target pid for namespace contexts

其中这个(not built-in because NO_DWARF=1)很有意思,这是否意味着,不能通过debug info 去获取局部变量?也不能通过行号加probe?

通过搜索perf的源码,发现似乎是编译perf的时候没有开启。

那么我需要自己编译perf? 然后移植?

查看可用的probe并添加记录

查看可以插入探针的函数

# perf probe -x a.out -F
abort@plt
call_weak_fn
completed.8444
data_start
deregister_tm_clones
frame_dummy
main
print_curr_state_one
print_curr_state_two
puts@plt
register_tm_clones
sleep@plt

通过-x指定执行文件。-F显示可能被用来插入探针的函数。

插入探针

# perf probe -x a.out -a print_curr_state_one 
Added new event:
  probe_a:print_curr_state_one (on print_curr_state_one in /home/root/test_uprobe/a.out)

You can now use it in all perf tools, such as:

        perf record -e probe_a:print_curr_state_one -aR sleep 1

查看插入的探针

# perf probe -l
  probe_a:print_curr_state_one (on print_curr_state_one in /home/root/test_uprobe/a.out)
  probe_a:print_curr_state_two (on print_curr_state_two in /home/root/test_uprobe/a.out)

开启记录新增的探针

# perf record -e probe_a:* -a
Couldn't synthesize bpf events.
^C[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.159 MB perf.data (24 samples) ]

查看记录的结果

# perf script
           a.out  3198 [000] 15137.303918: probe_a:print_curr_state_two: (40060c)
           a.out  3198 [000] 15137.304015: probe_a:print_curr_state_one: (4005ec)
           a.out  3198 [000] 15138.304117: probe_a:print_curr_state_two: (40060c)
           a.out  3198 [000] 15138.304153: probe_a:print_curr_state_one: (4005ec)
           a.out  3198 [000] 15139.304244: probe_a:print_curr_state_two: (40060c)
           a.out  3198 [000] 15139.304278: probe_a:print_curr_state_one: (4005ec)
           a.out  3198 [000] 15140.304378: probe_a:print_curr_state_two: (40060c)
           a.out  3198 [000] 15140.304415: probe_a:print_curr_state_one: (4005ec)
           a.out  3198 [001] 15141.304575: probe_a:print_curr_state_two: (40060c)
           a.out  3198 [001] 15141.304614: probe_a:print_curr_state_one: (4005ec)
           a.out  3198 [001] 15142.304696: probe_a:print_curr_state_two: (40060c)
           a.out  3198 [001] 15142.304729: probe_a:print_curr_state_one: (4005ec)
           a.out  3198 [001] 15143.304829: probe_a:print_curr_state_two: (40060c)
           a.out  3198 [001] 15143.304866: probe_a:print_curr_state_one: (4005ec)
           a.out  3198 [001] 15144.304969: probe_a:print_curr_state_two: (40060c)
           a.out  3198 [001] 15144.305004: probe_a:print_curr_state_one: (4005ec)
           a.out  3198 [001] 15145.305104: probe_a:print_curr_state_two: (40060c)
           a.out  3198 [001] 15145.305137: probe_a:print_curr_state_one: (4005ec)
           a.out  3198 [000] 15146.305243: probe_a:print_curr_state_two: (40060c)
           a.out  3198 [000] 15146.305279: probe_a:print_curr_state_one: (4005ec)
           a.out  3198 [000] 15147.305373: probe_a:print_curr_state_two: (40060c)
           a.out  3198 [000] 15147.305406: probe_a:print_curr_state_one: (4005ec)
           a.out  3198 [000] 15148.305499: probe_a:print_curr_state_two: (40060c)
           a.out  3198 [000] 15148.305533: probe_a:print_curr_state_one: (4005ec)

删去不再使用的probe

# perf probe -d probe_a:*

在LTTng中使用

Create or enable a recording event rule to match Linux kernel events created from a dynamic instrumentation point:
lttng [GENERAL OPTIONS] enable-event --kernel
      (--probe=LOC | --function=LOC | --userspace-probe=LOC) RECORDNAME
      [--session=SESSION] [--channel=CHANNEL]
# lttng enable-event --kernel --userspace-probe=./a.out:print_curr_state_one FUNC_A
kernel event FUNC_A created in channel channel0

# lttng enable-event --kernel --userspace-probe=./a.out:print_curr_state_two FUNC_B
kernel event FUNC_B created in channel channel0

在设定上,uprobe仍然属于是内核提供 所以还是内核的trace事件。

在LTTng中,好像没有找到关于uretprobe的内容。也没有发现类似可以按照行或者抓取局部变量的内容。可能是LTTng没有做。

之后正常使能所有内核Trace事件。
然后记录log。进行分析。

在这里插入图片描述

之后可以在可视化工具中查看进程调度,以及进程运行的细节。

在LTTng的log中,没有更多的细节,甚至函数名都没有保留,只有在注册probe的时候自定义的命名。

可能他们推荐大家使用LTTng-UST的USDT吧。

下一步工作

目前实际上是没有实现更细致的观测。例如perf prob -V /L这种。
可能需要重新编译移植perf.或者寻找其他的数据采集和分析工具。

或者有其他的工具可以使用。我甚至想尝试bpf了。但这意味着重新编译内核打开bpf的支持。


参考文献

  • Linux K/Uprobe 使用指南 · GitBook (t-head.cn)
  • Linux uprobe: User-Level Dynamic Tracing (brendangregg.com)
  • https://www.kernel.org/doc/Documentation/trace/uprobetracer.txt
  • Linux perf Examples (brendangregg.com)
  • lttng-enable-event(1) [v2.13] — LTTng

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/350432.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Visual Studio开启clang-tidy代码检查

在CLion中有针对C的静态代码检查工具clang-tidy&#xff0c;感觉非常好用&#xff0c;能养成好的编码习惯&#xff0c;后来写Qt转入了VS平台&#xff0c;想要继续使用功能一致的clang-tidy体验&#xff0c;所以研究出来在VS中开启clang-tidy的方法。 版本&#xff1a;Visual S…

XML 基础知识 XXE 漏洞原理解析及实验(基础篇)

XML 介绍 XXE全称XML外部实体注入&#xff0c;所以在介绍XXE漏洞之前&#xff0c;先来说一说什么是XML以及为什么使用XML进而再介绍一下XML的结构。 XML全称 可拓展标记语言&#xff0c;与HTML相互配合后&#xff1a; HMTL用来显示数据 HTML的焦点在于数据的外观&#xff08;…

双网卡(有线和wifi)同时连接内网和外网

双网卡&#xff08;有线和wifi&#xff09;同时连接内网和外网 Win10技巧&#xff1a;如何修改有线/WiFi网络优先级&#xff1a;https://www.ithome.com/html/win10/253612.htm双网卡实现两个网络的自由访问&#xff1a;https://blog.51cto.com/ghostlan/1299090Linux服务器安…

【Linux】网络编程 - 基础概念

目录 一.OSI七层模型vsTCP/IP五层模型 1.一些周边概念 2.OSI七层模型 3.TCP/IP五层模型 4.网络传输流程图 二.什么是MAC地址 三.什么是IP/IP地址 1.什么是IP 2.什么是IP地址 四.什么是端口号 一.OSI七层模型vsTCP/IP五层模型 1.一些周边概念 局域网vs广域网 网络互…

LeetCode——2341. 数组能形成多少数对

一、题目 给你一个下标从 0 开始的整数数组 nums 。在一步操作中&#xff0c;你可以执行以下步骤&#xff1a; 从 nums 选出 两个 相等的 整数 从 nums 中移除这两个整数&#xff0c;形成一个 数对 请你在 nums 上多次执行此操作直到无法继续执行。 返回一个下标从 0 开始、…

亚马逊云科技重磅发布《亚马逊云科技汽车行业解决方案》

当今&#xff0c;随着万物智联、云计算等领域的高速发展&#xff0c;创新智能网联汽车和车路协同技术正在成为车企加速发展的关键途径&#xff0c;推动着汽车产品从出行代步工具向着“超级智能移动终端”快速转变。挑战无处不在&#xff0c;如何抢先预判&#xff1f;随着近年来…

31-Golang中的二维数组

二维数组的使用方式 使用方式一&#xff1a;先声明/定义再赋值 1.语法&#xff1a;var数组名 [大小] [大小]类型2.比如&#xff1a;var arr [2] [3]int,再赋值 package main import ("fmt" )func main() {//定义/声明数组var arr [4][6]int//赋初值arr[1][2] 1ar…

volatile,内存屏障

volatile的特性可见性: 对于其他线程是可见,假设线程1修改了volatile修饰的变量,那么线程2是可见的,并且是线程安全的重排序: 由于CPU执行的时候,指令在后面的会先执行,在指令层级的时候我们晓得volatile的特性后,我们就要去volatile是如何实现的,这个很重要&#xff01;&#…

金三银四面试必备的软件测试八股文,看完拿捏面试官

1、问&#xff1a;你在测试中发现了一个 bug&#xff0c;但是开发经理认为这不是一个 bug&#xff0c;你应该怎样解决&#xff1f;首先&#xff0c;将问题提交到缺陷管理库里面进行备案。然后&#xff0c;要获取判断的依据和标准&#xff1a; 根据需求说明书、产品说明、设计文…

蓝屏怎么办电脑蓝屏怎么办?蓝屏问题详细分析

蓝屏怎么办电脑蓝屏怎么办&#xff1f;最近很多小伙伴在咨询这个问题&#xff0c;其实电脑蓝屏了进不去&#xff0c;我们可以重新启动电脑&#xff0c;如果进入系统后还是直接蓝屏&#xff0c;那么你可以尝试一下&#xff0c;关机重启&#xff0c;然后在进入系统的时候&#xf…

路肩石水渠机在施工公路项目中工艺特点的匹配

新建公路路肩项目在目前公路项目中的技术手段和实现方式,大多数依靠机械设备来机械来进行,还有一部分通过人工传统的预制作业和安装模式来进行,两种工艺特点的对比来说对于补充完善建设手段和效果实现有很重要的意义. 其中采用了机械设备进行一次成型制作的过程,按照设计需求匹…

useRef 几种使用场景

图修改自 dev.to Demystifying React Hooks: useRef useRef神奇的地方除了可以在不重新渲染的状态下更有价值,也可以直接获取D加粗样式OM 进入而控制DOM的行为 Ref 有什么用? useRef返回一个可变的 ref 对象,其 .current 属性被初始化为传递的参数 ( initialValue)。返回…

常用vim命令和vim基本使用及Linux用户的管理,用户和组相关文件

常用vim命令和vim基本使用及Linux用户的管理&#xff0c;用户和组相关文件1. vim 的基本介绍和使用1.1 vim的三种模式1.2 常用vim命令【小白】1.3 Vim键盘图&#xff1a;2. Linux用户管理2.1 添加用户2.2 删除用户2.3 修改账号3. Linux系统用户组的管理4. 用户和组相关文件4.1 …

RuoYi-Vue部署(Nginx+Tomcat)

环境搭建RuoYi-Vue搭建、Linux安装Nginx、Linux安装JDK8、Linux安装MySql8、Linux安装Redis、Linux安装Tomcat9前端打包 1.ruoyi-ui鼠标右键-->打开于终端2.安装依赖&#xff1a;npm install --registryhttps://registry.npm.taobao.org-->node_modules3.编译打包&#x…

中国天气——西风带环流和寒潮

中国天气——西风带环流和寒潮 一. 西风环流概述 1. 概念 西风带&#xff1a;中高纬度地区平均水平环流在对流层盛行西风&#xff0c;称之为西风带西风带波动&#xff1a;西风带围绕极涡沿纬圈运动&#xff0c;平均而言表现为冬季三槽三脊&#xff0c;夏季四槽四脊&#xff…

盘点八个简单易上手的前端低代码框架项目

低代码近年来做为前端市场上火爆到不行的项目&#xff0c;其热度也是长久不衰&#xff0c;本文就为大家盘点了8个简单易上手的前端低代码框架项目&#xff0c;并各自都附上了体验链接&#xff0c;欢迎大家前往体验哦&#xff5e;&#xff5e;&#xff5e;&#xff5e; 1. Appsm…

elementUI-plus虚拟表el-table-v2 checkbox删除后,下一个复选框又被选中且无法删除

虚拟表种设置了checkbox&#xff0c;但是删除时&#xff0c;发现删除后&#xff0c;下一个checkbox自动被选中&#xff0c;且删除时&#xff0c;报错找不到id没有设置row-key每行的 key 值&#xff0c;如果不提供&#xff0c;将使用索引 index 代替2.row-key值设置成什么值&…

openwrt开发板与ubuntu nfs挂载

1.ubuntu需要安装nfs服务 sudo apt-get install nfs-common nfs-kernel-server2.修改 /etc/exports文件&#xff1a; /home/test *(rw,nohide,insecure,no_subtree_check,async,no_root_squash) 前面是挂载的目录&#xff0c;后边是相应权限 rw&#xff1a;读写 insecure&am…

Is ChatGPT a general-purpose natural language processing task solver?

声明&#xff1a;平时看些文章做些笔记分享出来&#xff0c;文章中难免存在错误的地方&#xff0c;还望大家海涵。搜集一些资料&#xff0c;方便查阅学习&#xff1a;http://yqli.tech/page/speech.html。语音合成领域论文列表请访问http://yqli.tech/page/tts_paper.html&…

Android常用9种自动化测试框架对比,Appium有哪些优势?

随着移动终端的普及&#xff0c;手机应用越来越多&#xff0c;也越来越重要。 App的回归测试用例数量也越来越多&#xff0c;全量回归也越来越消耗时间。移动 APP自动化测试 的难点移动 APP的UI自动化测试长久以来一直是一个难点&#xff0c;难点在于UI的”变”, 变化导致自动化…