Linux中国  设为主页
 收藏本站
 
当前位置: > 首页 ->Linux技术 ->内核研究 ->使用 SystemTap 调试内核
·Linux 和对称多处理 ·Relay:一种高效的数据传输技术 ·使用 SystemTap 调试内核 ·配置FreeBSD内核 ·在FreeBSD4.x中制作启动菜单 ·制作软盘上运行的FreeBSD系统 ·FreeBSD光盘运行版的制作过程 ·制作RAMDISK in KERNEL的NetBSD ·制作RAMDISK in KERNEL的OpenBSD
  相关分类: 
入门与提高
系统管理
网络应用
嵌入式系统
内核研究
服务器相关
发行版专区
Linux程序设计
Linux安全
BSD相关
桌面应用
  站内搜索: 
热门文章排行
热门文章排行 一次即大功告成 Linux内核升级全过程(04-19)
使用 Linux 系统调用的内核命令 (04-22)
推荐:Linux用户态与内核态的交互(04-11)
Linux内核配置选项 (04-22)
Linux 2.6 内核的 Initrd 机制解析(04-11)
精采文章排行
精采文章排行 使用 Linux 系统调用的内核命令 (04-22)
Linux 和对称多处理 (04-22)
Relay:一种高效的数据传输技术 (04-22)
使用 SystemTap 调试内核 (04-22)
配置FreeBSD内核 (04-22)
 

使用 SystemTap 调试内核

作者:桂剑    来源:IBM DW中国   点击:   日期:2007-04-22 [收藏] [投稿]

  IE是否经常中毒?推荐您


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

SystemTap的例子

了解了SystemTap的基本用法,下面让我们来看几个有趣的例子。

统计当前系统中调用最多的前10个系统调用

在进行性能分析的时候,我们常常需要知道那些函数调用次数最多,才能有的放矢地展开分析。下面这个简单的例子可以打印出在过去的5秒钟里调用次数最多的那些系统调用。


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

它的输出结果一目了然:


图

看看是谁在偷偷动我的文件

有时候,我们如果中了恶意的病毒软件,会发现某些文件莫名其妙的被修改,下面这个例子可以帮你监视谁在修改你的文件。


#!/usr/bin/env stap
#
# monitor who is messing my file of secrets
#
probe generic.fop.open {
        if(filename == "secrets")
                printf("%s is opening my file: %s\n", execname(), filename)
}

我们运行这个脚本,在另外一个窗口做一些操作,来看看它的输出结果:


图

打印ANSI字符串

SystemTap不仅仅是一个简单的调试工具,强大的脚本语言能力让它同样能做一些有趣的事情,下面这个例子就可以对输出的字符进行美化:


#!/usr/bin/env stap
#
# print colorful ANSI strings
#
probe begin {
        printf("a \\ b |");
        for (c = 40; c < 48; c++)
                printf("   %d   ", c);
        printf("\12");
        for (l = 0; l < 71; l++)
                printf("-");
        printf("\12");

        for (r = 30; r < 38; r++)
                for (t = 0; t < 2; t++) {
                        printf("%d    |", r);
                        for (c = 40; c < 48; c++)
                                printf("\033[%d;%d%s %s \033[0;0m",
                                        r, c, !t ? "m" : ";1m", !t ? "Normal" : "Bold  ");
                        printf("\12");
                }
        exit();
}

来看看它的输出:


图 

SystemTap的基本原理


图

现在,大家已经熟悉了SystemTap的基本用法。在结束之前,让我们再来了解一下SystemTap的基本原理和工作流程以加深理解。

可以看出,SystemTap运行的过程依次分为五个阶段,通常称为Pass 1 - Pass 5。就像前面介绍用法的时候提到的,在命令行中加上-p NUM选项可以使得SystemTap在运行完Pass NUM之后停止,而不是运行到Pass 5。这允许你分析SystemTap在每一个阶段的输出,对于调试脚本尤其有用。

下面来介绍每一个阶段的主要功能:

  • Pass 1 - parse:这个阶段主要是检查输入脚本是否存在语法错误,例如大括号是否匹配,变量定义是否规范等
  • Pass 2 - elaborate:这个阶段主要是对输入脚本中定义的探测点或者用到的函数展开,不但需要综合SystemTap的预定义脚本库,还需要分析内核或者内核模块的调试信息
  • Pass 3 - translate: 在这个阶段,将展开后的脚本转换成C文件。前三个阶段的功能类似于编译器,将.stp文件编译成为完整的.c文件,因此又被合起来称为转换器(translator)

     如果您对本文有任何疑问或者建议,请到讨论区发表您的意见: >> 论坛入口 <<

    上一页 1 23 下一页

    上一篇:配置FreeBSD内核   下一篇:Relay:一种高效的数据传输技术
文章评论】 【收藏本文】 【推荐好友】 【打印本文】 【我要投稿】 【论坛讨论

   相关文章:
·使用 Linux 系统调用的内核命令

   文章评论:(1条)
  
 请留名: 匿名评论   点击查看所有评论 论坛讨论
 

 声明:刊登此文章是为了传递更多信息,文章内容仅供参考,转载请注明出处。