Home > Linux, 工具介绍 > 调查用户空间程序某函数最常调用路径

调查用户空间程序某函数最常调用路径

November 17th, 2010

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: 调查用户空间程序某函数最常调用路径

在做系统调优或者调查性能问题的的时候,比如说调查一个锁的性能问题。 这把锁的代码会有很多路径会调用, 我们可以在锁的地方设个probe点,但是我们无法知道那个路径是最经常调用的。 所以我就写了个stap脚本来解决这个问题,代码在RHEL 5.4/6下都调试没有问题的。

$ cat  > dig.stp 
global stacks_count

probe process(@1).function(@2)
{
 stacks_count[ubacktrace()]++;
}

function sprint_stackx(stack)
{
addr = tokenize(stack, " ");
while(addr != "")
{
        fun= symname(strtol(addr, 16));
        s = fun . "->" . s;
        addr = tokenize("", " ");
}
return s;
}

function print_top_stack () {
  printf ("%50s %10s\n", "STACK", "COUNT")
  foreach (stack in stacks_count- limit 20) {
    printf("%50s %10d\n", sprint_stackx(stack), stacks_count[stack])
  }
  delete stacks_count
}

probe timer.s(5) {
  print_top_stack ()
  printf("--------------------------------------------------------------\n")
}

CTRL+D

#我们用nmon这个程序来试验下吧
#脚本的使用方法是: stap dig.stp prog funcs
#注意这个程序需要-g编译, 才能有符号信息

#在另外一个控制台下运行nmon, 打开磁盘,CPU监控等。
$nmon

$ sudo stap dig.stp nmon proc_*
                                             STACK      COUNT
                                 main->proc_read->          2
                                  main->proc_cpu->          2
                                 main->proc_read->          2
                                  main->proc_mem->          2
                 main->proc_mem->proc_mem_search->          2
                 main->proc_mem->proc_mem_search->          2
                 main->proc_mem->proc_mem_search->          2
                 main->proc_mem->proc_mem_search->          2
                 main->proc_mem->proc_mem_search->          2
                 main->proc_mem->proc_mem_search->          2
                 main->proc_mem->proc_mem_search->          2
                 main->proc_mem->proc_mem_search->          2
                 main->proc_mem->proc_mem_search->          2
                 main->proc_mem->proc_mem_search->          2
                 main->proc_mem->proc_mem_search->          2
                 main->proc_mem->proc_mem_search->          2
                 main->proc_mem->proc_mem_search->          2
                 main->proc_mem->proc_mem_search->          2
                 main->proc_mem->proc_mem_search->          2
                 main->proc_mem->proc_mem_search->          2
--------------------------------------------------------------
...

哈效果不错哦!

祝玩的开心。

Post Footer automatically generated by wp-posturl plugin for wordpress.

  1. zituan
    November 17th, 2010 at 15:41 | #1

    只能感叹,systemtap太强大了~~~

    Yu Feng Reply:

    确实很猛,可以做以前不敢想的很多事情!

  2. rizhao
    November 17th, 2010 at 17:19 | #2

    systemtap神器,chuba V5

  3. November 21st, 2010 at 14:44 | #3

    我的内核咋没UTRACE选项呢, 2.6.33.4。。。

    Yu Feng Reply:

    utrace还没有合并到主流linux,所以目前是redhat产品支持的好。

  4. Fu Haiping
    December 11th, 2010 at 19:54 | #4

    您好,最近偶也在看SystamTap和utrace的一些东西,俺的系统Ubuntu 10.10,内核2.6.35,自己给内核打了utrace补丁,但是按照上面脚本的输出,即便使用了nmon使用了-g参数,也得不到符号信息啊,
    以下是我的实验步骤:
    1、编译nmon:Makefile文件中CFLAGS=-g -DJFS -DGETUSER -Wall -DLARGEMEM
    2、运行nmon
    3、运行dig脚本:
    STACK COUNT
    0x80547dd->0x804b418->0x8049806-> 2
    0x80547e2->0x804a80b-> 2
    0x805607b->0x8049806-> 2
    0x8056080->0x804b467-> 2
    0x8056085->0x804a80b-> 2
    0x8057c89->0x8049806-> 2
    0x8057c8e->0x804da49-> 2
    0x8057c8e->0x804da77->0x804d968-> 2
    0x8057c8e->0x804da8f->0x804d968-> 2
    0x8057c8e->0x804daa7->0x804d968-> 2
    0x8057c8e->0x804dabf->0x804d968-> 2
    0x8057c8e->0x804dad7->0x804d968-> 2
    0x8057c8e->0x804daef->0x804d968-> 2
    0x8057c8e->0x804db07->0x804d968-> 2
    0x8057c8e->0x804db1f->0x804d968-> 2
    0x8057c8e->0x804db37->0x804d968-> 2
    0x8057c8e->0x804db4f->0x804d968-> 2
    0x8057c8e->0x804db67->0x804d968-> 2
    0x8057c8e->0x804db7f->0x804d968-> 2
    0x8057c8e->0x804db97->0x804d968-> 2
    我也知道在Eclipse 3.6的Linux C/C++开发人员版本(Eclipse IDE for C/C++ Linux Developers (includes Incubating components))中有个Callgraph工具可以使用,这个工具也是使用SystemTap作为后端解析函数调用的路径,应该也和这种方式差不多吧~

  5. November 28th, 2011 at 00:11 | #5

    看函数调用callgrind也挺好的,只是没有stap这么灵活.

    Yu Feng Reply:

    二个不同定位的东西

  6. mickey
    March 27th, 2012 at 14:55 | #6

    我测试的情况也是显示的地址
    版本:SystemTap translator/driver (version 1.3/0.137 non-git sources)
    系统:Linux platform1 2.6.18-164.el5 #1 SMP Tue Aug 18 15:51:48 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
    ————————————————————–
    STACK COUNT
    0x3e3401d994->0x40147e->0x480c0d-> 1

    Yu Feng Reply:

    带debuginfo了吗?

    mickey Reply:

    有装这几个:
    rpm -i kernel-debuginfo-common-2.6.18-164.el5.x86_64.rpm
    rmp -i kernel-debuginfo-2.6.18-164.el5.x86_64.rpm
    rpm -i glibc-debuginfo-2.5-42.x86_64.rpm

    Yu Feng Reply:

    这就比较奇怪!

Comments are closed.