perf probe的使用方法
perf probe具有多个运行选项。这里将按照实际添加追踪事件、使用并删除的步骤来介绍该命令的使用方法。
首先,需要确认用来定义追踪事件的源代码。perf probe具有显示源代码以及显示源代码的哪一行可以插入事件的功能。
[~]#perf probe—line vfs_symlink
<vfs_symlink:0>
0 int vfs_symlink(struct inodedir, struct dentrydentry,
const char*oldname)
1{
2 int error=may_create(dir, dentry);
4 if(error)
return error;
7 if(!dir->i_op->symlink)
8 return-EPERM;
10 error=security_inode_symlink(dir, dentry, oldname);
11 if(error)
return error;
14 error=dir->i_op->symlink(dir, dentry, oldname);
15 if(!error)
16 fsnotify_create(dir, dentry);
return error;
18}
SYSCALL_DEFINE3(symlinkat, const char__user*,oldname,
int, newdfd, const char__user*,newname)
根据不同的内核构建环境和perf tools的版本(即内核版本),有时会出现找不到源代码路径的错误。这时应当先移动到内核源代码解压缩到的目录再尝试执行。
通过perf probe的—line选项可以知道指定为参数的函数和文件的源代码,以及是否能向各自的行添加事件。从输出结果可以看出,有些行的最前面有编号,有些行没有编号。前面有编号的行可以添加追踪事件。在C语言中,空行等无意义的行在编译时会消失,因此不能向这些地方添加追踪事件。调试信息记录了与进行相关处理的行相对应的地址,因此perf probe可以对其进行分析并找出可以指定的行。
另外,从perf probe的—var选项可以看出指定为参数的行可以访问哪个变量。使用编译器的优化选项时,有的变量一旦进行优化就会消失,需要事先调查出可以访问的变量。下面实际列举的是从vfs_symlink的第4行可以访问的变量。
[~]#perf probe—vars vfs_symlink:4
Available variables at vfs_symlink:4
@<vfs_symlink+36>
char*oldname
int error
struct dentry*dentry
struct inode*dir
根据这个结果,可以看出能够访问oldname、error、dentry、dir这4个局部变量。如果加上—var选项的附加选项—externs,则除了上述局部变量以外,还会列举出全局变量。
实际定义追踪事件的是perf probe—add。perf probe—add指定追踪事件定义位置的格式如下。
·根据函数名定义时:
[事件名=]函数[@文件][:从函数开头的行数|+偏移量|%return|;模式]·根据文件名和行数或模式定义时:
[事件名=]文件[:从文件开头的行数|;模式]
文件名是基于绝对路径的,但不需要写出实际文件的所有绝对路径。perf probe只会检查文件名的末尾是否一致,因此,例如,当绝对路径为/usr/src/linux-2.6/kernel/timer.c时,只需要写出linux-2.6/kernel/timer.c就足够了。格式中的“模式”是在选择符合条件的多个行时使用的一种glob描述匹配。例如,schedule;cpu=[!=]*显示的是schedule()函数中向变量cpu赋值的行。
在下例中,vfs_symlink的第4行定义了记录dentry结构的d_name.name、oldname、error各自值的事件。另外,为了提高事件的可读性,将dentry->d_name.name和oldname设置为以string类型记录。
[~]#perf probe—add'vfs_symlink:4 dentry->d_name.name:string oldname:string error'
Add new event:
probe:vfs_symlink(on vfs_symlink:4 with name=dentry->d_name.name:string
oldname:string error)
You can now use it on all perf tools, such as:
perf record-e probe:vfs_symlink-aR sleep 1
当前已定义的动态追踪事件列表可以通过perf probe—list看到。
perf probe—list
probe:vfs_symlink(on vfs_symlink:4@fs/namei.c with name oldname_string error)
可以看出,使用perf probe—list可以看到该事件定义在哪个文件的哪一行(这个例中为fs/namei.c的vfs_symlink()函数的第4行)。
下面,使用Hack#69介绍的方法来尝试获取追踪。
[~]#cd/sys/kernel/debug/tracing
[tracing]#echo probe:vfs_symlink>set_event
[tracing]#ln-s/tmp/hoge/tmp/huga
[tracing]#head trace
tracer:nop
#
TASK-PID CPU#TIMESTAMP FUNCTION
|||||
ln-2439[001]9061.438993:vfs_symlink:(vfs_symlink+0x24/0x78)
name="huga"oldname_string="/tmp/hoge"error=0
可以看出,记录了已执行的ln的变量等。