本文为网上各位大神文章的综合简单实践篇,参考文章较多,有些总结性东西,自认暂无法详细写出,建议读文中列出的参考文档,相信会受益颇多。下面开始吧(本文出自 “cclo的博客” 博客,请务必保留此出处http://xuclv.blog.51cto.com/5503169/1184517
  SystemTap provides free software (GPL) infrastructure to simplify the gathering of information about the running Linux system. This assists diagnosis of a performance or functional problem. SystemTap eliminates the need for the developer to go through the tedious and disruptive instrument, recompile, install, and reboot sequence that may be otherwise required to collect data.
  SystemTap provides a simple command line interface and scripting language for writing instrumentation for a live running system. We are publishing samples, as well as enlarging the internal "tapset" script library to aid reuse and abstraction.




  通过性能分析来确定什么原因导致CPU繁忙是日常工作中长做的事情,这往往会涉及到栈性能分析。通过定期采样的方式来确定哪些代码是导致CPU繁忙的原因是一个比较粗糙的方法。一个更好的方式是创建一个定时中断来收集程序运行时的计数,函数地址,甚至整个堆栈回溯,最后打印为我们可阅读的报告.我们常用的性能分析工具有oprofile,gprof,dtracesystemtap 等
  Flame Graph:火焰图,是一个把采样所得到的堆栈跟踪可视化展示的工具。它是基于上面提到的性能分析工具的结果,Flame graph本身并不具备性能检测的能力。




  OS:ubuntu12.10 				#支持uprobes机制
  systemtap:2.1					#尽少的bug
1> 安装systemtap,这里源码编译
   $ sudo apt-get install build-essential
   $ wget http://sourceware.org/systemtap/ftp/releases/systemtap-2.1.tar.gz
   $ tar zxvf systemtap-2.1.tar.gz
   $ sudo ./configure -prefix=/opt/systemtap -disable-docs -disable-publican -disable-refdocs
   configure: error: missing elfutils development headers/libraries (install elfutils-devel, libebl-dev, libdw-dev and/or libebl-devel
   $ sudo apt-get install libdw-dev      #其实缺的该是libdw1这个包,按提示安装libdw-dev罢了,另三个包都木有
   $ sudo make
   $ sudo make install
   $ sudo ln -s /opt/systemtap/bin/stap /usr/sbin/stap
2> 安装debug packages (Kernel debug info packages on Ubuntu, which will aid in providing information for bugs)
  1:$ uname -r
  2:在http://ddebs.ubuntu.com/pool/main/l/linux/网址找到对应内核的的debug packages,下载并安装之
    $ sudo dpkg -i linux-image-3.5.0-17-generic-dbgsym_3.5.0-17.28_amd64.ddeb
如没有找到自己系统对于的debug packages,建一个,方法如下:(How do I build a debuginfo kernel if one isn't available?)(官网原文,本文不涉及)
    $ cd $HOME
    $ sudo apt-get install dpkg-dev debhelper gawk
    $ mkdir tmp
    $ cd tmp
    $ sudo apt-get build-dep --no-install-recommends linux-image-$(uname -r)
    $ apt-get source linux-image-$(uname -r)
    $ cd linux-2.6.31 (this is currently the kernel version of 9.10)
    $ fakeroot debian/rules clean
    $ AUTOBUILD=1 fakeroot debian/rules binary-generic skipdbg=false
    $ sudo dpkg -i ../linux-image-debug-2.6.31-19-generic_2.6.31-19.56_amd64.ddeb
3> 测试systemtap,出现hello world,安装完成
   $ sudo stap -e 'probe kernel.function("sys_open") {log("hello world") exit()}'
4> systemtap安装参考:




5> 安装LNMP(非必须,安装nginx即可)
   $ sudo apt-get install nginx mysql-server mysql-client php5 php5-fpm php5-mysql
   $ sudo vim /etc/nginx/sites-enabled/default     #启用下面几行
  1. location ~ \.php$ {

  2.        fastcgi_split_path_info ^(.+\.php)(/.+)$;

  3. #       # NOTE: You should have "cgi.fix_pathinfo = 0;"in php.ini

  4. #

  5. #       # With php5-cgi alone:

  6. #       fastcgi_pass;

  7. #       # With php5-fpm:

  8.        fastcgi_pass unix:/var/run/php5-fpm.sock;

  9.        fastcgi_index index.php;

  10.        include fastcgi_params;

  11. }

   $ sudo vim /usr/share/nginx/www/index.php       #随便建个测试页
  1. <html><body><h1>It is my works!!</h1></body></html>

  2. <?php

  3. $link=mysql_connect('localhost','root','root');

  4. if ($link)

  5.    echo "Success";

  6. else

  7.    echo "Failure";

  8. mysql_close();

  9. phpinfo();

  10. ?>

   访问http://	                  #访问确保正常 
6> 用systemtap进行nginx的分析,并用flameGraph画出相应的火焰图。
   1:编写systemtap脚本: vim ngx.stp
  1. global s;

  2. global quit = 0;

  3. probe timer.profile {

  4.    if (pid() == target()) {

  5.        if (quit) {

  6.            foreach (i in s-) {

  7.                print_ustack(i);

  8.                printf("\t%d\n", @count(s[i]));

  9.            }

  10.            exit()

  11.        } else {

  12.            s[ubacktrace()] <<< 1;

  13.        }

  14.    }

  15. }

  16. probe timer.s(20) {

  17.    quit = 1

  18. }

   $ sudo stap --ldd -d /usr/sbin/nginx --all-modules -D MAXMAPENTRIES=256 -D MAXACTION=20000 -D MAXTRACE=100 -D MAXSTRINGLEN=4096 -D MAXBACKTRACE=100 -x 2082 ngx.stp --vp 0001 > ngx.out
可能需修改的地方: /usr/sbin/nginx #nginx的安装位置,一般是此 -D MAXMAPENTRIES=256 #本机是个虚拟机,只给了其512M内存,为了保证内存不溢出,设为256 -x 2082 #指定其中一个nginx worker进程的pid 在执行以上命令的同时保证对nginx的压力测试,另开终端执行: $ ab -n 900000 -c 50
   $ perl stackcollapse-stap.pl ngx.out > ngx.out2
   $ perl flamegraph.pl ngx.out2 > ngx.svg
7> 访问192.168.1.94/ngx.svg        #火焰图出炉了

8> 可能遇到的问题:
  1:如果有类似如下行,执行 $ sudo rm .systemtap -rf
   Pass 4: using cached /home/ubuntu/.systemtap/cache/24/stap_2479e8647ccf262def735ebf0eeb57c5_5866.ko
   Pass 4: compiled C into "stap_2711449662ecf03b09d98a743c2122d0_5946.ko" in 24060usr/6960sys/103610rea
   WARNING: Missing unwind data for module, rerun with 'stap -d stap_2711449662ecf03b09d98a743c2122d0_3437'
   $ sudo apt-get install nginx-full-dbg 
  5:WARNING: missing unwind/symbol data for module 'kernel' :user-space facilities not available without kernel CONFIG_UTRACE 
   这个错误是说你的 kernel 没有提供 utrace/uprobes 用户态支持。两种解法:
   1. 自己给Ubuntu自带的老kernel应用utrace补丁,并重新编译它。chaoslawful老师写过一篇博客分享过ubuntu上的步骤:http://chaoslawful.iteye.com/blog/1463564
   2. 将kernel升级到官方最新的3.5或以上的版本。最新的kernel默认包含了uprobes机制,不再需要utrace补丁了(这是为什么用ubuntu12.10的原因)
9> 火焰图生成参考的文档:




$ stap -h
Systemtap translator/driver (version 2.1/0.153, non-git sources)
Copyright (C) 2005-2013 Red Hat, Inc. and others
This is free software; see the source for copying conditions.
enabled features: TR1_UNORDERED_MAP NLS

Usage: stap [options] FILE         Run script in file.
   or: stap [options] -            Run script on stdin.
   or: stap [options] -e SCRIPT    Run given script.
   or: stap [options] -l PROBE     List matching probes.
   or: stap [options] -L PROBE     List matching probes and local variables.

Options (in /home/ubuntu/.systemtap/rc and on command line):
   --         end of translator options, script options follow
   -h --help  show help
   -V --version  show version
   -p NUM     stop after pass NUM 1-5, instead of 5			
              (parse, elaborate, translate, compile, run)
   -v         add verbosity to all passes
   --vp {N}+  add per-pass verbosity [00000]
   -k         keep temporary directory
   -u         unoptimized translation 
   -w         suppress warnings 
   -W         turn warnings into errors 
   -g         guru mode 
   -P         prologue-searching for function probes 
   -b         bulk (percpu file) mode 
   -s NUM     buffer size in megabytes, instead of 0
   -I DIR     look in DIR for additional .stp script files, in addition to
   -D NM=VAL  emit macro definition into generated C code
   -B NM=VAL  pass option to kbuild make
   --modinfo NM=VAL
              include a MODULE_INFO(NM,VAL) in the generated C code
   -G VAR=VAL set global variable to value
   -R DIR     look in DIR for runtime, instead of
   -r DIR     cross-compile to kernel with given build tree; or else
   -r RELEASE cross-compile to kernel /lib/modules/RELEASE/build, instead of
   -a ARCH    cross-compile to given architecture, instead of x86_64
   -m MODULE  set probe module name, instead of 
   -o FILE    send script output to file, instead of stdout. This supports
              strftime(3) formats for FILE
   -c CMD     start the probes, run CMD, and exit when it finishes
   -x PID     sets target() to PID
   -F         run as on-file flight recorder with -o.
              run as on-memory flight recorder without -o.
   -S size[,n] set maximum of the size and the number of files.
   -d OBJECT  add unwind/symbol data for OBJECT file
   --ldd      add unwind/symbol data for all referenced object files.
              add unwind/symbol data for all loaded kernel objects.
   -t         collect probe timing information
              set the pass-5 runtime mode, instead of kernel
              check the script for constructs not allowed at the given privilege level
              equivalent to --privilege=stapusr
              suppress incompatible language/tapset changes beyond VERSION,
              instead of 2.1
              displays warnings where a syntax element may be 
              version dependent
              substitute zero for bad context $variables
              catch all runtime errors, quietly skip probe handlers
              specify systemtap compile-servers
              report on the status of the specified compile-servers:
              run pass 5 on the specified ssh host.
              may be repeated for targeting multiple hosts.
              prefix each line of remote output with a host index.
              specify name of temporary directory to be used.
              automatically download debuginfo using ABRT.
              yes,no,ask,<timeout value>
              show a list of available probe types.
              specify sysroot directory where target files (executables,
              libraries, etc.) are located.
              provide an alternate value for an environment variable
              where the value on a remote system differs.  Path
              variables (e.g. PATH, LD_LIBRARY_PATH) are assumed to be
              relative to the sysroot.
              disable -DSTP_NO_OVERLOAD -DMAXACTION and -DMAXTRYACTION limits