i4fumi's blog

オープンソースなど

ソースコードを読むときのツール

最近、もっとソースコードを読まねばと思うようになったので、 ソースを読むときに使えるツールを調べてみました。

ソースの読み方は、エディタなどで静的に読み進めるやり方と、 デバッガなどで実際にプログラムを動かしてみるやり方の2つに大別できると思います。 以下、静的解析・動的解析という視点で自分が使っているもの/使いそうなものを挙げてみます。

静的解析

タグファイルを生成してくれます。 タグファイルがあれば、エディタを使ってソースコードを読むとき、 簡単に関数定義や関数の呼び出し元にジャンプできます。 (使い方は、vim globalとかで検索)

コールグラフを生成してくれます。 コールグラフとは、関数の呼び出しスタックを一覧にしたものです。 cflowは関数の呼び出しごとにインデントして一覧を生成します。

$ cflow -m onig_parse_make_tree -bn --omit-arguments --omit-symbol-names regparse.c

 1 onig_parse_make_tree() <int () at regparse.c:6199>:
 2     names_clear() <int () at regparse.c:620>:
 3         IS_NOT_NULL()
 4         onig_st_foreach()
 5         i_free_name_entry() <int () at regparse.c:447>:
 6             xfree()
 7             IS_NOT_NULL()
 8         xfree()
 9     scan_env_clear() <void () at regparse.c:925>:
10         BIT_STATUS_CLEAR()
11     parse_regexp() <int () at regparse.c:6171>:
12         fetch_token() <int () at regparse.c:3236>:
13             PFETCH()
14             IS_MC_ESC_CODE()
15             IS_SYNTAX_OP()
16             PPEEK_IS()
17             IS_SYNTAX_OP2()
18             fetch_range_quantifier() <int () at regparse.c:2347>:
19                 IS_SYNTAX_BV()
20                 onig_scan_unsigned_number() <int () at regparse.c:1601>:
21                     PFETCH()

(コールグラフは、gprofやvalgrindなどの動的解析ツールを使うやり方もある)

動的解析

GDBCUIフロントエンドです。gdbをそのまま使うより、cgdbからgdbを使ったほうがいろいろ捗ります。 ただ、マルチバイト文字に対応していません。

  • トレーサ

トレーサとは関数や変数の値を、実行された順に出力するツールです。

strace (1)コマンドはシステムコールのトレーサです。 簡単に使えて便利。

ctraceは、Cのソースコードにトレース出力用のコードを埋め込みます。 ctraceが変換したソースコードをコンパイルして実行すると、トレースが出力されるという仕組みです。

自分は今のところ、あまりトレーサは使わず、printfしまくる派です。

ソースコードの読み方

青木峰郎さんの「Rubyソースコード完全解説」(通称RHGRuby Hacking Guide)という素晴らしすぎる本があります。 この本はたまたまRubyソースコードを解説していますが、 なにもないところから、どうやってソースコードを読み進めていけばいいのか、 そのやり方を具体的に示した指南書だと思います。

全文が公開されています。神!