Personal tools
You are here: Home 原稿・資料 codeblog発表資料 codeblogとcode reading
Document Actions

codeblogとcode reading

8月10日主査会の発表資料です。

目次

  • 自己紹介
  • コード読みの経験談と知見
  • Apacheのコード
  • codeblogの活動

自己紹介

  • アリエルネットワーク株式会社
  • 製品ラインナップ
    • AirOne ProjectA: P2Pプロジェクト管理ソフト
    • マルスケ(Multi Scheduler): 無料P2Pスケジュール管理ソフト
    • ν: エンタープライズ向けポータル(予定)

コード読みの経験談と知見

規模の大きなソースコードを読んできた経験談と、得られたかもしれない知見について

Lotus NotesのUnixクライアントのコード

1996年ごろLotus NotesのUnixクライアントの開発の手伝いをしました。

Mirageというライブラリを利用

  • 商用ライブラリ(ソースごとLotusが取得)
  • Motif(X Window System)をラップしてMS-Windows APIをエミュレーション
  • 大部分のMS-Windows APIをカバー
  • 主に国際化まわりのバグ修正(フォントやInput Methodなど)
  • コードの規模は覚えていません(今想像すると、5万行以上はあったと思います)

この時の個人的スキル

  • XlibとXt(toolkit)のAPIは知っていた
  • Motifはまったく知らなかった (fyi; MotifはXlibとXtの上に載るAPI層です)
  • MS-Windows APIは少し知っていた

Lotus NotesのUnixクライアントのコード [cont.]

Lotus Notesのコードは初めてでしたが、意外にすんなり作業に入れた(はず)

  • XlibのAPIを知っていたのが有利
    • テキスト出力であれば、Xlibの該当するAPIでbreakpointを張っておけば良い
    • 入力系であれば、該当するXのイベントで探せば良い
    • など
  • がむしゃらにコードを読んでいたので、
    • MotifのAPIも熱心に勉強した => ますますコードが読みやすくなった
    • (結果的に)MS-WindowsのAPIもかなり習得した (後につながる)

Lotus NotesのUnixクライアントのコード [cont.2]

  • 当時のコードの読み方
    • ひたすらデバッグ
    • 実行時のコールスタックで処理を把握

知見

  • 低レイヤのAPIを把握していることは大きな利点
  • ある規模(数万行?)までなら、実行時のコールスタックと気合いがあれば、なんとか把握できる(たぶん)

Lotus Notes本体のコード

2年間、Iris AssociatesでLotus Notes R5開発に参加

  • 全体で500万行以上 (R5開発中に600万行を越えたはず)
  • メインの担当は国際化および日本からの機能要求の実装
  • が、これを機会にNotesのソースコードを把握してやるぞと、気合い充分でした(若かった...)

しかし、

  • 500万行のソースコードの壁は高かった
  • 周辺のバグ修正はできても、全体の上っ面だけをいじっている感覚

Lotus Notes本体のコード [cont.]

  • 当時のコードの読み方
    • 実行時のコールスタックを見て、
    • 重要そうな処理に当たりをつけて、*処理中心*にコードを読むスタイル
    • MS-WindowsのAPIは把握していたので、画面処理周りは比較的把握しやすかった
    • メモリ周りやネットワーク周りは階層が深すぎて歯が立たず (mallocやrecv、sendはコールスタックの深い底にあり、その上に多層のAPI => うんざり)
    • 当然、Notesのストレージ周り(一種のObject DB)は、全く不明な状態

Lotus Notes本体のコード [cont.2]

徐々に、大規模なコードを読むために、何が足りないのか分かり始める

  • APIで切っていく感覚 内部APIも含めて、モジュールやレイヤの境界を意識して「切っていく」感覚
  • データ構造を意識する感覚 遅まきながら、処理中心からデータ構造中心にコードを読み始める
  • (オブジェクトの)集合に対する感覚 集合および集合に対する操作(列挙など)を意識 (いわゆるコンテナやコレクションなど)

Lotus Notes本体のコード [cont.3]

(コード以外の)メタな情報から高レベルな概念(アーキテクチャ)や用語(コード上の略称)を把握

  • 内部スペック文書
  • 公開API => 公開APIのサンプルコードは、ムダが無く直接的なので、大きな概念をつかみやすい
  • (スクリプト言語用)公開クラスライブラリ => 同上
  • コードの読み方の変化
    • モジュール(ディレクトリで分けられたコード)が*何であるか*の把握
    • モジュール名やAPIのprefixに現れる略称が*何であるか*の把握
    • モジュールの境界(内部API)の把握
    • モジュール間の「呼ぶ-呼ばれる」の方向性を把握(依存度の把握)

500万行-600万行のコードが全て頭に入った、とは言いませんが、コツはつかみました。

オープンソースのコード

2000年ごろ、GNU/Linux上のデスクトップ環境に夢を抱いて...

  • GNOME1.xは、GTK+1.x/GLib1.xを含めて、コードをだいたい把握 (Xlibを知っていたのでだいぶ楽)
  • Emacs、Linux(kernel)、小物ツールなど。
  • Mozilla0.xはビルドが通っただけで満足。コードはほとんど読んでいません

パッチを送って貢献しようという気持ちより、どう書いているのだろうという好奇心でコードを読んでいました

アリエルネットワークのコード

2001年、AirOne(P2Pコラボレーションツール)の開発開始

(BSD系ライセンスの)オープンソースを活用

初期

  • libapr(Apache Portable Runtime): ポータブル層(WindowsとGNU/Linuxの差を吸収)
  • (expat): XMLパーサ
  • openssl: 暗号化、署名
  • xerces: XMLパーサ (C++)
  • xalan: XSLTプロセッサ (C++)

アリエルネットワークのコード [cont.]

  • libapr(Apache Portable Runtime): ポータブル層(WindowsとGNU/Linuxの差を吸収)
  • (expat): XMLパーサ
  • openssl: 暗号化、署名、SSL
  • libxml2: XMLパーサ。xercesがあまりに遅いの置き換え
  • libxslt: XSLTプロセッサ。xalanがあまりに遅いので置き換え
  • sqlite: ローカルキャッシュDB用
  • libpq(postgresql): サーバ上のユーザ管理DBとの通信用

利用オープンソースのコード

  • libapr: 初期の頃、パッチやバグ報告を頻繁に行いました。コードはほとんど把握
  • openssl: かなりブラックボックス。興味でBIO(chain化できるbuffering IO)辺りのコードは読んだ
  • xerces、xalan: JavaからC++に書き換えたコード。ひどいコード
  • expat、libxml2、libxslt: 利用範囲内で特に問題がないので、読む機会なし
  • sqlite: 最近、興味あり
  • libpq(postgresql): 読む時間なし

Apacheのコード

コード規模(apache2.2)

  • 全部で約30万行(ヘッダやテストコード込み)
    • srclib/ディレクトリ(apr、apr-util、expat、pcre)が約14万行
    • modules/ディレクトリが約11万行
    • server/ディレクトリが約4万行
    • その他

Apacheのコード [cont.]

コードのスタイルの特徴

  • コーディングスタイルは一貫しています (一部のモジュールに例外あり)
  • libaprにプラットフォーム依存コードを追い出しているので、#ifdefは少ない
  • プリプロセッサマクロの使用はほどほど (opensslほどひどくない)
  • assert(3)はほとんどありません (理由は不明)
  • コメントは多い方?

Apacheのコード [cont.2]

c_count<http://dickey.his.com/c_count/c_count.html>で、コメントとコードの割合(コード1行に対してコメントの行数)を出してみると、

apache2.2 0.40
gtk+2.8 0.17
sqlite 0.63
libxml2 0.23
postgresql 0.36
emacs21 0.47
linux2.6 0.25

Apacheのコード [cont.3]

ポイント

  • APR
  • hook
  • bucketとbrigade
  • filter
  • mpm (Multi Process Model)
  • module

Apacheのコードの動向

  • つい最近、mod_rewriteでセキュリティホールがありました
  • HTTP1.1のchunk対応は落ち着いた様子
  • authn/authz周りのコードがまた再整理
  • apr-utilにmemcachedとの接続APIが追加 (いずれmod_cacheで利用?)
  • apr_ssl APIが追加 (opensslのAPIのラッパー。apr_ssl_openssl.cと並んでapr_ssl_winsock.cもある(事実上、中身無しですが))
  • mod_proxy、ajp(tomcatとの接続プロトコル)周りが色々騒がしい
  • mod_cache周りが色々騒がしい

mod_proxyとmod_cacheは要注意

codeblogの活動

作業の環境

  • Emacs
  • grep

以上。

初期の頃はgonzuiで検索したりしていましたが => コードの構成が頭に入るとM-x grep-findで事足りてしまう(etagsすら不要)

  • {{code "httpd-2.2.0/include/httpd.h", "741-750,975"}}

こう記事に書く時も、手元のソースツリーで行数を調べて書いています。

codeblogの活動 [cont.]

記事で嘘を書かないように、自信がない時は

  • gdbで実際の動作を確認
  • サンプルコードを書いて動作を確認

しています。

  • codeblogのgonzuiではhttpd-2.2.0のソースツリー
  • apache-2.2系の最新はhttpd-2.2.3

幸か不幸か、コードに大きな変化はないので、困ってはいません。


Copyright(C) 2001 - 2006 Ariel Networks, Inc. All rights reserved.