Kprobes events
写一个包含 Kprobes 注册/注销的模块稍微有点复杂, 使用 Kprobes events 就像对简单一些. 它们类似基于 tracepoint 的events, 但是使用 Kprobes 实现的, 可以动态的添加删除.
概念
- 要使用此功能, 编译 Kernel的时候, 必须
CONFIG_KPROBE_EVENTS=y.
; - 类似其它 event tracer, 不需要通过
current_tracer
激活; - 通过
/sys/kernel/tracing/kprobe_events
或/sys/kernel/tracing/dynamic_events
添加 Kprobes events; - 通过
/sys/kernel/tracing/events/kprobes/<EVENT>/enable
开启 events; /sys/kernel/tracing/kprobe_profile
统计 hit 多少, miss 多少.
一个简单的例子
下面的例子使用探测 uptime_proc_show
函数, 建立以 trace_sample
为event 名字的 Kprobes event.
可以看到动态添加这个 Kprobes events 之后, 对应的文件夹被建立了.
并且不需要设置 current_tracer
.
# 保证环境正确
$ echo 0 > /sys/kernel/tracing/tracing_on
$ echo "" > /sys/kernel/tracing/trace
# 设置 Kprobes events
$ echo "p:trace_sample uptime_proc_show" > /sys/kernel/debug/tracing/kprobe_events
# 查看新生成的 Kprobes 文件夹
$ ls /sys/kernel/tracing/events/kprobes/trace_sample/
enable filter format hist id inject trigger
$ echo 1 > /sys/kernel/tracing/events/kprobes/trace_sample/enable
# 开启 probe
$ echo 1 > /sys/kernel/tracing/tracing_on
# 执行包含该函数的命令
$ uptime
# 查看结果
$ cat /sys/kernel/tracing/trace
# tracer: nop
#
# entries-in-buffer/entries-written: 1/1 #P:8
#
# _-----=> irqs-off
# / _----=> need-resched
# | / _---=> hardirq/softirq
# || / _--=> preempt-depth
# ||| / _-=> migrate-disable
# |||| / delay
# TASK-PID CPU# ||||| TIMESTAMP FUNCTION
# | | | ||||| | |
uptime-40063 [007] ..... 67233.823241: trace_sample: (uptime_proc_show+0x0/0x1d0)
# 清理
$ echo 0 > /sys/kernel/tracing/tracing_on
$ echo 0 > /sys/kernel/tracing/events/kprobes/trace_sample/enable
$ echo -:trace_sample > /sys/kernel/debug/tracing/kprobe_events
查看 ksys_read
系统调用返回值的例子
下面的内容都放到 test.sh 文件里, 然后执行 sh test.sh
echo $$
# 准备
echo 0 > /sys/kernel/tracing/tracing_on
echo "" > /sys/kernel/tracing/trace
# 注册事件
echo "r:myreturnprobe ksys_read $retval" > /sys/kernel/debug/tracing/kprobe_events
echo $$ > /sys/kernel/debug/tracing/set_event_pid
#开启
echo 1 > /sys/kernel/tracing/events/kprobes/myreturnprobe/enable
echo 1 > /sys/kernel/tracing/tracing_on
# 等一会, 然后查看结果, 命令替换同一个进程读
sleep 5
output=$(cat /tmp/test.sh > /dev/null)
# 关闭
echo 0 > /sys/kernel/tracing/tracing_on
# 查看结果
cat /sys/kernel/tracing/trace
# 清理
echo 0 > /sys/kernel/tracing/events/kprobes/myreturnprobe/enable
echo -:myreturnprobe > /sys/kernel/debug/tracing/kprobe_events 2>/dev/null
echo "done"
Kprobes events 格式
更多说明在这里: https://docs.kernel.org/trace/kprobetrace.html
p[:[GRP/][EVENT]] [MOD:]SYM[+offs]|MEMADDR [FETCHARGS] : Set a probe
r[MAXACTIVE][:[GRP/][EVENT]] [MOD:]SYM[+0] [FETCHARGS] : Set a return probe
p[:[GRP/][EVENT]] [MOD:]SYM[+0]%return [FETCHARGS] : Set a return probe
-:[GRP/][EVENT] : Clear a probe