uprobe试用小结
来源:互联网 发布:哪个cms好 编辑:程序博客网 时间:2024/05/01 14:14
项目上需要分析用户态程序的性能,开发人员一般的方式是在程序内部实现打点函数,记录当程序运行到该点的时间戳,通过比较两点之间的时间间隔来估计两点之间的时间消耗。这样一方面增加了开发的工作量,另外这些打点也会给业务带来额外性能消耗,是否有另外的方式来解决该问题呢?
前段时间在研究ftrace,发现其还有个uprobe特性,故名思意就是用户态的探针工具,今天尝试了下uprobe的使用,小结如下:
1.编写小测试程序如下:
#include <stdlib.h>
#include <stdio.h>
int count = 0;
void do_sth()
{
printf("current count = %d\n", count);
count++;
}
int main(int argc, char* argv[])
{
while(1)
{
do_sth();
}
return 0;
}
2.运行测试程序并找到需要probe的函数符号偏移量
root@X200:/home/kernel_test# objdump -t loop_print | grep do_sth
000000000040052d g F .text 000000000000002c do_sth
root@X200:/home/kernel_test# ./loop_print 1>/dev/null &
[1] 28481
root@X200:/home/kernel_test# pgrep loop_print
28481
root@X200:/home/kernel_test# man pgrep
root@X200:/home/kernel_test# cat /proc/28481/maps | grep loop_print | grep r-xp
00400000-00401000 r-xp 00000000 08:01 2885775 /home/kernel_test/loop_print
3.配置uprobe事件
echo 'p:do_sth /home/kernel_test/loop_print:0x52d %ip %ax' > /sys/kernel/debug/tracing/uprobe_events
echo 'r:do_sth_exit /home/kernel_test/loop_print:0x52d %ip %ax' >> /sys/kernel/debug/tracing/uprobe_events
uprobe的事件格式如下:
p[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : Set a uprobe
r[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : Set a return uprobe (uretprobe)
-:[GRP/]EVENT : Clear uprobe or uretprobe event
GRP : Group name. If omitted, "uprobes" is the default value.
EVENT : Event name. If omitted, the event name is generated based
on PATH+OFFSET.
PATH : Path to an executable or a library.
OFFSET : Offset where the probe is inserted.
FETCHARGS : Arguments. Each probe can have up to 128 args.
%REG : Fetch register REG
@ADDR : Fetch memory at ADDR (ADDR should be in userspace)
@+OFFSET : Fetch memory at OFFSET (OFFSET from same file as PATH)
$stackN : Fetch Nth entry of stack (N >= 0)
$stack : Fetch stack address.
$retval : Fetch return value.(*)
+|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(**)
NAME=FETCHARG : Set NAME as the argument name of FETCHARG.
FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types
(u8/u16/u32/u64/s8/s16/s32/s64), "string" and bitfield
are supported.
(*) only for return probe.
(**) this is useful for fetching a field of data structures.
其中FETCHARGS是每次执行到probe点的时候需要抓取的数据,其输出格式在/sys/kernel/debug/tracing/events/uprobes/do_sth/format中定义。
4.启动用户态探针
echo 1 > /sys/kernel/debug/tracing/events/uprobes/enable
5.查询探针结果
cat /sys/kernel/debug/tracing/trace | less
# tracer: nop
#
# entries-in-buffer/entries-written: 72053/1766702004 #P:2
#
# _-----=> irqs-off
# / _----=> need-resched
# | / _---=> hardirq/softirq
# || / _--=> preempt-depth
# ||| / delay
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |
loop_print-28481 [001] d... 5590.582582: do_sth: (0x40052d) arg1=0x40052d arg2=0x0
loop_print-28481 [001] d... 5590.582585: do_sth_exit: (0x400572 <- 0x40052d) arg1=0x400572 arg2=0x4df27b17
loop_print-28481 [001] d... 5590.582586: do_sth: (0x40052d) arg1=0x40052d arg2=0x0
loop_print-28481 [001] d... 5590.582589: do_sth_exit: (0x400572 <- 0x40052d) arg1=0x400572 arg2=0x4df27b18
loop_print-28481 [001] d... 5590.582590: do_sth: (0x40052d) arg1=0x40052d arg2=0x0
loop_print-28481 [001] d... 5590.582593: do_sth_exit: (0x400572 <- 0x40052d) arg1=0x400572 arg2=0x4df27b19
loop_print-28481 [001] d... 5590.582594: do_sth: (0x40052d) arg1=0x40052d arg2=0x0
loop_print-28481 [001] d... 5590.582597: do_sth_exit: (0x400572 <- 0x40052d) arg1=0x400572 arg2=0x4df27b1a
loop_print-28481 [001] d... 5590.582598: do_sth: (0x40052d) arg1=0x40052d arg2=0x0
loop_print-28481 [001] d... 5590.582600: do_sth_exit: (0x400572 <- 0x40052d) arg1=0x400572 arg2=0x4df27b1b
loop_print-28481 [001] d... 5590.582602: do_sth: (0x40052d) arg1=0x40052d arg2=0x0
loop_print-28481 [001] d... 5590.582604: do_sth_exit: (0x400572 <- 0x40052d) arg1=0x400572 arg2=0x4df27b1c
从以上输出可以看出进入函数和退出函数的时间轨迹。另外可以通过修改用户探针命中时指定的行为FETCHARGS来获取更多信息,比如观测全局变量变化等。
后注:
尝试了下uprobe的事件是否能和内核事件同时启用,发现启用一个另一个会自动关闭,因此无法看到进程包含核心态及用户态整体运行时间轨迹。
- uprobe试用小结
- ubuntu试用小结
- py2exe试用小结
- Win8 Beta试用小结
- servlet小结~面试用
- proGuard试用小结
- 试用Tinker小结
- Text Speech Engine试用小结
- python操纵sqlite试用小结
- SQL SERVER 2005 BCP功能试用小结
- Android最快的模拟器Genymotion试用小结
- SQL SERVER 2005 BCP功能试用小结
- 试用
- 试用
- 试用
- 试用
- 试用
- 试用
- [leetcode] 400. Nth Digit
- 文件IO---lseek、fcntl函数
- 趣写算法系列之--匈牙利算法
- 判断字符串中的括号是否成对出现
- equals方法与hashcode方法
- uprobe试用小结
- 系统命令注入的介绍与代码防御
- shell脚本调用java jar包 的问题总结
- 数据库索引
- 分享一道有意思的HTML题
- Clojure 学习入门(3)- 数字类型
- 拒绝从入门到放弃_《Python 核心编程 (第二版)》必读目录
- Android Studio 问题记录-全部java文件全部报错,却可以运行
- SQL符合函数查询