使い方
たとえば、 vim という名前のプロセスからシステムコール stat, open, stat64 されたときに第一引数(ファイル名)を監視するには以下のようにします。
$ sudo dtrace -n "syscall::open:entry, syscall::stat:entry, syscall::stat64:entry / execname == \"vim\" / { trace(copyinstr(arg0)) } "
説明
まず、 -n というのは「probe」の「name」を指定して dtrace する!という意味です。
$ sudo dtrace [-n [[[ provider: ] module: ] func: ] name [[ predicate ] action ]]
probe とは
probe というのは、 監視ポイントのことです。
以下のコマンドで監視ポイントの一覧を見ることができます。
$ sudo dtrace -l
たくさんあるので、 grep するといいです。
$ sudo dtrace -l | grep syscall
とにかくいろんな情報を監視できるのが分かりますね!
probe の指定方法
probe は固有の数字か、「provider:module:func:name」というコロンで区切られた文字列で指定します。
文字列で指定する場合は、さっきのように -n を使います。
$ sudo dtrace -n syscall::open:entry
syscall には module 名がないのでコロンコロンになってます。
また、
数字で指定する場合は、以下のように -i を使います。
$ sudo dtrace -i 18270
この数字は sudo dtrace -l で分かります。
action とは
action とは監視した情報をどのようにトレースするかという情報です。中括弧で囲って書きます。
たとえば、 プロセス名とプロセス ID を trace したい場合は、以下のようにします。
$ sudo dtrace -n "syscall::open:entry { trace(execname); trace(pid) }"
この中括弧の中には、 d 言語(別の D 言語と誤解しないように)というスクリプトのステートメント(文)を書きます。
trace 以外にも様々な関数があり、 execname や pid 以外にも様々な変数があります。
predicate とは
predicate とは監視した情報をフィルタリングする場合に使います。スラッシュで囲って書きます。
ここには、 d 言語の式を書きます。
たとえば、以下のようにすれば vim という名前のプロセスか emacs という名前のプロセスだけをトレースすることができます。
$ sudo dtrace -n "syscall::open:entry / execname == \"emacs\" || pid == \"vim\" / { trace(execname); trace(pid) }"
d 言語の詳細なドキュメントは
d 言語を別のファイルにする
d 言語を別のファイルにすることもできます
#! /usr/sbin/dtrace -s syscall::open:entry / execname == "emacs" || pid == "vim" / { trace(execname); trace(pid); } profile:::tick-100sec { trace("timeout!\n") exit(0) }
パーミッションを設定すれば、そのまま実行できます。
実際に実行してみる
こんな感じです。
$ sudo dtrace -n "syscall::open:entry, syscall::stat:entry, syscall::stat64:entry / execname == \"vim\" / { trace(copyinr(arg0)) } " > dtrace.txt & [1] 70629 dtrace: description 'syscall::open:entry, syscall::stat:entry, syscall::stat64:entry ' matched 3 probes $ vim hoge $ fg sudo dtrace -n "syscall::open:entry, syscall::stat:entry, syscall::stat64:entry / execname == \"vim\" / { trace(copyinstr(arg0)) } " > dtrace.txt ^C $ cat dtrace.txt CPU ID FUNCTION:NAME 0 17970 stat:entry /usr/lib/libncurses.5.4.dylib 0 17970 stat:entry /usr/lib/libiconv.2.dylib 0 17970 stat:entry /usr/lib/libgcc_s.1.dylib 0 17970 stat:entry /usr/lib/libSystem.B.dylib 0 17970 stat:entry /usr/lib/system/libmathCommon.A.dylib 0 17604 open:entry /dev/dtracehelper 0 18270 stat64:entry /Users/amachang/Downloads 0 18270 stat64:entry /Users/amachang 0 17970 stat:entry /usr/share/vim/vim70 0 17970 stat:entry /usr/share/vim 0 18270 stat64:entry /Users/amachang/Downloads 0 17970 stat:entry hoge 0 17604 open:entry /usr/share/terminfo/78/xterm-color 0 17604 open:entry . 0 18270 stat64:entry /usr/share/vim 0 17970 stat:entry /usr/share/vim/vimrc 0 17970 stat:entry /usr/share/vim/vimrc 0 17604 open:entry . 0 18270 stat64:entry /Users/amachang 0 17970 stat:entry /Users/amachang/.vimrc 0 17970 stat:entry /Users/amachang/.vimrc : :
おおお dylib が読み込まれて、設定ファイルが読み込まれていく様が分かりますね!