straceでシステムコールをトレースする
BINARY HACKS p311
straceってのは、
ptrace(PTRACE_SYSCALL, ...)でシステムコールの入り口と出口をフックして、システムコールの引数と戻り値を出力することです。
とのことです。AOPっぽい?
普通にHello, Worldを書いて試してみる。
taka@ubuntu:~$ more hello.c #includeint main() { printf("Hello, World\n"); } taka@ubuntu:~$ cc -o hello hello.c taka@ubuntu:~$ ./hello Hello, World taka@ubuntu:~$ strace ./hello execve("./hello", ["./hello"], [/* 17 vars */]) = 0 uname({sys="Linux", node="ubuntu", ...}) = 0 brk(0) = 0x804a000 old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fea000 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) old_mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fe8000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=17520, ...}) = 0 old_mmap(NULL, 17520, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7fe3000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/tls/i686/cmov/libc.so.6", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\220O\1"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=1232784, ...}) = 0 old_mmap(NULL, 1238972, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7eb4000 old_mmap(0xb7fd9000, 28672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x125000) = 0xb7fd9000 old_mmap(0xb7fe0000, 10172, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7fe0000 close(3) = 0 old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7eb3000 set_thread_area({entry_number:-1 -> 6, base_addr:0xb7eb38e0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 munmap(0xb7fe3000, 17520) = 0 fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fe7000 write(1, "Hello, World\n", 13Hello, World ) = 13 munmap(0xb7fe7000, 4096) = 0 exit_group(13) = ?
8行目くらいにopenシステムコールがありますが、戻り値がいきなり3になっています。
これが昨日のナゾを解くヒントになったわけですが、本書中にもあるように、
「設定ファイルを作ったのになぜか反映されない。果たして読み込まれているのだろうか」というときはstraceを使って、その設定ファイルがプログラムによって開かれているか確認すると便利です。
とのことで、もちろん、
strace ruby hello.rb
みたいなことも出来るので、いろんな場面で役立ちそうです。