6
25
2014
1

systemtap安装、运行

systemtap安装

关于systemtap安装这一部分,实验室小鱼师兄给出了具体操作,这儿我借用:

一、开启内核调试信息

首先由于Systemtap运行时需要内核的调试信息支撑,默认发行版的内核在配置时,这些调试开关是关闭的,所以为了Systemtap能够正常运行,我们首先要使内核开启运行调试信息功能。主要有两种方法:

方法一:下载并安装debuginfo安装包

由于发行版的内核默认无内核调试信息,所以我们还需要一个调试内核镜像,在http://ddebs.ubuntu.com/pool/main/l/linux/ 找到你的内核版本相对应的内核调试镜像(版本号包括后面的发布次数、硬件体系等都必须一致),

假设我的内核版本2.6.32-24,i386结构,那么我需要下载

linux-image-2.6.32-24-generic-dbgsym_2.6.32-24.42_i386.ddeb下载后安装

dpkg -i linux-image-2.6.32-24-generic-dbgsym_2.6.32-24.42_i386.ddeb

 

方法二:重新编译内核

由于http://ddebs.ubuntu.com/pool/main/l/linux/下载页面中并不包含有些版本的内核(比如我们的pcmfs基于的2.6.34.14内核),这个时候我们需要重新编译内核,执行make menuconfig后,配置以下选项(不同版本内核,选项位置可能稍有不同):

 General Setup  -- ->

[*] Kernel->user space relay support (formerly relayfs)

[*] Kprobes

kernel hacking  -- ->

[*]Kernel debugging

[*]Compile the kernel with debug info                    

[*]Debug Filesystem

配置完成后,最终效果是内核的.config文件中看到下面四个选项是设置的:

CONFIG_DEBUG_INFO =y

 CONFIG_KPROBES = y

 CONFIG_DEBUG_FS = y

 CONFIG_RELAY = y

配置完之后,按照以前的编译内核的步骤编译安装即可。

(在该内核代码路径下输入gedit .config可以看到config内容。。这里顺便说一句刚刚解压没有编译的代码中是没有.config这个文件的)

 

二、安装Systemtap和相关依赖包

该步骤很简单,只要使用apt-get安装elfutils依赖包和Systemtap即可

apt-get install elfutils

apt-get install systemtap

 

检测systemtap是否安装好

示例一:打印hello Systemtap

$stap -ve 'probe begin { log("hello Systemtap!") exit() }'

如果安装正确,会得到如下类似的输出结果:

 

测试错误总结:

错误1:

今天运行.stp脚本很怪,有时候可以正确检测,有时候就报错,报错内容如下

Error inserting module '/tmp/stapvDz3zm/stap_csf***.ko':File exists

即模块已经存在,截图

原因在于,systemtap的运行机制如下:

  1. 将.stp 脚本翻译成C源代码,并且作为一个kernel的module。
  2. 将C文件编译成module(.ko)
  3. 将module加载到kernel里
  4. Module会运行,报告script脚本里面说明的事件信息。
  5. 从kernel收集这些信息并且打印到终端。
  6. 如果给stap一个CTRL-C或者是达到脚本里面说明的结束点,会unload module。脚本运行结束。

在上一次非法中断该*.stp脚本时,systemtap无法将*.ko文件移除,这导致再次插入模块出现file exists情况。通过终端输入lsmod指令我们可以看到存在stapc***.ko这个模块,解决办法如下:先移除模块,再重新运行:

rmmod stap**.ko //移除已经存在的模块

./*.stp //重新运行脚本

 

错误2:

在*.stp 运行的过程中,若stp脚本中没有加入运行的持续时间,那么需要通过 ctrl+c 来中断。

若用ctrl+x 中断,则下次运行同样的*.stp脚本时就会出现“错误1”所描述的错误。

Category: systemtap | Tags: systemtap
6
16
2014
2

systemtap脚本

参考

http://blog.csdn.net/kafeiflynn/article/details/6429976

1.systemtap脚本以.stp为扩展名,其基本格式如下

probe event{statements}

2.可以用*来代表通配符

probe kernel.function("*@net/socket.c"){ }

probe kernel.function("*@net/socket.c").return{ }

   代表了所有net/socted的入口和出口

3.可以测试跟踪模块

probe module("pcmfs").function("*").call{

...}

probe  module("pcmfs").function("*").return{

...} 

4.下面以及各例子说明

例1:ext4.stp

#!/usr/bin/stap 
probe kernel.function("*@fs/ext4/namei.c"),
        kernel.function("*@fs/ext4/namei.c").return,
        kernel.function("*@fs/ext4/ialloc.c"),
        kernel.function("*@fs/ext4/ialloc.c").return
        {
                 printf("PID:%d probepoint : %s execname: %s\n",pid(),pp(),execname());
        }

第一行#!/usr/bin/stap 为像系统指定该脚本的类型stap。改程序probe监控四个事件,当这四个时间发生时, 打印改行:printf("PID:%d probepoint : %s execname: %s\n",pid(),pp(),execname());

其中pid为进程号,pp()可以打印 函数名,该函数所在的具体目录具体地点的行数,execname为

chmod +x ext4.stp变为可执行文件,然后./ext4.stp运行该脚本。在另一个终端输入:mkdir newdir则可以看到函数调用结果:

root@desktop:/home/systemtap_study# ./ext4.stp 
PID:3020 probepoint : kernel.function("ext4_lookup@fs/ext4/namei.c:1054") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_find_entry@fs/ext4/namei.c:876") execname: mkdir
PID:3020 probepoint : kernel.function("search_dirblock@fs/ext4/namei.c:826") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_match@fs/ext4/namei.c:813") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_match@fs/ext4/namei.c:813") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_match@fs/ext4/namei.c:813") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_match@fs/ext4/namei.c:813") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_match@fs/ext4/namei.c:813") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_match@fs/ext4/namei.c:813") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_match@fs/ext4/namei.c:813") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_match@fs/ext4/namei.c:813") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_find_entry@fs/ext4/namei.c:876").return execname: mkdir
PID:3020 probepoint : kernel.function("ext4_lookup@fs/ext4/namei.c:1054").return execname: mkdir
PID:3020 probepoint : kernel.function("ext4_mkdir@fs/ext4/namei.c:1827") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_update_dx_flag@fs/ext4/namei.c:800") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_new_inode@fs/ext4/ialloc.c:788") execname: mkdir
PID:3020 probepoint : kernel.function("find_group_orlov@fs/ext4/ialloc.c:460") execname: mkdir
PID:3020 probepoint : kernel.function("get_orlov_stats@fs/ext4/ialloc.c:414") execname: mkdir
PID:3020 probepoint : kernel.function("get_orlov_stats@fs/ext4/ialloc.c:414").return execname: mkdir
PID:3020 probepoint : kernel.function("find_group_orlov@fs/ext4/ialloc.c:460").return execname: mkdir
PID:3020 probepoint : kernel.function("ext4_claim_inode@fs/ext4/ialloc.c:709") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_read_inode_bitmap@fs/ext4/ialloc.c:101") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_read_inode_bitmap@fs/ext4/ialloc.c:101").return execname: mkdir
PID:3020 probepoint : kernel.function("ext4_new_inode@fs/ext4/ialloc.c:788").return execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_to_disk@fs/ext4/namei.c:191") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_to_disk@fs/ext4/namei.c:191").return execname: mkdir
PID:3020 probepoint : kernel.function("ext4_set_de_type@fs/ext4/namei.c:1126") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_next_entry@fs/ext4/namei.c:210") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_from_disk@fs/ext4/namei.c:182") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_to_disk@fs/ext4/namei.c:191") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_to_disk@fs/ext4/namei.c:191").return execname: mkdir
PID:3020 probepoint : kernel.function("ext4_set_de_type@fs/ext4/namei.c:1126") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_add_entry@fs/ext4/namei.c:1474") execname: mkdir
PID:3020 probepoint : kernel.function("add_dirent_to_buf@fs/ext4/namei.c:1290") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_from_disk@fs/ext4/namei.c:182") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_from_disk@fs/ext4/namei.c:182").return execname: mkdir
PID:3020 probepoint : kernel.function("ext4_match@fs/ext4/namei.c:813") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_from_disk@fs/ext4/namei.c:182") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_from_disk@fs/ext4/namei.c:182") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_from_disk@fs/ext4/namei.c:182").return execname: mkdir
PID:3020 probepoint : kernel.function("ext4_match@fs/ext4/namei.c:813") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_from_disk@fs/ext4/namei.c:182") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_from_disk@fs/ext4/namei.c:182") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_from_disk@fs/ext4/namei.c:182").return execname: mkdir
PID:3020 probepoint : kernel.function("ext4_match@fs/ext4/namei.c:813") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_from_disk@fs/ext4/namei.c:182") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_from_disk@fs/ext4/namei.c:182") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_from_disk@fs/ext4/namei.c:182").return execname: mkdir
PID:3020 probepoint : kernel.function("ext4_match@fs/ext4/namei.c:813") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_from_disk@fs/ext4/namei.c:182") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_from_disk@fs/ext4/namei.c:182") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_from_disk@fs/ext4/namei.c:182").return execname: mkdir
PID:3020 probepoint : kernel.function("ext4_match@fs/ext4/namei.c:813") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_from_disk@fs/ext4/namei.c:182") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_from_disk@fs/ext4/namei.c:182") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_from_disk@fs/ext4/namei.c:182").return execname: mkdir
PID:3020 probepoint : kernel.function("ext4_match@fs/ext4/namei.c:813") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_from_disk@fs/ext4/namei.c:182") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_from_disk@fs/ext4/namei.c:182") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_to_disk@fs/ext4/namei.c:191") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_to_disk@fs/ext4/namei.c:191").return execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_to_disk@fs/ext4/namei.c:191") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_rec_len_to_disk@fs/ext4/namei.c:191").return execname: mkdir
PID:3020 probepoint : kernel.function("ext4_set_de_type@fs/ext4/namei.c:1126") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_update_dx_flag@fs/ext4/namei.c:800") execname: mkdir
PID:3020 probepoint : kernel.function("add_dirent_to_buf@fs/ext4/namei.c:1290").return execname: mkdir
PID:3020 probepoint : kernel.function("ext4_add_entry@fs/ext4/namei.c:1474").return execname: mkdir
PID:3020 probepoint : kernel.function("ext4_inc_count@fs/ext4/namei.c:1708") execname: mkdir
PID:3020 probepoint : kernel.function("ext4_inc_count@fs/ext4/namei.c:1708").return execname: mkdir
PID:3020 probepoint : kernel.function("ext4_mkdir@fs/ext4/namei.c:1827").return execname: mkdir

上述一个mkdir的动作就调用了许多函数,如果需要看特定一个函数,可以通过管道再使用grep查找

 

例二:将进出函数的退出函数分开标记

#!/usr/bin/stap
probe kernel.function("*@fs/ext4/file.c"),
        kernel.function("*@fs/read_write.c"),
        kernel.function("*@fs/ext4/namei.c"),
        kernel.function("*@fs/ext4/ialloc.c")
        {
                 ts = __indent_timestamp()
                 t1=gettimeofday_ms
                 printf(">>>>>>%d  %6d PID:%d probepoint : %s execname: %s\n",t1,ts,pid(),pp(),execname());
        }


probe kernel.function("*@fs/ext4/file.c").return,
        kernel.function("*@fs/read_write.c").return,
        kernel.function("*@fs/ext4/ialloc.c").return,
        kernel.function("*@fs/ext4/file.c").return
        {
                 printf("<<<<<<PID:%d probepoint : %s execname: %s\n",pid(),pp(),execname());
        }
		

 

例三:用strace来跟踪

这里不是采用的systemtap,而是strace。其中./blktrace为运行程序名字。output.txt为输出文件名。

#!/bin/sh
strace -o output.txt -T -tt -e trace=all ./blktrace_study
		

 

Category: systemtap | Tags: systemtap

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com