基于 Linux-5.15
=========================================
Uprobe-tracer:基于 Uprobe 的事件追踪
=========================================
:作者:Srikar Dronamraju
概述
----------
基于 Uprobe 的跟踪事件类似于基于 kprobe 的跟踪事件。 要启用此功能,请使用 CONFIG_UPROBE_EVENTS=y(默认使能) 构建内核。
与 kprobe-event tracer 类似,这不需要通过 current_tracer 激活。 取而代之的是,通过 /sys/kernel/debug/tracing/uprobe_events 添加探测点,并通过 /sys/kernel/debug/tracing/events/uprobes/<EVENT>/enable 启用它。
然而,与 kprobe-event tracer 不同的是,uprobe 事件接口期望用户计算对象中探测点的偏移量。
您还可以使用 /sys/kernel/debug/tracing/dynamic_events 而不是 uprobe_events。 该接口也将提供对其他动态事件的统一访问。
uprobe_tracer 说明
--------------------------
:: p[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : 设置一个 uprobe r[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : 设置return uprobe (uretprobe) p[:[GRP/]EVENT] PATH:OFFSET%return [FETCHARGS] : 设置返回 uprobe (uretprobe) //p也可以设置uretprobe ? -:[GRP/]EVENT : 清除 uprobe 或 uretprobe 事件 GRP:组名。 如果省略,则“uprobes”为默认值。 EVENT:事件名称。 如果省略,则根据 PATH+OFFSET 生成事件名称。 PATH :可执行文件或库的路径。 OFFSET : 插入的probe的偏移量。 OFFSET%return :插入return probe的偏移量。 FETCHARGS :参数。 每个probe最多可以有 128 个参数。 %REG : 获取寄存器 REG @ADDR : 获取 ADDR 处的内存(ADDR 需要在用户空间) @+OFFSET : 在 OFFSET 处获取内存(OFFSET 与 PATH 来自相同的文件) $stackN : 获取堆栈的第 N 个条目 (N >= 0) $stack : 获取堆栈地址。 $retval : 获取返回值。(\*1) $comm : 获取当前任务的comm。 +|-[u]OFFS(FETCHARG) : 在 FETCHARG +|- OFFS 地址获取内存。(\*2)(\*3) \IMM :将立即值存储到参数中。######## NAME=FETCHARG :将 NAME 设置为 FETCHARG 的参数名称。 FETCHARG:TYPE :将 TYPE 设置为 FETCHARG 的类型。 目前支持基本类型(u8/u16/u32/u64/s8/s16/s32/s64)、十六进制类型(x8/x16/x32/x64)、“string” 和 bitfield。 (\*1) 仅适用于return probe。 (\*2) 这对于获取数据结构的字段很有用。 (\*3) 与 kprobe 事件不同,“u”前缀将被忽略,因为 uprobe 事件只能访问用户空间内存。
类型
------
fetch-args 支持多种类型。 Uprobe 跟踪器将按给定类型访问内存。 前缀“s”和“u”表示这些类型分别是有符号和无符号的。 'x' 前缀表示它是无符号的。 跟踪参数以十进制(“s”和“u”)或十六进制(“x”)显示。
在没有类型转换的情况下,使用“x32”或“x64”取决于体系结构(例如,x86-32 使用 x32,而 x86-64 使用 x64)。
字符串类型是一种特殊类型,它从用户空间获取一个“null-terminated”的字符串。
Bitfield 是另一种特殊类型,它有 3 个参数,bit-width、bit-offset 和 container-size(通常为 32)。 语法是:
b<bit-width>@<bit-offset>/<container-size>
对于 $comm,默认类型是“string”; 任何其他类型均无效。
事件分析
--------------
您可以通过 /sys/kernel/debug/tracing/uprobe_profile 检查每个事件的探测命中总数。 第一列是文件名,第二列是事件名称,第三列是探测命中数。
使用示例
--------------
* 添加一个探测器作为新的 uprobe 事件,如下所示向 uprobe_events 写入新定义(在可执行文件 /bin/bash 中将 uprobe 设置为偏移量 0x4245c0):: echo 'p /bin/bash:0x4245c0' > /sys/kernel/debug/tracing/uprobe_events * 将探针添加为新的 uretprobe 事件:: echo 'r /bin/bash:0x4245c0' > /sys/kernel/debug/tracing/uprobe_events * 取消设置注册事件:: echo '-:p_bash_0x4245c0' >> /sys/kernel/debug/tracing/uprobe_events * 打印出注册的事件:: cat /sys/kernel/debug/tracing/uprobe_events * 清除所有事件:: echo > /sys/kernel/debug/tracing/uprobe_events
以下示例显示如何在探测到的文本地址转储指令指针和 %ax 寄存器。 探测 /bin/zsh:: 中的 zfree 函数:
# cd /sys/kernel/debug/tracing/ # cat /proc/`pgrep zsh`/maps | grep /bin/zsh | grep r-xp 00400000-0048a000 r-xp 00000000 08:03 130904 /bin/zsh # objdump -T /bin/zsh | grep -w zfree 0000000000446420 g DF .text 0000000000000012 Base zfree
0x46420 是 zfree 在 0x00400000 加载的对象 /bin/zsh 中的偏移量。 因此,uprobe 的命令是:
# echo 'p:zfree_entry /bin/zsh:0x46420 %ip %ax' > uprobe_events
与 uretprobe 相同的是:
# echo 'r:zfree_exit /bin/zsh:0x46420 %ip %ax' >> uprobe_events
.. note:: 用户必须明确计算对象中探测点的偏移量。
我们可以通过查看 uprobe_events 文件来查看注册的事件。
:: # cat uprobe_events p:uprobes/zfree_entry/bin/zsh:0x00046420 arg1=%ip arg2=%ax r:uprobes/zfree_exit /bin/zsh:0x00046420 arg1=%ip arg2=%ax
通过查看文件 events/uprobes/zfree_entry/format 可以看到事件的格式。
:: # cat events/uprobes/zfree_entry/format name: zfree_entry ID: 922 format: field:unsigned short common_type; offset:0; size:2; signed:0; field:unsigned char common_flags; offset:2; size:1; signed:0; field:unsigned char common_preempt_count; offset:3; size:1; signed:0; field:int common_pid; offset:4; size:4; signed:1; field:int common_padding; offset:8; size:4; signed:1; field:unsigned long __probe_ip; offset:12; size:4; signed:0; field:u32 arg1; offset:16; size:4; signed:0; field:u32 arg2; offset:20; size:4; signed:0; print fmt: "(%lx) arg1=%lx arg2=%lx", REC->__probe_ip, REC->arg1, REC->arg2
在定义之后,默认情况下每个事件都是禁用的。 要跟踪这些事件,您需要通过以下方式启用它:
# echo 1 > events/uprobes/enable
让我们开始追踪,休眠一段时间然后停止追踪。
:: # echo 1 > tracing_on # sleep 20 # echo 0 > tracing_on
此外,您可以通过以下方式禁用该事件:
# echo 0 > events/uprobes/enable
你可以通过 /sys/kernel/debug/tracing/trace 看到跟踪信息。
:: # cat trace # tracer: nop # # TASK-PID CPU# TIMESTAMP FUNCTION # | | | | | zsh-24842 [006] 258544.995456: zfree_entry: (0x446420) arg1=446420 arg2=79 zsh-24842 [007] 258545.000270: zfree_exit: (0x446540 <- 0x446420) arg1=446540 arg2=0 zsh-24842 [002] 258545.043929: zfree_entry: (0x446420) arg1=446420 arg2=79 zsh-24842 [004] 258547.046129: zfree_exit: (0x446540 <- 0x446420) arg1=446540 arg2=0
输出显示 uprobe 被 pid 24842 触发,ip 为 0x446420,ax 寄存器的内容为 79。并且 uretprobe 被触发,ip 为 0x446540,对应函数条目为 0x446420。
标签:bin,ftrace,15,trace,tracing,zfree,zsh,events,uprobe From: https://www.cnblogs.com/hellokitty2/p/17092674.html