Linux有一个和solaris的dtrace类似的工具systemtap,同样很强大,本文主要介绍此工具,最后用这个工具编写脚本,做一下应用瓶颈分析。
SystemTap是一个诊断Linux系统性能或功能问题的开源软件。它使得对运行时的Linux系统进行诊断调式变得更容易、更简单。有了它,开发者或调试人员不再需要重编译、安装新内核、重启动等烦人的步骤。
为了诊断系统问题或性能,开发者或调试人员只需要写一些脚本,而且SystemTap本身也提供了很多脚本,称为”tapset”方便开发,然后通过SystemTap提供的命令行接口就可以对正在运行的内核进行诊断调试,以前需要的修改或插入调试代码、重新编译内核、安装内核和重启动等这些琐碎的工作完全消除。目前该工具并不支持对用户态应用的诊断调试,但是它们在以后会被添加进去。当前该项目的主要开发人员为来自Red Hat, IBM, Intel和Hitachi的工程师。其中Redhat主要负责脚本转换/翻译器和运行时库,IBM负责kprobe和relayfs,Intel负责转换器安全检查以及performance monitor tapset。
OS: RHEL7: 3.10.0-327.el7.x86_64
1.yum install kernel-devel
2.yum install systemtap,elfutils,gcc
3.rpm install kernel&glibc debuginfo这4个rpm需要下载,版本一定要对
kernel-debuginfo-common-x86_64-3.10.0-327.el7.x86_64.rpm
kernel-debuginfo-3.10.0-327.el7.x86_64.rpm
glibc-debuginfo-common-2.17-106.el7_2.1.x86_64.rpm
glibc-debuginfo-2.17-106.el7_2.1.x86_64.rpm
4.验证是否缺包:
[root@localhost dbmysqlfiles]# stap-prep #无返回缺包信息则OK
5.测试安装
stap -ve ‘probe kernel.function(“do_fork”) { print(“hello world\n”) exit() }’ #无返回错误则OK
或
[root@localhost dbmysqlfiles]# stap -V
Systemtap translator/driver (version 2.8/0.163, rpm 2.8-10.el7)
Copyright © 2005-2015 Red Hat, Inc. and others
This is free software; see the source for copying conditions.
enabled features: AVAHI LIBRPM LIBSQLITE3 NSS BOOST_SHARED_PTR TR1_UNORDERED_MAP NLS DYNINST JAVA LIBVIRT LIBXML2
[root@localhost dbmysqlfiles]# stap -L ‘kernel.function(“printk”)’
kernel.function(“printk@kernel/printk.c:1693”) $fmt:char const* $args:va_list
[root@localhost dbmysqlfiles]# stap -L ‘process("/lib64/libc.so.6").function(“malloc”)’
process("/usr/lib64/libc-2.17.so").function(“malloc”)
,很简单的一段C代码,保存为mytrace.c,然后用gcc mytrace.c –o mytraced编译成二进制可执行文件。
#include
void a();
void a_1();
void b();
int main ()
{
printf("fun:main\n");
while (1)
{
a();
b();
//sleep(3);//why? release cpu
}
return 0;
}
void a()
{
printf("fun:a\n");
sleep(2);
a_1();
}
void a_1()
{
sleep(3);
printf("fun:a_1\n");
}
void b()
{
printf("fun:b\n");
}
[root@localhost tracetest]# more mytrace.stp
#!/usr/bin/stap
global tm
probe process("mytraced").function("*"){
tm[ppfunc()]=gettimeofday_us()
}
probe process("mytraced").function("*").return{
printf("fun:%s,spent:%d\n",ppfunc(),(gettimeofday_us()-tm[ppfunc()])/1000)
}
分析输出结果,完美的找到的问题所在
[root@localhost tracetest]# ./mytraced
fun:main
fun:a
fun:a_1
fun:b
fun:a
fun:a_1
fun:b
fun:a
fun:a_1
fun:b
fun:a
^C
[root@localhost tracetest]# stap mytrace.stp
WARNING: function _start return probe is blacklisted: keyword at mytrace.stp:7:1
source: probe process(“mytraced”).function("*").return{
^
fun:_init,spent:0
fun:register_tm_clones,spent:0
fun:frame_dummy,spent:0
fun:__libc_csu_init,spent:0
fun:a_1,spent:3000
fun:a,spent:5000
fun:b,spent:0
fun:a_1,spent:3000
fun:a,spent:5000
fun:b,spent:0
^C[root@localhost tracetest]#
systemtap功能和用法和dtrace都很类似,但有少部分用户空间和内核空间的探测还无法实现(这点没dtrace强大),对于大部分分析调试基本没问题。