uprobe 事件tracer工具是在内核3.5开发期间何入内核主线版本的,虽然uprobe已经存在很久了。uprobe是和kprobe类似的调试方法。编译内核时通过打开CONFIG_UPROBE_EVENT=y来时能该特性。和kprobe类似,使用时不需要通过current_tracer来激活,而是检测点通过/sys/kernel/debug/tracing/uprobe_events设置,通过/sys/kernel/debug/tracing/events/uprobes/<EVENT>/enabled来使能。
然而,和kprobe不同的是,使用时需要用户自己计算探测点在用户态文件中的偏移,可以通过nm等工具,这还是有点麻烦的。
可以通过/sys/kernel/debug/tracing/uprobe_profile来查看某一检测事件命中的总数和没有命中的总数。第一列是事件名称,第二列是事件命中的次数,第三列是事件miss-hits的次数。
如下定义一个新的检测事件:
echo 'p: /bin/bash:0x4245c0' > /sys/kernel/debug/tracing/uprobe_events
这样就在可执行文件/bin/bash的偏移0x4245c0处设置了检测点。
要清空所有的检测点,如下:
echo > /sys/kernel/debug/tracing/uprobe_events
下面的例子给出了获得某可执行文件符号地址的方法:
# cd /sys/kernel/debug/tracing/
# cat /proc/`pgrep bash`/maps | grep /bin/bash | grep r-xp
00400000-004e1000 r-xp 00000000 08:01 786439 /bin/bash
# objdump -T /bin/zsh | grep -w free
00000000004ab500 g DF .text 0000000000000009 Base free
0x4ab500是可执行文件/bin/zsh中哦给你free函数的偏移,可以看出/bin/bash的加载地址是0x00400000,因此设置free处为检测点的命令如下:
echo 'p /bin/bash:0x4ab500 %ip %ax' > uprobe_events
可以通过uprobe_events来查看注册的事件:
# cat uprobe_events
p:uprobes/p_bash_0x4ab500 /bin/bash:0x00000000004ab500 arg1=%ip arg2=%ax
在正确的注册后,每个检测点事件都是禁止的,要检测这个事件,需要手动去激活它:
# echo 1 > events/uprobes/enable
在程序执行了一段事件后,禁止它,然后可以查看监控到的事件:
# sleep 20
# echo 0 > events/uprobes/enable
# cat trace
# tracer: nop
#
# TASK-PID CPU# TIMESTAMP FUNCTION
# | | | | |
zsh-24842 [006] 258544.995456: p_bash_0x46420: (0x446420) arg1=446421 arg2=79
zsh-24842 [007] 258545.000270: p_bash_0x46420: (0x446420) arg1=446421 arg2=79
zsh-24842 [002] 258545.043929: p_bash_0x46420: (0x446420) arg1=446421 arg2=79
zsh-24842 [004] 258547.046129: p_bash_0x46420: (0x446420) arg1=446421 arg2=79