tips – ltrace で共有ライブラリの関数呼び出しをトレースする

http://0xcc.net/blog/archives/000103.html
より。

ltrace [ {オプション} ] {実行するプログラム} [ {引数..} ]

のようにすると、任意のプログラムを動的にブレークポイントを挿入して実行し、共有ライブラリとシステムコールの呼び出しをトレースすることができます。
簡単にいうと GDB より高級なデバッガのような感じです。
 
Linux の場合は標準でインストールされることが多そうですが、yum や apt-get を使う場合は

yum install ltrace

または

apt-get install ltrace

でインストールできます。
また FreeBSD の場合も ports に含まれているため、

portinstall sysutils/ltrace

とすることでインストールできます。
 
利用例:
ls / を実行しライブラリ関数をトレースし、log.txt にトレース結果を出力する(-o)。

$ ltrace -o log.txt ls / # プログラムの実行とトレース
bin dev home lib media mnt proc sbin tmp var
boot etc initrd lost+found misc opt root sys usr
$ cat log.txt # トレース結果参照
_start(0xbff1abd4, 0xbff1abd7, 0, 0xbff1abd9, 0xbff1abf0 <unfinished …>
__libc_start_main(0x804ea41, 2, 0xbfe34df4, 0x8056f58, 0x8056fac <unfinished …
setlocale(6, “”) = “en_US”
bindtextdomain(“coreutils”, “/usr/share/locale”) = “/usr/share/locale”
textdomain(“coreutils”) = “coreutils”
__cxa_atexit(0x8053701, 0, 0, 0x805b570, 0xbfe34d68) = 0
is_selinux_enabled(0x8053701, 0xd1bbe4, 0x32206e75, 0x34312036, 0x3a30333a) = 0
isatty(1) = 1
# 以下略

利用例2:
ライブラリのトレースだけでなくシステムコールもトレース(-S)し、
関数呼び出しの関係を階層構造で出力する(-n {number})。

$ ltrace -o log2.txt -S -n 2 ls /
# 略

$ cat log2.txt
SYS_uname(0xbfe4106c) = 0

SYS_brk(NULL) = 0x99ca000
SYS_access(0xbffdc1, 4, 0xc03fd4, 0xbffdc1, 4) = -2
SYS_open(“/etc/ld.so.cache”, 0, 00) = 3
# 中略
SYS_munmap(0xb7f92000, 4096) = 0
_start(0xbff20bd4, 0xbff20bd7, 0, 0xbff20bd9, 0xbff20bf0 <unfinished …>
    __libc_start_main(0x804ea41, 2, 0xbfe412c4, 0x8056f58, 0x8056fac <unfinished
 …>
        setlocale(6, “” <unfinished …>
            SYS_open(“/usr/lib/locale/locale-archive”, 32768, 01540) = 3
            SYS_fstat64(3, 0xd301a0, 0xd2eff4, 0xd301a0, 0xd0fc60) = 0
            SYS_mmap2(0, 0x200000, 1, 2, 3) = 0xb7d82000
            SYS_mmap2(0, 204800, 1, 2, 3) = 0xb7d50000
            SYS_mmap2(0, 4096, 1, 2, 3) = 0xb7d4f000
            SYS_close(3) = 0
        <... setlocale resumed> ) = “en_US”
# 以下略

利用例3: プログラムの経過時間を一緒に出力する(パフォーマンスチューニング用途など)

$ ltrace -tt -o log.txt ls / # マイクロ秒単位
19:56:53.267749 SYS_uname(0xbff417dc) = 0
19:56:53.267865 SYS_brk(NULL) = 0x9e12000
19:56:53.267917 SYS_access(0xbffdc1, 4, 0xc03fd4, 0xbffdc1, 4) = -2
# 以下略

-t にすると 19:56:53 のように秒単位、-tt にすると例のようにマイクロ秒単位、 -ttt にすると マイクロ秒単位で 1201517930.289331 のような UNIX タイムスタンプ形式になります。