下面是我结合网上资料摸索出的可行的操作方法,记录在这样,以备后面继续研究。操作系统是CentOS 6.6 x86_64。
1.将内核版本升级到最新版
因为我机器上CentOS 6.6的内核版本号是2.6.32-573.12.1.el6.x86_64,网上根本找不到对应的kernel-devel,kernel-debuginfo和kernel-debuginfo-common内核rpm包,而升级到最新版就可以解决这个问题。
升级方法参见
http://blog.csdn.net/tao_627/article/details/52136091
升级后的版本号是2.6.32-642.3.1.el6.x86_64
![](http://img.e-com-net.com/image/info8/19285cd8020441e681c95f601f42aac9.jpg)
2.检查内核是否提供utrace/uprobes用户态支持
打开/boot/config-2.6.32-642.3.1.el6.x86_64文件(内核版本不同,文件名不同),检查CONFIG_UTRACE宏是否设置。如果没有,就不能使用SystemTap
cat /boot/config-2.6.32-642.3.1.el6.x86_64 | grep '_UTRACE'
2.安装内核调试所需要的包
yum -y install kernel-devel-2.6.32-642.3.1.el6.x86_64
yum -y install kernel-debuginfo-2.6.32-642.3.1.el6.x86_64
yum -y install kernel-debuginfo-common-x86_64-2.6.32-642.3.1.el6.x86_64
3.安装SystemTap并配置脚本
yum -y install systemtap
验证SystemTap是否安装成功?
stap -ve 'probe begin{log("hello SystemTap!")exit()}'
![](http://img.e-com-net.com/image/info8/b9530edf36b44bb88c44d7aac58dacb8.jpg)
我目前安装的版本号是
![](http://img.e-com-net.com/image/info8/c87cc670aabe4a2b9316d535459b519e.jpg)
![](http://img.e-com-net.com/image/info8/604d69699dc14d898b9f550d9c221d76.jpg)
配置的脚本flame.stp内容如下
global s;
global quit = 0;
probe timer.profile {
if (pid() == target()) {
if (quit) {
foreach ([sys,usr] in s- limit 1000) {
print_stack(sys)
print_ustack(usr);
printf("\t%d\n", @count(s[sys, usr]));
}
exit()
} else {
s[backtrace(), ubacktrace()] <<< 1;
}
}
}
probe timer.s(20) {
quit = 1
}
4.监视运行中的ats并采样,输出svg图
stap --ldd -d /usr/bin/traffic_server --all-modules -D MAXMAPENTRIES=256 -D MAXACTION=20000 -D MAXTRACE=100 -D MAXSTRINGLEN=4096 -D MAXBACKTRACE=100 -x $(pidof traffic_server) flame.stp --vp 0001 > ats.out
这里ats必须是debug版本的,各重要参数说明一下:
-d 表示要查看的对象,比如这里必须要填traffic_server
--ldd 表示加载所有需要的动态库名
--all-modules 加载内核所有需要用到所有动态库名
-D NM=VAL emit macro definition into generated C code
注意这些宏参数根据各自环境自行配置和摸索得到合适的值,可以进一步参考SystemTap的官方资料和文档,我这里暂没有好的结果。
各种资源的使用限制由所生成的C代码中的宏来设置。这些值可在编译时由-D选项来重写。下面描述了部分挑选出来的宏:
MAXNESTING 递归函数的最大调用层数,默认值是10。
MAXSTRINGLEN 字符串的最大长度,默认值是128。
MAXTRYLOCK 在声称可以出现死锁和跳出探测点前,等待全局变量锁的最大迭代次数,默认值是1000。
MAXACTION 单个探测点内可以执行语句数的最大值,默认值是1000。
MAXMAPENTRIES 数组在声明时没有显示指定大小时,数组的最大行数(译者注:即组数的最大下标个数),默认值为2048。
MAXERRORS 在触发退出前,可以容忍软件错误个数的最大值,默认值是0。
MAXSKIPPED 在触发退出前,可忽略的重入探测点的最大值,默认值是100。
MINSTACKSPACE 运行探测处理函数所需要的内核栈的最小字节数。此数值应比探测处理函数所需内核栈的大小加上安全边界大小足够大。默认值是1024。
参考nginx的项目nginx-systemtap-toolkit中sample-bt这个perl脚本的内容来完善我们的测试。
5.下载FlameGraph包,并转换输出数据为svg图
git clone https://github.com/brendangregg/FlameGraph.git
将需要用到的flamegraph.pl和stackcollapse-perf.pl到当前目录,并执行
perl stackcollapse-stap.pl ats.out > ats.out2
perl flamegraph.pl ats.out2 > ats.svg
使用浏览器打开该svg文件就可以了。
6.perf+FlameGraph生成的火焰图
另外使用perf record也可以采集指定时间的数据,并使用FlameGraph生成活跃图。下面是火焰图示例
![](http://img.e-com-net.com/image/info8/7217ad16405646c787431d2762e836a3.jpg)
局部图
参考文献
[1].https://sourceware.org/systemtap/ftp/releases/
[2].https://github.com/brendangregg/FlameGraph
[3].https://github.com/openresty/nginx-systemtap-toolkit
[4].https://github.com/openresty/stapxx