systemtab备忘

前端之家收集整理的这篇文章主要介绍了systemtab备忘前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

简介

安装

systemtab

@H_404_6@
  • sudo apt-get install systemtap 直接安装
  • 各版本linux安装指南
  • 通过源码安装
    源码下载
    ./configure
    make
    sudo make -k -i install
  • sudo stap -v -e ‘probe vfs.read {printf(“read performed\n”); exit()}’ (测试是否安装成功)
  • 内核调试信息

    http://ddebs.ubuntu.com/pool/main/l/linux/
    uname -r 查询内核版本信息
    sudo dpkg -i linux-*_amd64.ddeb

    内核源码查询

    @H_404_6@
  • http://kernel.ubuntu.com/git/ubuntu/ubuntu-trusty.git/refs/
  • 搜索指定内核的版本的源码
  • 火焰图

    @H_404_6@
  • https://github.com/brendangregg/FlameGraph
  • ./stackcollapse-stap.pl ./trace.txt > trace.out
  • ./flamegraph.pl ./trace.out > trace.svg
  • firefox ./trace.svg
  • 注: 火焰图 从上到下 表示堆栈顺序,每个色块表明改调用占比
  • systemtap 工作原理

    systemtap 的核心思想是定义一个事件(event),以及给出处理该事件的句柄(Handler)。当一个特定的事件发生时,内核运行该处理句柄,就像快速调用一个子函数一样,处理完之后恢复到内核原始状态。这里有两个概念:

    @H_404_6@
  • 事件(Event):systemtap 定义了很多种事件,例如进入或退出某个内核函数、定时器时间到、整个systemtap会话启动或退出等等。
  • 句柄(Handler):就是一些脚本语句,描述了当事件发生时要完成的工作,通常是从事件的上下文提取数据,将它们存入内部变量中,或者打印出来。
  • Systemtap 工作原理是通过将脚本语句翻译成C语句,编译成内核模块。模块加载之后,将所有探测的事件以钩子的方式挂到内核上,当任何处理器上的某个事件发生时,相应钩子上句柄就会被执行。最后,当systemtap会话结束之后,钩子从内核上取下,移除模块。整个过程用一个命令 stap 就可以完成。

    stap 基本语法

    1. global变量才能在注入点执行
    2. 辅助函数格式   function <name>[:<type>] ( <arg1>[:<type>],... ) { <stmts> }
    3. print(str) - Print the value of str.
    
    printf(fmt) - Print a string with formatting similar to the printf function in C.
    
    sprintf(fmt) - Return a string with formatting similar to the sprintf function in C.
    
    strlen(str) - Return the number of characters in str.
    
    isinstr(str1,str2) - Return 1 if the str1 contains the str2.
    
    strtol(str,base) - Convert a numerical value with the specified base stored in a string to an 
    integer.
    
    exit() - Exit the running script.
    
    probefunc() - Return the name of the function being probed.
    
    execname() - Return the name of the current running process.
    
    pid() - Return the process id of the current process.
    
    pp() - Return current kernel function info.
    
    uid() - Return the user ID of the current process.
    
    cpu() - Return the cpu number the current process is exe
    4. 元素存在 if ([4,"hello"] in foo) {}
    5. 统计类型
    arg<<< 3 # 相当于 arg += b
    @count(g_value):所有统计操作的操作次数
    @sum(g_value):所有统计操作的操作数的总和
    @min(g_value):所有统计操作的操作数的最小值
    @max(g_value):所有统计操作的操作数的最大值
    @avg(g_value):所有统计操作的操作数的平均值

    demo

    打印open调用的执行时间

    global time
    probe syscall.open {
            time[tid()] = gettimeofday_ns()
    }
    probe kernel.function("sys_open").return {
            if(time[tid()]) {
                    printf("sys_open took %d ns to execute %s\n",gettimeofday_ns() - time[tid()],execname())
                    delete time[tid()]
            }
    }

    注意事项

    @H_404_6@
  • stap -V 查看systemtap 版本2.*版本无法打印堆栈信息,可以手动安装3.*版本
  • 安装内核调试信息,一定要安装和当前系统相同的版本,可以禁止系统版本自动更新,避免更新导致不一致
  • 参考资料

    @H_404_6@
  • IBM document
  • Office tutorial
  • Flame Graphs
  • systemtab demo
  • systemtab demo2
  • document
  • 猜你在找的Ubuntu相关文章