我是从新编译内核搞定的。但是还是不支持用户空间的侦测。需要给内核打补丁,建议用红帽系列。
在 2012-10-18 上午11:49, <
pengl...@gmail.com>写道:
在ubuntu上执行
stap --ldd -d /usr/local/openresty/nginx/sbin/nginx --all-modules -D MAXMAPENTRIES=2024 -D MAXACTION=20000 -D MAXTRACE=100 -D MAXSTRINGLEN=4096 -D MAXBACKTRACE=100 -x 2635 a.stp > a.out
提示错误:
WARNING: missing unwind/symbol data for module 'kernel'
user-space facilities not available without kernel CONFIG_UTRACE
Pass 4: compilation failed. Try again with another '--vp 0001' option.
这个是怎么回事呢,有朋友碰到过么
在 2012年10月14日星期日UTC+8上午1时50分24秒,agentzh写道:
> Hello!
>
> 2012/10/13 Wenhua Zhang:
> > Hi 章老师,
> > 您好,
> > 之前在微博上看到有些您用flamegraph画的“火焰图”,例如:http://agentzh.org/misc/nginx/lua-resty-redis-flamegraph.svg
> > 目前也想用systemtap进行nginx的时间消耗分析,并用flameGraph画出相应的火焰图。
> > 能否提供一下您之前画图使用的systemtap脚本作为参考?谢谢
> >
>
> 我生成纯用户态的火焰图所使用的 systemtap 脚本 a.stp 的源码如下:
>
> global s;
> global quit = 0;
>
> probe timer.profile {
> if (pid() == target()) {
> if (quit) {
> foreach (i in s-) {
> print_ustack(i);
> printf("\t%d\n", @count(s[i]));
> }
> exit()
> } else {
> s[ubacktrace()] <<< 1;
> }
> }
> }
>
> probe timer.s(20) {
> quit = 1
> }
>
> 运行这个脚本的一条典型命令行是:
>
> stap --ldd -d /path/to/nginx/sbin/nginx \
> -d /path/to/luajit/lib/libluajit-5.1.so.2.0.0 \
> --all-modules -D MAXMAPENTRIES=20240 \
> -D MAXACTION=20000 \
> -D MAXTRACE=100 \
> -D MAXSTRINGLEN=4096 \
> -D MAXBACKTRACE=100 -x 5857 a.stp > a.out
>
> 假设这里测量的 nginx worker 进程的 pid 是 5857. 大约过 20 多秒之后,该命令会退出并生成 a.out
> 输出文件,然后从此文件生成火焰图文件 a.svg:
>
> perl stackcollapse-stap.pl a.out > a.out2
> perl flamegraph.pl a.out2 > a.svg
>
> 这里使用的两个 perl 脚本(.pl 文件)来自 Brendan Gregg 放在 GitHub 上的 flamegraph 项目:
>
> https://github.com/brendangregg/FlameGraph
>
> 值得提醒的是,在运行 systemtap 脚本期间,被采样的 nginx worker 进程(或者其他任意进程)须是足够繁忙的,否则
> systemtap 脚本可能会长时间不退出。一般我在上面第一步运行 stap 之前会先用 ab 工具对 nginx
> 服务器保持压力,至少得持续到 stap 命令自动退出以后。
>
> 当然,利用这种方法也可以绘制核心态 + 用户态的更为完整的火焰图,例如这个例子:
>
> http://agentzh.org/misc/nginx/lua-resty-redis-flamegraph4.svg
>
> 这样可以把 kernel 空间中的调用栈也给一起采样了,从而可以得到整个“软件栈”(software stack)的全景图。
>
> 此时需要换用类似下面这样的 systemtap 脚本:
>
> global bt;
> global quit = 0
>
> probe timer.profile {
> if (pid() == target()) {
> if (!quit) {
> bt[backtrace(), ubacktrace()] <<< 1
>
> } else {
>
> foreach ([sys, usr] in bt- limit 1000) {
> print_stack(sys)
> print_ustack(usr)
> printf("\t%d\n", @count(bt[sys, usr]))
> }
> exit()
> }
> }
> }
>
> probe timer.s(20) {
> quit = 1
> }
>
> 值得一提的是,建议使用最新的 SystemTap 2.0 发布:
>
> http://sourceware.org/systemtap/ftp/releases/
>
> 或者干脆直接使用 systemtap 的 git master HEAD:
>
> git clone git://sourceware.org/git/systemtap.git
>
> 从源码编译 systemtap 是推荐的做法。我一般使用类似下面这样的命令构造之:
>
> ./configure --prefix=/opt/systemtap --disable-docs
> --disable-publican --disable-refdocs && make -j8
> sudo make install
>
> PATH=/opt/systemtap/bin:$PATH
> export PATH
>
> >
> > 目前对Brendan Gregg在博客上写的systemtap的参数不是很理解:
> > stap -s 32 -D MAXTRACE=100 -D MAXSTRINGLEN=4096 -D MAXMAPENTRIES=10240 \
> > -D MAXACTION=10000 -D STP_OVERLOAD_THRESHOLD=5000000000 --all-modules \
> > -ve 'global s; probe timer.profile { s[backtrace()] <<< 1; }
> > probe end { foreach (i in s+) { print_stack(i);
> > printf("\t%d\n", @count(s[i])); } } probe timer.s(60) { exit(); }' \
> > > out.stap-stacks
>
> Brendan 使用的各个 stap 命令行参数的具体含义可以参见 stap -h 的输出。
>
> 特别地,其中 -D 选项定义的那些宏的值是为了放宽 systemtap 内部的很多限制。例如,MAXTRACE
> 宏用于控制调用栈的深度,默认只有 20. 所以当实际的调用栈深度超过 20
> 时(事实上,经常会超时),但会发生调用栈信息的自动截断,从而影响火焰图的绘制。
>
> 其他宏的具体含义可以参考 systemtap 邮件列表中的相关讨论以及 systemtap 自身的源码实现。
>
> Brendan 在这里给出的 systemtap one-liner 是单独对 Linux kernel 进行采样,即得到纯核心态的火焰图 :)
>
> Best regards,
> -agentzh
>
> P.S. 同时抄送给 openresty 中文邮件列表:https://groups.google.com/group/openresty
> 这样其他朋友也可以从我们这里的讨论中获益 :)