Slide 1

Slide 1 text

1 大規模ソースコードの読み方 v1.0.0 2016/2/13 Satoru Takeuchi

Slide 2

Slide 2 text

2 はじめに ● 大規模ソースコード(以下ソースと記載)を、未 経験者が前提知識を持たない状態で読もうとす ると、ほぼ確実に挫折する ● 例えばLinux kernelの場合一千万行をゆうに超える ● 一日千行読んでも一万日かかる… ● 本スライドは大規模ソースを読む上でのコツを いくつか紹介 ● 想定読者 ● これまで大規模ソースを見たことが無い人/見よう としたが、挫折した人 ● Linux/UNIXユーザ

Slide 3

Slide 3 text

3 目次 ● ソースを読む前 ● 目的の明確化 ● 設計意図の理解 ● 読むソースの絞り込み ● ソースを読むとき ● タグジャンプツールの使用 ● 実際に動かしてみる ● まとめ

Slide 4

Slide 4 text

4 目的の明確化 ● まず自分がどの機能の実装を理解したいのかを明確化 ● 目的が無いまま闇雲にソースの字面を眺めるだけでは 内容の理解は困難 ● 「全てを理解しなくては!」や「とりあえずmain()か ら芋づる式に辿ろう」という考えかたは挫折への近道 ● 大規模プログラムでは、全ソースを完璧に理解して いる開発者は少ない/居ない。全部を理解していな いのは別に恥ずかしいことではない ● 最終目的はあくまで機能の実装を理解することであり、 ソースを読むのは手段であることを常に意識しておく

Slide 5

Slide 5 text

5 設計意図の理解 ● 機能が何のためにあるのか、どういう方針で設 計されているかという意図を理解する ● ドキュメントを見る ● マニュアル、コメント、パッチのコミットログ ● 自分なりの仮説を立てる ● この機能を実現するためには設計はこうなってい るはず…と考える ● 構造体の関連図がわかっていると、仮説を立て やすい ● アルゴリズム+データ構造=プログラム ● 仮説が外れていても、無いよりは全然よい

Slide 6

Slide 6 text

6 gitの活用 ● 設計意図を知るのにはgitが役立つ ● 無論ソースがgitで管理されていることが前提 ● 他のVCSについては割愛 ● ここでは2つのgitコマンドを紹介 ● git log ● git blame

Slide 7

Slide 7 text

7 git log ● git log : を変更したパッチの一覧を 表示 ● 機能追加、実装の再設計をしたパッチセットの先頭 パッチに設計意図が書いていることが多い ● パッチそのものではなく、当該パッチセットを開発 MLに投稿した際の”[PATCH 0/X]”というメールに 書いていることもある

Slide 8

Slide 8 text

8 git blame ● git blame : の各行を最後に変更した パッチを表示 ● の各行が、どのような意図で現在そうなって いるかがわかる ● もちろんまともなコミットログがあることが前提 ● git logより細かい粒度の情報が得られる

Slide 9

Slide 9 text

9 読むソースの絞り込み ● ソース全体のうちの、どこを読めばいいのか、 及び、どこを読まなくてよいのかを絞り込む ● 余計なところを”読まない”ことが重要 ● なるべく読む対象のソースを少なくする ● 大規模ソースは大抵複数、かつ階層状のモ ジュールに細分化されている

Slide 10

Slide 10 text

10 絞り込みの例 ● 興味のある機能の実行中に出てくるメッセージ を用いてgrepをかけることによって、関連ソー スの位置を知る ● デバッガを使ってプログラム内の興味のある機 能を動かしてみることによって、当該機能の ソース上の位置を知る

Slide 11

Slide 11 text

11 実際にソースを読むにあたって ● ここからようやく実際にソースを熟読する ● これまでに述べたことが全てできていれば、必 要な作業の八割程度は終わっている ● 一部しかできていなくても、漫然とソースを読むよ りは、はるかに良い ● ソースを読む前の作業は戦略、実際にソースを読む 作業は戦術

Slide 12

Slide 12 text

12 タグジャンプツールの使用 ● ソースを読むにあたって、テキストエディタと基本コマン ドだけでソースを読むのは非常に面倒。以下、一例。 ● foo()という関数内でbar()という関数を呼んでいる。bar()が何 をしている関数か知りたい ● foo()の引数の型であるstruct hogeの定義を知りたい ● grepコマンドなどでソースを全て検索した上で、マッチ したファイルを開いてカーソルを所定の場所に移動、と いった操作を毎回実行するのは面倒、かつ非効率 ● bar()やstruct hogeの調査後、foo()の調査を再開したいよ うな場合はさらに面倒 ● これを解決するのがタグジャンプツール

Slide 13

Slide 13 text

13 タグジャンプツールの仕組み ● ソースコードを走査して、ソースのどこにどのような シンボル(前述の例でいうとfoo,bar,およびhoge)が定義 されており、それぞれどこで使用されているのかを記 録したデータベースを作成 ● エディタなどからシンボルを指定すると、当該シンボ ルの定義場所、および使用箇所に自動的にジャンプ ● 検索ごとの全ソース調査が不要なため、高速。マシ ンパワーも節約可能 ● ジャンプ履歴を覚えているため、たとえばfoo()から bar()へのジャンプ後に、元のfoo()に戻ることも可能

Slide 14

Slide 14 text

14 タグの形式 ● タグには色々な形式があり、それぞれ一長一 短。以下に著名なものを記載 ● cscope ● GNU Global ● ctags ● etags ● 詳細はそれぞれのドキュメントを参照 ● タグジャンプ相当機能を内蔵している開発環境 もある(例: eclipse)

Slide 15

Slide 15 text

15 プログラムを動かしてみる ● ソースを読みつつプログラムを実際に動かして みるのは非常に有用 ● デバッガを用いてプログラムを動かしてみることに よって、関数の呼び出し関係、引数、およびデータ 構造の意味を知る ● 興味のある箇所にprintf()などのデバッグメッセー ジを突っ込んで実行してみる ● ソースを少し変更した上で挙動の変化を見る ● ソースの読み/書き、実行を行き来することに よってソースの内容を理解

Slide 16

Slide 16 text

16 まとめ ● 大規模ソースを読むためにはソースを読む前/読 むときについて様々なコツがある ● 最終目標はソースを読むことではなく、実装を 理解することだと常に意識する ● 機能の実装を理解するために必要なことの八割 は、ソースを読む前に終わっている ● 実際にソースを読む際も、ただ読むだけではな く、タグジャンプツールを使ったり、読み書き 実行を行き来したりして、作業を効率化する

Slide 17

Slide 17 text

17 Happy Hacking!