Entry

ソースコード解析におけるアタリのつけ方とか(その1)

2012年08月19日

仕事でプログラムを書いていると,デバッグ以外に他人のソースコードを読む機会がたくさんあるわけですけれど,大抵の場合,漫然と読んでいるのではなく目的があります。例えば,字句解析する際のバッファ管理の方法を知りたいから GCC を読むとか,ベクタオブジェクトの描画系はどうやってるんだろと思って,Inkscape のソースを読むとかいった具合。もちろん,それらが最適なプログラムとは限らないわけですけれど,他の人の考え方を取り入れるには,下手な能書きが書かれた本を読むよりも,ソースを読む方が手っ取り早かったりします。

で,ま,目的をもってソースを読むわけですけれど,この場合,まずもって目的のソースにたどり着けなくちゃいけません。全然関係ないところを読むのは時間の無駄ですから。この点,巷には,ソースの読み方をあちこちで紹介しているわけですけれど,あたしはあまりこゆ読み方はしていない気がします。例えば,某所で紹介している方法は次のようなもの。

  • ファイル名やコメントから処理を判断する
  • デバッガを使って main 関数から順に処理を追っていく

はじめの方法は,例えば,grep(1) や ctags,GNU Global なんかを使って,怪しそうな処理を片っ端からあげつらっていくみたい。しかし,特定の処理に対して,人間が取り決めた識別子を狙い撃ちするのは,なかなかできることではありません。メモリ管理について,memory.c なんてソースがあるならいいとしても,mmng.c なんてこともあり得るし,util.c なんかに隠れてるかもしれない(関数名等の識別子も同じ)。こゆ方法は,アヒルが混ざってる白鳥の群れに対して,アヒルだけを打ち落とすようなもんです。方法としては下手っぴだと思う。

もうひとつの方法である,main 関数から云々みたいな話は,ほんとにやってる人がいるなら見てみたい。少し大きなファイルになると,まず途中で挫折すると思う。

ソースのアタリをつける方法は,ある程度経験によるものが大きいのだけれども,指標になる方法はいくつかあります。まずひとつ挙げると,それは「分かっていることから逆算する方法」です(残りは後日)。

例えば,C言語で書かれたメモリ管理のプログラムを読む場合を考えます。いきなり memory.c がない……と途方にくれる必要はありません。

冷静になって考えると,こうしたプログラムの場合,ほとんど確実といっていいほど使われる関数があります。それは言うまでもなく,malloc(3) をはじめとした *alloc 系の関数や free(3) です。もちろん,標準関数を使わないで OS の API を直接叩いているかもしれないので,GlobalAlloc(Windows 系の場合)なんかが使われている可能性も考えておきます。メモリ確保に使われる関数をどれだけ知っているかは経験によるけれども,ま,「そこら辺の関数」はメモリ管理のプログラムを書く以上絶対に使われているわけです。まずは,こいつを grep(1) で探し出す。あとは,これらのメモリ管理用の関数を使っている関数の呼び元をたどっていけばいい。

このように,プログラムを書く上では,ほとんど絶対にはずせないキモがあるわけです。ファイルの書き出しなら絶対 fopen(3) を使っているはず,とか,スレッド管理だったら pthread や _beginthread(ex)(Windows の場合)を使わなきゃ書けないとかいった具合です。ソースを読むときは,まず,そのキモを特定できるか冷静になって考えてみるといい。カーネル空間を使うプログラムだったら,ほぼこの方法だけで目的のソースにたどり着けます。

難しいのは,ユーザ定義のデータ構造を解析する場合です。これはプログラマが勝手に考えたものなので,あるメンバが実際何に使われているのか解析するのには骨が折れます。これについてもそれなりに方法があるので,これは,また別の機会にでも。

プログラマは論理的な思考を商売の種にしているのだから,ソースの解析も論理的に行いたいもんです。当て勘でやるようなもんじゃないんだよね,とかとか。

Trackback
Trackback URL:
Ads
About
Search This Site
Ads
Categories
Recent Entries
Log Archive
Syndicate This Site
Info.
クリエイティブ・コモンズ・ライセンス
Movable Type 3.36
Valid XHTML 1.1!
Valid CSS!
ブログタイムズ

© 2003-2012 AIAN