sttsのソースコードMemoブログ

色々やってみた結果のMemo

systemtapを試してみる

以前からなんとなく気になっていたsystemtapを試してみました。
systemtapとは、kernelにプローブを挿入しデバッグするためのツールのようです。

ユーザ空間でしかプログラムを組まない人間なのでkernelデバッグとかはまったくしないのですが、システムコールが呼ばれるタイミングにプローブを挿入しておくとユーザ空間のデバッグに便利な気がして調べました。straceやltraceでもいいような気もしますが、OSで動く全てのプロセスを調べられない。

必要なパッケージのインストール

CentOSだったのでsystemtapとかsystemtap-runtimeパッケージをインストールしました。
その後、http://debuginfo.centos.org/から使用中のkernelに対応するkernel-debuginfoとkernel-debuginfo-commonパッケージをダウンロードしインストールしました。yumとかでは入らない。

動かしてみる

まず、スクリプトを書きます。forkとexecveシステムコールが呼ばれたときに表示する。スクリプトは、サンプルコードを参考に以下のようにしました。

probe syscall.fork
{
printf("%s (%d) fork\n", execname(), pid())
}
probe syscall.execve
{
printf("%s (%d) exec (%s)\n", execname(), pid(), argstr)
}

# stap fork.stp
で実行するとforkもしくはexecシステムコールが呼ばれるたびに1行表示されます。

# stap fork.stp
zsh (3043) fork
zsh (4027) exec (/bin/ls --color=tty)

signalも調べる

シグナルも調べたいときがあると思うので、スクリプトを書いて試してみました。スクリプトは以下

probe signal.send
{
printf("signal:%s from %s(%d) to %s(%d)\n", sig_name, execname(), pid(), pid_name, sig_pid )
}

以下のように実行表示されました。

# stap signal.stp
signal:SIGCHLD from ls(4042) to zsh(3043)
signal:SIGALRM from swapper(0) to screen(3041)
signal:SIGSEGV from a.out(4044) to a.out(4044)
signal:SIGCHLD from a.out(4044) to zsh(3043)

まとめ

試してみて気づいたのですがシステムコールやシグナルは、想像以上にたくさん使われています。ここから追いかけるのは大変そうです。素直にデバッガやltrace,straceを使った方が簡単かもしれません。かなり複雑なシステムで原因のプロセスも特定できていないときには役に立つかもしれません。

また、systemtapのドキュメントには、パフォーマンスを調べるときのスクリプトとかも載っていたのですが、これらは必要になった時に調べることにします。

TODO

これもそのうち調べたい。INOTIFY ファイルシステムイベントを監視する
http://www.linux.or.jp/JM/html/LDP_man-pages/man7/inotify.7.html

Frysk
動作している状態で動作したままcoreを出力したり、動作している状態のままスタックトレースが表示できるようです。