アフィリエイト広告を利用しています

広告

posted by fanblog

systemtapのテンプレート

kernelをデバッグするときにsystemtapを利用するのですが、
毎回スクリプトを作るのが面倒くさいのでテンプレートを作成するのを書いてみました(使う場合は、末尾のスクリプトをコピペしてください)。
個人的なスクリプトなので自己責任で利用してください。

使い方は

./stap-setter.sh [mh] 関数 ” です。

例えば ext4_fill_superが実行されたことを出力したい場合、

./stap-setter.sh ext4_fill_super 

と実行します。すると"test.stp"が下記の内容でできあがります。




#!/usr/local/bin/stap

probe begin
{
printf("start\n")
}

probe kernel.statement("ext4_fill_super") {
printf ("ext4_fill_super called\n")
}





# stap test.stp  でsystemtapを実行します。

裏でext4をmountするとext4_fill_superが呼ばれるので


start
ext4_fill_super called


と出力されます。
printfで関数の呼び出しだけ出力しているのですが、print_backtrace()に置き換えて
バックトレースを見たりもできます。
そこら辺はsystemtapのマニュアルに書いてありますので、別の機会に。
モジュールの場合は -m をつけます。ext3/ext4/jbd/jbd2しか対応してませんが、
他のモジュールも利用する場合は、スクリプト内の配列に追加すればokです。



#!/bin/bash

func_array=($*)
kallsyms="/proc/kallsyms"
num=0
module=0
filename="test.stp"
mod_array=(ext3 ext4 jbd jbd2)

usage()
{
echo "stap-setting.sh [-mh] func-name ..."
echo "e.g. ./stap-setting.sh ext4_fill_super"
exit 0
}


check_env()
{
if [ -z `which stap` ];then
echo "systemtap is not installed"; exit 1
fi
if [ -e $filename ];then
echo "File name $filename is duplicated"; exit 1
fi

#echo "Ok, check_env are safe"

}
search_func_name()
{
local name=$1
local out=`grep -w $name $kallsyms | awk '{printf $3}'`
local ret=0

# $name does not exist in $kallsyms
[ -z $out ] && ret=1

return $ret
}

add_line()
{
echo "$1" >> $filename
}

add_begin() {
add_line "#!/usr/local/bin/stap"
add_line ""
add_line "probe begin"
add_line "{"
add_line " printf(\"start\n\")"
add_line "}"
}

fill_up_name_with_module() {
local out=""
local name2=$1

for mod in ${{mod_array[@]}mod_array[@]};do
out=`echo $name2 | grep $mod`
if [ $out ];then
add_line "probe module(\"$mod\").function(\"$name2\") {"
add_line " printf (\"$name2 called\n\")"
add_line "}"
fi
done
}

fill_up_name(){
local name=$1
local count=$2

# add "probe begin" to script
[ $count -eq 1 ] && add_begin


if [ $module -eq 0 ];then
add_line ""
add_line "probe kernel.statement(\"$name\") {"
add_line " printf (\"$name called\n\")"
add_line "}"
else
fill_up_name_with_module $name
fi
}

check_env

while getopts ":m:h" GETOPTS
do
case $GETOPTS in
m) module=1
echo "module mode is not tested well...";;
h) usage;;
*) usage;;
esac
done

count=1
for num in ${{func_array[@]}func_array[@]};do #
search_func_name $num
[ $? -eq 1 ] && continue

fill_up_name $num $count
((count++))
done



この記事へのコメント

   

WWW を検索 Linux Blue を検索
プロフィール

uni
仙台でLinuxのエンジニアをしています。 忘備録もかねて主にLinuxについて載せています。 ここからの情報が何かの役に立てば幸いです。
リンク集
Links

<< 2013年01月 >>
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
カテゴリアーカイブ
月別アーカイブ
最新記事
×

この広告は30日以上新しい記事の更新がないブログに表示されております。