Linuxカーネルソースコードを読むツール (1):cscope編

皆さん、Linuxカーネルのソースコードを読む時には、どのツールを使っているのでしょうか?ソースコードをインデックス化してくれるツールはいろいろありますよね。ブラウザで見るならLXR等は便利ですよね。

手元のソースコードを見る時に便利だと僕が思っているのは、cscope, vi, ctags の組み合わせです。文字端末で使う非常にクラッシックなツールですが、軽いですし、インデックスファイルもコピーすれば、どこでも見られるようになるのも嬉しいです。残念なのは、cscopeはその名の通りC言語では非常に使いやすいのですが、その他の言語のサポートが非常に弱いところです。シンプルなツールなので仕方ないですね。そんな cscope (+ ctags) ですが、Linuxカーネルで便利に使うにはちょっとしたコツがあると思っていますので、それを紹介したいと思います。

まずは使い方です。以下が cscope を起動した画面です。Linuxカーネルは /usr/include にあるような標準のインクルードファイルを参照しませんので、オプションに -k をつけて起動します。

Ctrl-N, P かカーソルキーでカーソルを移動して、探したいシンボルや文字列を入力するだけです。試しに、file_operations の定義を検索してみます。Find this global definition: のところに file_operations と入力してリターンを叩くと、いくつかの候補が表示されます。候補が1画面に収まらない場合は、スペースをタイプすると次のページに移動します。

明らかに 5 の fs.h のものが定義ですので、5 をタイプすると、vi が起動して、該当箇所が表示されます。

vi を :q で修了すると cscope に戻ります。cscope の終了は Ctrl-D です。

Find this C symbol: は、関数がどこで呼び出されているのか、大域変数がどこで参照されているのかなどを調べるのに便利です。Find this text string: は、部分的な文字列からシンボルやコメント内の情報を探す時、またマクロが間に入ってうまくシンボルを探せない時に全文検索したい時などに便利です。

さて、次は vi + ctags です。例として do_page_fault を追ってみましょう。まずは、cscope で do_page_fault を探します。Find this global definition: を使えば良いのですが、以下は Find this C symbol: で検索してみた例です。

4 をタイプして do_page_fault の関数定義に移動します。

__do_page_fault へカーソルを移動し、Ctrl-] をタイプすると、__do_page_fault の関数定義に移動します。元来たところに戻りたい時には Ctrl-T をタイプします。Ctrl-], Ctrl-T での移動が便利なのは、どこから移動したのかの場所をスタックで覚えてくれてるところです。例えば、do_page_fault → __do_page_fault → handle_mm_fault → __handle_mm_fault → handle_pte_fault → do_fault とCtrl-] をタイプして追っていった時、Ctrl-T で1つまえの関数に戻ることができ、最終的には do_page_fault まで戻れます。つまり、caller/calleeの間を行ったり来たりするのが簡単にできるのが、コードを追う時に便利だと思います。

最初の方で、ちょっとしたコツがあると書きましたが、それはインデックス化についてです。cscope はカレントディレクトリに cscope.files と言う名前のファイルがあれば、そこに書かれているファイル名を検索対象とします。cscope.files を作成する Makefile のターゲットもデフォルトで入っていますが、ありとあらゆるファイルを入れてくれてしまいます(さすがにCPUアーキテクチャ依存部だけは限定してくれますが)。特に、不必要なデバイスドライバやファイルシステムがたくさん入ってしまうのが、著しく検索の効率を下げてくれます。そこで、cscope.files に入っているファイル名を、できるだけ自分が見たい対象だけに限定することで、効率よく検索することができるようになります。自分用の cscope.files ができれば、ctags には cscope.files の内容を与えれば、同じように見たいところに移動してくれるようになります。

ctags は tags という名前のファイルをインデックスとして作りますが、これはただのテキストファイルです。先ほどの do_page_fault の例で __do_page_fault に移動しようとした時、tags が以下のようになっていると、上の書かれている行の方へ移動してしまい、適切な関数定義の方には移動してくれません。

そこで、これはただのテキストファイルですから、関数定義の方が上になるように編集すれば、適切な方に移動してくれるようになります。ちょっと一手間ですが、ソースコードを読みながら、インデックスファイルを鍛えることで、効率よくコードを追いかけられるようになり、最初はわけわからないものが、だんだんと理解できるようになっていくと思います。

最後に…、僕はLinuxを「リヌックス」と発音しているのですが、若い人に「それ何ですか?」と聞かれ、自分の年齢を再認識しました。次回は Eclipse 編です。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です