使用systemtap调试内核

   SystemTap是半年之前接触的东西了,今天突然又用到了点,怕再次忘记,就稍微找了点资料,再加上自己应用运行,就放在这里了。主要是其脚本的运行方式,包括脚本中嵌入C时的编译命令。

    SystemTap是一种新颖的 Linux 内核诊断工具,提供了一种从运行中的 Linux 内核快速和安全地获取信息的能力。SystemTap
是内核开发人员和系统管理员的福音,因为这使得他们可以通过编写或者重用简单的脚本来收集内核的实时数据,而不需要再忍受修改源码、编译内核、重启系统的漫长煎熬。本文介绍了 SystemTap 的安装、使用和基本原理,并用一些有趣的例子揭示了 SystemTap 提供的强大能力。


   在 SystemTap 出现之前,对于 Linux 程序员或者系统管理员而言,调试内核往往是一场噩梦。例如,你怀疑传递给系统调用read 的参数 fd 出了问题,想把它打印出来,你需要做的是:首先得到一份内核源码,找到 sys_read() 的函数体中插入printk()语句,接下来重新编译内核,然后用新的内核重新启动系统。谢天谢地,你总算看到了你想要看到的东西,不过你马上会发现遇到了一个新的麻烦:除非重新启动系统到原来的内核,printk() 会无休止地打印下去。SystemTap 的目的就是要把人们从这种泥潭中解救出来。SystemTap提供了一个简单的命令行接口和强大的脚本语言,同时预定义了丰富的脚本库。基于内核中的kprobe,SystemTap允许你自由地从运行中的内核无害地收集调试信息和性能数据,来用于之后的分析和处理。你可以随时开始或者停止这种收集过程,而无需漫长的修改代码、编译内核和重启系统的悲惨循环。SystemTap 使得上面的问题变得简单了,简单得只需要一条命令就可以做到:
stap -e 'probe syscall.read { printf("fd = %d\n",fd) }


    SystemTap的功能和Sun的DTrace和IBM的dprobe工具相似。但是和它们不同的是,SystemTap是遵循GPL的开源软件项目。它的出现使得Linux社区也拥有了功能强大而且易于使用的动态内核调试工具。目前,SystemTap的主要开发成员来自于RedHat、IBM、Intel和Hitachi,其中还包括来自IBM中国开发中心的工程师。

运行SystemTap  

运行SystemTap首先需要root权限。
运行SystemTap有三种形式:
1. 从文件(通常以.stp作为文件名后缀)中读入并运行脚本:stap [选项] 文件名
2. 从标准输入中读入并运行脚本: stap [选项] -
3. 运行命令行中的脚本:stap [选项] -e 脚本
4. 直接运行脚本文件(需要可执行属性并且第一行加上#!/usr/bin/stap):./脚本文件名
使用"Ctrl+C"中止SystemTap的运行。
systemtap的选项还在不断的扩展和更新中,其中最常用的选项包括:
-v         -- 打印中间信息
-p NUM      -- 运行完Pass Num后停止(缺省是运行到Pass 5)
-k         -- 运行结束后保留临时文件不删除
-b         -- 使用RelayFS文件系统来将数据从内核空间传输到用户空间
-M        -- 仅当使用-b选项时有效,运行结束时不合并每个CPU的单独数据文件
-o FILE    -- 输出到文件,而不是输出到标准输出
-c CMD     -- 启动探测后,运行CMD命令,直到命令结束后退出
-g        -- 采用guru模式,允许脚本中嵌入C语句
其它更多选项请参看stap的手册。

 

下面是给的例子

每隔5秒统计系统调用 

#!/usr/bin/stap
global syscalls
function print_top() {
        cnt = 0
        //log (?.YSCALL\t\t\t\tCOUNT?.
        printf("%25s %10s\n","SYSCALL","COUNT")
        foreach (syscall in syscalls-) {
                //printf(?.-20s\t\t%5d\n?. name, syscalls[name])
                printf("%25s %10d\n",syscall,syscalls[syscall])
        if (cnt++ == 10)
                        break
        }
        printf("-------------------------------------\n")
        delete syscalls
}
probe syscall.* {
        syscalls[probefunc()]++
}
probe timer.ms(5000) {
        print_top()
}

  • 探测点(probe):每个systemtap脚本中至少需要定义一个探测点,也就是指定了在内核的什么位置进行探测。探测点名
    称后面紧跟的一组大括号内定义了每次内核运行到该探测点时需要运行的操作,这些操作完成后再返回探测点,继续下面的指令。这里给出了systemtap目
    前支持的所有探测点类型。
  • 全局变量(global):用来定义全局变量。单个探测点函数体中使用的局部变量不需要预先定义,但是如果一个变量需要在多个探测点函数体中使用,则需要定义为全局变量。
  • 函数(function):用来定义探测点函数体中需要用到的函数。除了可以用脚本语言定义函数以外,还可以用C语言来定义函数,只是这时函数名后面的大括号对需要换成%{ %}。

    编译命令为stap -v test.stp

    运行结果为:

     

           这里给出的是比较简单的例子。利用SystemTap是可以跟踪到内核函数的,比如open,write,read等函数,甚至可以跟踪到vfs层的数据结构inode,dentry等,从而获取inode,dentry中的信息,对于内核调试而言是很灵活很方便的。

           在SystemTap中还可以嵌入C语言的语句,但是编译命令是:stap -gv test.stp

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值