Skip to main content
セキュリティプログラミング
    キャンプ2011

  ゜ヌスコヌドの読み方

   よしおかひろたか
     2011幎8月11日
講垫玹介
●   よしおかひろたか、Debug Hacks著者、カヌネル
    読曞䌚䞻宰、YLUG(暪浜Linux Users Group)、勉
    匷䌚勉匷䌚
●   未来のい぀か/hyoshioの日蚘
    http://d.hatena.ne.jp/hyoshiok
●   hyoshiok@gmail.com
●   http://twitter.com/hyoshiok



                                        2
お題
●   ゜ヌスコヌドの読み方




                 3
プログラマに必芁な぀の
    スキル
●   ゜ヌスコヌドを読むチカラ
●   デバッグするチカラ
●   テストをするチカラ




                   4
぀のスキルをどう身に぀
    けるか
●   孊校では教えおくれない
●   教科曞を読む
●   実際のプロゞェクトで経隓する
    ●   オヌプン゜ヌスのプロゞェクトに参加
●   垫匠に匟子入り
    ●   そこでプログラミングキャンプだ



                             5
゜ヌスコヌドの読み方
●   ゜ヌスコヌドっお䜕
●   人間がプログラミング蚀語などを甚い
    お蚘述したもの。
    ●   そのたたではコンピュヌタは実行できないので
        、通垞、コンパむラず呌ばれる゜フトりェアで
        盎接実行できる圢匏に倉換しお実行されるか、
        むンタプリタず呌ばれる゜フトりェアで字面を
        解釈し実行される。


                            6
トラブルシュヌティングず
    ゜ヌスコヌドの読み方
●   トラブルシュヌティングず問題の理解
●   実践的なコヌドの理解




                        7
゜ヌスコヌドを読むチカラ
●   プログラマの基瀎䜓力
    ●   ゜フトりェア開発コストの倧郚分は保守
    ●   䞍具合修正、改良、機胜远加にはコヌドの理解
        が必須
●   技術者の付加䟡倀
    ●   OSSは深远いできる
    ●   陳腐化しにくい
●   プロフェッショナルずしおの研鑚
    ●   すぐれた技術者は゜ヌスコヌドを䞊手に読む
                               8
コヌドの読み方
●   なぜ、コヌドを読むのか
●   どのように、読むのか




                  9
なぜコヌドを読むのか
●   仕事だから目的䞭心
    ●   トラブルシュヌティング䞍具合修正
    ●   機胜修正、機胜開発
    ●   自己研鑚、勉匷
●   趣味だから興味䞭心
    ●   楜しいから
    ●   自己啓発知的奜奇心
●   䞍玔な動機
    ●   圢から入る                10
なぜコヌドを読むのか
●   目的䞭心の堎合
    ●   察象に察する基瀎知識は必芁
    ●   アヌキテクチャ
        OS、プログラミング蚀語、RDBMS、 
    ●   定番の教科曞で知識を埗る




                               11
なぜコヌドを読むのか
●   興味䞭心の堎合
    ●   人それぞれ、人生いろいろ
    ●   無目的でもいいじゃないか
    ●   熟読、濫読、積読、黙読、音読、再読、誀読、
        粟読、速読、耜読、通読、埩読、茪読、朗読、
        茪読、 




                            12
コヌドの理解に぀いお
●   モットヌ
    コヌドは読むな、
    理解しろ〜


               13
どのようにコヌドを理解す
    るのか
●   個人的な方法を玹介する
    ●   唯䞀あるいはベストな方法ずいうわけでもない
    ●   適材適所、もっず良い方法があるず思う
    ●   公開するこずによっお進化したいもっず良い
        方法ぞの暡玢




                            14
゜ヌスコヌドを読む芖点


       埮芖的理解 巚芖的理解

静的理解

動的理解

                     15
理解の仕方、読み方
●   静的、動的理解
●   埮芖的、巚芖的
●   芏暡の把握
●   ツヌルの利甚
●   事䟋


                16
静的理解、動的理解
●   静的理解
    ●   字面での理解
●   動的理解
    ●   動䜜による理解




                  17
静的、動的構造
●   静的構造デモ
    ●   芏暡
    ●   ディレクトリ構造
    ●   名前぀け芏玄
●   動的構造
    ●   呌び出し経路
    ●   プロファむリング
    ●   実行結果
                   18
埮芖的、巚芖的
●   埮芖的现郚からの理解
    ●   最終的にはコヌドの䞀行
●   巚芖的党䜓からの理解
    ●   芏暡、構造、機胜など。実行結果性胜
    ●   俯瞰図、鳥瞰図。




                               19
芏暡の把握巚芖的理解
●   芏暡重芁
    ●   芏暡盞手を知らずしお䜜戊を立おられない
    ●   倧局的な地図、俯瞰図、鳥瞰図
    ●   倧芏暡になればなるほど、システマティックな
        方法論が必芁になっおくる
    ●   巚芖的な理解




                            20
芏暡の把握
●   小芏暡100K行未満皋床、
    ファむル数100未満
    10人未満
●   䞭芏暡100K行〜1M行皋床
    ファむル数100〜1000未満
    100人未満
●   倧芏暡1M行以䞊
    ファむル数1000以䞊
    100人以䞊
    ざっくりの芏暡感
                      21
芏暡の把握䟋
●   find -type f -name "*.[ch]"|wc
●   find -type f -name "*.[ch]"|xargs wc|grep total




      Ruby 1.8.5                  257 197767
      Linux 2.6.18              16522  680侇
      MySQL 5.0.24a              1795 988463

                                                      22
ディレクトリ構造
●   トップディレクトリは、゜フトりェア
    の論理的構造を衚しおいる
    ●   doc ドキュメント
    ●   lib ラむブラリ関係
    ●   test テスト
●   ゜ヌスツリヌの把握


                      23
ドキュメント
●   README, INSTALL, COPYING, 

●   内郚ドキュメント(Docs)
●   リリヌスノヌト
●   ChangeLog




                                  24
倉曎の履歎
●   ChangeLog/Release Notes
●   コヌド管理システム
    ●   䟋Linux git/Subversion/CVS
●   Mailing List
●   Wiki
●   blog
●   倉曎時間軞の埮芖的理解
                                     25
ドキュメント、情報収集
●   マニュアルを読む
●   サヌチ゚ンゞンGoogleに聞く
●   Mailing List
●   Bug database
●   開発者ずの䌚話シンポゞりムなど
●   勉匷䌚

                     26
゜ヌスコヌドを読む芖点


       埮芖的理解 巚芖的理解
                                 ディ ト 構造、
                                   レク リ  名前付け芏玄
静的理解   ゜
       ノ
        ヌスコ 、 h a n ge Log 、 リ
        ヌト
           ヌド C             リ ヌス 、芏暡の把握
                                 など
                                        行数、 ァ ル数
                                           フ ã‚€




動的理解   デバッガによる実行           実行性胜、 グレッ ンテスト
                                リ   ショ




                                                   27
いよいよコヌドを読む
●   ツヌル
    ●   ゚ディタemacs
    ●   デバッガgdb
    ●   クロスレファレンスcscope
    ●   カヌネルの堎合、クラッシュダンプ(crash)




                                  28
デモ、実習
●   䟋題ずしおrubyを読むこずにする。
    ●


●   GNU Hello
    ●   http://savannah.gnu.org/projects/hello




                                                 29
実習
●   ゜ヌスコヌドの芏暡を理解する
●   ディレクトリ構造を理解する
●   ビルドする
●   ゜ヌスコヌドのナビゲヌト
●   機胜倉曎をする


                     30
実習
●   ディレクトリ構造を理解する
●   ファむル名を眺める
●   ファむル数を調べる
●   プログラムの行数を調べる




                    31
実習
●゜ヌスコヌドの入手
    $ git-clone git:// (講垫に聞いおください)
●   ビルドの準備
    READMEをよく読む
●   必芁なツヌルを揃える
    -   automake <http://www.gnu.org/software/automake/>
    -   autoconf <http://www.gnu.org/software/autoconf/>
    -   bison <http://www.gnu.org/software/bison/>
    -   gettext <http://www.gnu.org/software/gettext/>
    -   git <http://git.or.cz/>
    -   gperf <http://www.gnu.org/software/gperf/>
    -   gzip <http://www.gnu.org/software/gzip/>
    -   perl <http://www.cpan.org/>
    -   rsync <http://samba.anu.edu.au/rsync/>
    -   tar <http://www.gnu.org/software/tar/>

                                                           32
実習
●   ビルド
    $   time git clone ssh:// (講垫から情報を埗る)
    $   cd ruby
    $   time autoconf
    $   time ./configure
    $   time make
    $   time make test




                                            33
●   $ git checkout -b trunk
    origin/trunk
●   $ autoconf
●   ./configure
●   make -j4 miniruby



                              34
動的理解
●   ビルド




           35
動的理解
●   ずもかく動かす
    ●   make
    ●   strace
    ●   ltrace
    ●   gdb
    ●   oprofile
    ●   リグレッションテスト
    ●   ベンチマヌクテスト

                     36
make
●   ずりあえず、make
●   実行環境の構築
    ●   gcc -g (デバッグシンボルを付加する
        通垞はMakefileのCFLAGSなどに蚭定
    ●   cscopeのむンデックスを䜜成
    ●   ビルドはemacsのshellなどから行い、ビルドの
        ログを取埗しおおくず䟿利



                                 37
strace
 ●   システムコヌルのトレヌス
$ strace ruby -v
execve("/usr/local/bin/ruby", ["ruby", "-v"], [/* 39 vars */]) = 0
uname({sys="Linux", node="asianux2.miraclelinux.com", ...}) = 0
brk(0)                       = 0x976a000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or dir
open("/etc/ld.so.cache", O_RDONLY)          =3
fstat64(3, {st_mode=S_IFREG|0644, st_size=89946, ...}) = 0
old_mmap(NULL, 89946, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7
close(3)                     =0
open("/lib/libdl.so.2", O_RDONLY)         =3
                                                                  38
gdb
●   デバッガはコヌドを理解するためにあ
    る
    ∎コヌドを読むために䜿う
●   http://savannah.gnu.org/projects/gdb




                                     39
gdbで読むための準備
●   gcc -g でコンパむル
●   コンパむルしたコヌドサむズが倧きく
    なる以倖、特に副䜜甚はない
●   printfデバッグは有害無益




                    40
gdb
●   ブレヌクポむントを蚭定
●   りオッチポむント倉数の倉曎
●   run
●   止たった時点で
    ●   bt スタックフレヌムの衚瀺
    ●   p 倉数の衚瀺
    ●   c 実行再開、s ステップ実行関数に朜る、
        n ステップ実行関数に朜らない
●   繰り返す                      41
oprofile
●   プロファむラヌ
    ●   実行時のボトルネックを発芋
    ●   # opcontrol --start
    ●   テストの実行
    ●   # opcontrol --stop
    ●   # opreport -l
●   http://oprofile.sourceforge.net/news/

                                     42
oprofile
CPU: Core Solo / Duo, speed 2666.77 MHz (estimated)
Counted DCACHE_PEND_MISS events (Weighted cycles of L1 miss outstanding) with
a unit mask of 0x00 (Weighted cycles) count 100000
          vma    samples    %             linenr info          app name symbol
   name
000000000042be50 244787     33.2383       gc.c:1661            ruby
   os_each_obj
  000000000042bfac 1            4.1e-04     gc.c:1599
  000000000042bfb9 5            0.0020     gc.c:1599
  000000000042bfbe 6            0.0025      gc.c:1599
  000000000042bfd0 4862         1.9862      gc.c:1601
  000000000042bfd3 228573       93.3763     gc.c:1601
  000000000042bfd6 2698         1.1022     gc.c:1601
  000000000042bfd8 250          0.1021     ruby.h:672
                                                                                 43
oprofile
●   高速道路で、ズバリ最もコストのか
    かっおいるずころに連れお行っおくれ
    る
●   コヌドを読たないで、理解する極意




                    44
埮芖的理解
●   ひたすらコヌドを読む
●   王道はない
●   ↑身もふたもない
●   デヌタ構造、倉数などに泚目し、どこ
    で定矩され、参照され、代入倉曎
    されおいるかずいう芳点でみる
●   デバッガず゚ディタ、クロスリファレ
    ンスツヌルを駆䜿
                    45
埮芖的理解
●   $ time find -type f -name 
    '*.[ch]' -or -name '*.cpp' 
    -or -name '*.cxx' | xargs 
    egrep -l hogehoge
●   $ time grep -r 
    –include='*.[ch]' hogehoge .
●   hogehogeを含むファむルを怜玢
                                   46
埮芖的理解
●   クロスリファレンスツヌル
    ● 倉数の定矩型情報、倉曎代入、参照


●   倉数関数が、どのように定矩されおいお、ど
    のように参照、倉曎されおいるかを远う
●   cscope
    http://cscope.sourceforge.net/
●   lxr
    http://lxr.linux.no/
●   GNU GLOBAL
    http://www.gnu.org/software/global/
●   ack-grep
                                          47
実習
●   cscopeを利甚する
    $ time cscope-indexer -r
●   emacsを利甚する
●   gdbを利甚する
●   oprofileを利甚する



                               48
゜ヌスコヌドを読む芖点


       埮芖的理解 巚芖的理解
                                 ディ ト 構造、
                                   レク リ  名前付け芏玄
静的理解   ゜ヌスコ 、 h a n ge Log 、 リ
             ヌド C
       ノ 、 sco p e
        ヌト c
                            リ ヌス 、芏暡の把握
                                 など
                                        行数、 ァ ル数
                                           フ ã‚€




動的理解   デバッ (g db )による実行、 e
          ガ             strac
                                op ro fie 、 c e 、
                                ッ ンテスト
                                 ショ
                                       l stra    実行性胜、 グレ
                                                      リ




                                                            49
参考曞
●   Linux
     ● 詳解LINUXカヌネル第䞉版

       ISBN:487311313X
     ● Linuxカヌネル2.6解読宀

       ISBN:4797338261
●   コヌドリヌディング
    ● ISBN:4839912653


●   Ruby゜ヌスコヌド完党解説
     ● ISBN:4844317210(品切れ䞭

       http://i.loveruby.net/ja/rhg/
                                       50
ナメのチカラブログ
●   http://blog.miraclelinux.com/yume/
●   ブックマヌクで芋た人気゚ントリヌ
●   ゜ヌスコヌドの読み方(524個)
    ●   http://blog.miraclelinux.com/yume/2007/08/post_d6bd.html

●   デバッグ方法論99個)
    ●   http://blog.miraclelinux.com/yume/2007/08/post_d3eb.html

●   倚くの人に興味がある話題

                                                                   51
●   ブログナメのチカラ
●   http://blog.miraclelinux.com/yume/
●   未来のい぀か/hyoshiokの日蚘
●   http://d.hatena.ne.jp/hyoshiok/




                                         52