Debug Hacksを読んでたら、kprobesっていうデバッグツールの話があった。
自分でモジュール作ってinsmodするだけで、カーネル再コンパイルなしで、ある実行地点でのカーネル内変数を調べるツールだそうで。
プロセスのユーザ空間(=デバッギのユーザ空間)に対してデバッガプロセスがプローブする場合は1
- デバッガプロセスがptrace辺りを使ってデバッギのメモリ空間上の指定アドレス上にあるアセンブリ命令をint 3に書き変えて2
- デバッギプロセス実行中にそのint 3命令実行して発生したSIGTRAPをデバッガプロセスがフック(=これも事前にptraceで設定する)して
- デバッガプロセスがptraceでデバッギプロセスのメモリ空間から値をread
っていう流れが普通だと思う。kprobes.cのコメントを見てみると、kprobesの場合もカーネルの指定命令アドレスにint 3を入れてるらしい。
/* * Called after single-stepping. p->addr is the address of the * instruction whose first byte has been replaced by the "int 3" * instruction. To avoid the SMP problems that can occur when we * temporarily put back the original opcode to single-step, we * single-stepped a copy of the instruction. The address of this * copy is p->ainsn.insn. ... * ... */
ただ、SMPの関係で色々対策が必要なんだね3。int 3を実行した後、例外ベクタにジャンプしてからどういう手順で処理してるかについてイメージがわかないから、今度ソース読んでみようかな。
あと、kprobesだと見たい変数(とくにローカル変数などCPUアーキテクチャとデバッグ情報からアドレスを割り出す必要のあるもの)のアドレスを探すのが大変だけど、
kprobes+GDBでそこを解決しようとしてるのがtracepointsってやつらしい。ふむふむ。
- 以前、デバッガについて書いた記事もどうぞ。 [↩]
- int 3はIA-32とかIntel architectureの場合の話です [↩]
- デバッギプロセスにプローブする場合に必要なマルチスレッド対策とどの程度一緒なのかは、まだよくわからない。 [↩]

