Upload
satoru-takeuchi
View
27.088
Download
0
Embed Size (px)
Citation preview
2
はじめに● 大規模ソースコード(以下ソースと記載)を、未
経験者が前提知識を持たない状態で読もうとすると、ほぼ確実に挫折する● 例えばLinux kernelの場合一千万行をゆうに超える● 一日千行読んでも一万日かかる…
● 本スライドは大規模ソースを読む上でのコツをいくつか紹介
● 想定読者● これまで大規模ソースを見たことが無い人/見よう
としたが、挫折した人● Linux/UNIXユーザ
3
目次● ソースを読む前
● 目的の明確化● 設計意図の理解● 読むソースの絞り込み
● ソースを読むとき● タグジャンプツールの使用● 実際に動かしてみる
● まとめ
4
目的の明確化● まず自分がどの機能の実装を理解したいのかを明確化
● 目的が無いまま闇雲にソースの字面を眺めるだけでは内容の理解は困難
● 「全てを理解しなくては!」や「とりあえずmain()から芋づる式に辿ろう」という考えかたは挫折への近道● 大規模プログラムでは、全ソースを完璧に理解して
いる開発者は少ない/居ない。全部を理解していないのは別に恥ずかしいことではない
● 最終目的はあくまで機能の実装を理解することであり、ソースを読むのは手段であることを常に意識しておく
5
設計意図の理解● 機能が何のためにあるのか、どういう方針で設
計されているかという意図を理解する● ドキュメントを見る
● マニュアル、コメント、パッチのコミットログ● 自分なりの仮説を立てる
● この機能を実現するためには設計はこうなっているはず…と考える
● 構造体の関連図がわかっていると、仮説を立てやすい
● アルゴリズム+データ構造=プログラム● 仮説が外れていても、無いよりは全然よい
6
gitの活用● 設計意図を知るのにはgitが役立つ
● 無論ソースがgitで管理されていることが前提● 他のVCSについては割愛
● ここでは2つのgitコマンドを紹介● git log● git blame
7
git log● git log <path>: <path>を変更したパッチの一覧を
表示● 機能追加、実装の再設計をしたパッチセットの先頭
パッチに設計意図が書いていることが多い● パッチそのものではなく、当該パッチセットを開発MLに投稿した際の”[PATCH 0/X]”というメールに書いていることもある
8
git blame● git blame <file>: <file>の各行を最後に変更した
パッチを表示● <file>の各行が、どのような意図で現在そうなって
いるかがわかる● もちろんまともなコミットログがあることが前提
● git logより細かい粒度の情報が得られる
9
読むソースの絞り込み● ソース全体のうちの、どこを読めばいいのか、及び、どこを読まなくてよいのかを絞り込む● 余計なところを”読まない”ことが重要
● なるべく読む対象のソースを少なくする● 大規模ソースは大抵複数、かつ階層状のモ
ジュールに細分化されている
10
絞り込みの例● 興味のある機能の実行中に出てくるメッセージ
を用いてgrepをかけることによって、関連ソースの位置を知る
● デバッガを使ってプログラム内の興味のある機能を動かしてみることによって、当該機能のソース上の位置を知る
11
実際にソースを読むにあたって● ここからようやく実際にソースを熟読する● これまでに述べたことが全てできていれば、必要な作業の八割程度は終わっている● 一部しかできていなくても、漫然とソースを読むよ
りは、はるかに良い● ソースを読む前の作業は戦略、実際にソースを読む作業は戦術
12
タグジャンプツールの使用● ソースを読むにあたって、テキストエディタと基本コマン
ドだけでソースを読むのは非常に面倒。以下、一例。● foo()という関数内でbar()という関数を呼んでいる。bar()が何
をしている関数か知りたい● foo()の引数の型であるstruct hogeの定義を知りたい
● grepコマンドなどでソースを全て検索した上で、マッチしたファイルを開いてカーソルを所定の場所に移動、といった操作を毎回実行するのは面倒、かつ非効率
● bar()やstruct hogeの調査後、foo()の調査を再開したいような場合はさらに面倒
● これを解決するのがタグジャンプツール
13
タグジャンプツールの仕組み● ソースコードを走査して、ソースのどこにどのようなシンボル(前述の例でいうとfoo,bar,およびhoge)が定義されており、それぞれどこで使用されているのかを記録したデータベースを作成
● エディタなどからシンボルを指定すると、当該シンボルの定義場所、および使用箇所に自動的にジャンプ● 検索ごとの全ソース調査が不要なため、高速。マシ
ンパワーも節約可能● ジャンプ履歴を覚えているため、たとえばfoo()から
bar()へのジャンプ後に、元のfoo()に戻ることも可能
14
タグの形式● タグには色々な形式があり、それぞれ一長一短。以下に著名なものを記載● cscope● GNU Global● ctags● etags
● 詳細はそれぞれのドキュメントを参照● タグジャンプ相当機能を内蔵している開発環境
もある(例: eclipse)
15
プログラムを動かしてみる● ソースを読みつつプログラムを実際に動かして
みるのは非常に有用● デバッガを用いてプログラムを動かしてみることに
よって、関数の呼び出し関係、引数、およびデータ構造の意味を知る
● 興味のある箇所にprintf()などのデバッグメッセージを突っ込んで実行してみる
● ソースを少し変更した上で挙動の変化を見る● ソースの読み/書き、実行を行き来することに
よってソースの内容を理解
16
まとめ● 大規模ソースを読むためにはソースを読む前/読
むときについて様々なコツがある● 最終目標はソースを読むことではなく、実装を
理解することだと常に意識する● 機能の実装を理解するために必要なことの八割
は、ソースを読む前に終わっている● 実際にソースを読む際も、ただ読むだけではな
く、タグジャンプツールを使ったり、読み書き実行を行き来したりして、作業を効率化する
17
Happy Hacking!