DTrace VM 内部コード
DTrace は実際の情報採取処理がカーネルモジュールで実施されていて、その際の処理は一種の VM 上で稼動するイメージとなっている。
で、DTrace の内部処理に関して調べるついでに、内部コードに関して色々試してみた。
とりあえず、vn_open(= open(2) システムコールの下請けみたいなもの)実行時のスレッド状態フラグを表示させる、というありがちな D スクリプトから、内部コードを生成してみる。
$ cat show_t_flag.d fbt::vn_open:entry { printf("%p", curthread->t_flag); } $ dtrace -S -s show_t_flag.d DIFO 0x6eab40 returns D type (integer) (size 2) OFF OPCODE INSTRUCTION 00: 29010001 ldgs DT_VAR(256), %r1 ! DT_VAR(256) = "curthread" 01: 25000002 setx DT_INTEGER[0], %r2 ! 0x24 02: 07010201 add %r1, %r2, %r1 03: 20010001 lduh [%r1], %r1 04: 23000001 ret %r1 NAME ID KND SCP FLAG TYPE curthread 100 scl glb r D type (pointer) (size 8) $
やぁ、まんま SPARC アセンブラだなぁ。curthread の保持するアドレスに、t_flag オフセット分の 0x24 を足した値で間接アドレッシングして値を取得、といったところか。コレなら読める。
シンボルテーブル(勝手にそう呼んじゃうけど、要するに DT_VAR() 参照先)は表示されるのに、整数値テーブル(これまた勝手にそう呼んじゃうけど DT_INTEGER[] 参照先)は表示されないのね。まぁ、コメントがあるから良いか。
そういう意味では、DT_VAR() の添え字は 10 進数なのに、シンボルテーブル側の表示は 16 進数、ってのも何か変だけどね。
で、気になるのが、printf() 部分の内部コードが生成されないこと。フォーマッティングとかはどうなるんだ?
ということで、もうちょっと複雑なスクリプトを食わせてみる。
$ cat show_t_flag2.d fbt::vn_open:entry { printf("%p->t_flags=%d", curthread, curthread->t_flag); } $ dtrace -S -s show_t_flag2.d DIFO 0x6eab40 returns D type (pointer) (size 8) OFF OPCODE INSTRUCTION 00: 29010001 ldgs DT_VAR(256), %r1 ! DT_VAR(256) = "curthread" 01: 23000001 ret %r1 NAME ID KND SCP FLAG TYPE curthread 100 scl glb r D type (pointer) (size 8) DIFO 0x75dae0 returns D type (integer) (size 2) OFF OPCODE INSTRUCTION 00: 29010001 ldgs DT_VAR(256), %r1 ! DT_VAR(256) = "curthread" 01: 25000002 setx DT_INTEGER[0], %r2 ! 0x24 02: 07010201 add %r1, %r2, %r1 03: 20010001 lduh [%r1], %r1 04: 23000001 ret %r1 NAME ID KND SCP FLAG TYPE curthread 100 scl glb r D type (pointer) (size 8) $
あぁ、そういうことか。
この結果を元に他にも色々試してみた結果、結局内部コードが生成されるのは:
- 評価の必要な「式」
- 代入ステートメント
に限定されていることがわかった。つまり、printf() 等のフォーマッティング部分は、カーネル内部では実施せずに、ユーザ空間= dtrace コマンド側に持ち越している模様。
結局試し損ねたけど、多分「条件指定」も内部コードを生成しているのじゃないかな?
VM 内部コード処理ループに相当する関数が、usr/src/uts/common/dtrace/dtrace.c で定義されている dtrace_probe() なのだが、これを見ても printf() 類は別処理扱いになっているので、多分合っている筈。