まぶち氏からptraceのサンプルない?って言われたのでstraceを紹介しました。straceはptraceの難しいところをどうしているのか見るには良いですが、初めてptraceを使う人が見るもんじゃない気がします。
入門に使えると信じて、簡単なサンプルを作ってみたので公開。Linux専用です。 ソースコードはこちらからどうぞ。
(2008年7月25日追記)需要はなさそうなものの、一応ライセンスを明確にしました。修正BSDライセンスです。
うまくいけばトレース対象のシステムコール名がずらっと表示されるはずです。以下に私の環境での実行結果を示します。
$ gcc -Wall 20080724_ptrace_simple.c $ ls -l 合計28 -rw-r--r-- 1 katsuhiro katsuhiro 8679 2008-07-24 02:12 20080724_ptrace_simple.c -rwxr-xr-x 1 katsuhiro katsuhiro 13367 2008-07-24 02:28 a.out $ ./a.out ls -la 1115: child started 1115: sys out( 11): execve 1115: sys in(122): uname 1115: sys out(122): uname 1115: sys in( 45): brk 1115: sys out( 45): brk 1115: sys in( 33): access 1115: sys out( 33): access (略) 1115: sys in( 4): write -rwxr-xr-x 1 katsuhiro katsuhiro 13367 2008-07-24 02:28 a.out 1115: sys out( 4): write 1115: sys in( 6): close 1115: sys out( 6): close 1115: sys in( 91): munmap 1115: sys out( 91): munmap 1115: sys in(252): exit_group 1115: exited, st:0
動作はDebian GNU/Linux 4.0(etch) で確認しました。さほど変なことはやっていないはずなので、最近のLinuxディストリビューションなら問題ないと思います。たぶん…。
仕組みとしてはforkした後に親プロセスは監視役、子プロセスは監視対象、で役割分担します。
親プロセスの仕事はwait -> ptrace(PTRACE_SYSCALL, ...) を繰り返すことです。子プロセスに何か変化があるとwaitから戻ってくるので、その都度何が起きたか調べます。イベントには色々ありますが、サンプルで見ている種類をざくっと紹介します。
子プロセスにシグナルを渡さないと、子プロセスがシグナルを認識できません。逆に言うと監視役の親プロセスのさじ加減次第では、子プロセスに飛んで来たシグナルを消すこともできてしまいます。ただしSIGKILLとSIGSTOPは消せません。
受け取ったシグナルがSIGTRAPだったら、システムコールの入口/出口で止まったことを表しますので、システムコール番号の解析をします。
子の仕事はptrace(PTRACE_TRACEME, ...) を実行して「監視される準備」を整えるだけです。その後は余計なことをせずに監視対象にしたいプログラムをexecしてください。
< | 2008 | > | ||||
<< | < | 07 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | 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 | - | - |
合計:
本日:
管理者: Katsuhiro Suzuki(katsuhiro( a t )katsuster.net)
This is Simple Diary 1.0
Copyright(C) Katsuhiro Suzuki 2006-2023.
Powered by PHP 8.2.15.
using GD bundled (2.1.0 compatible)(png support.)