わたしは、90年代にシリコンバレーにいたとき、シリコンバレー日記と言うものを書いていてWebで公開していた。今そのサイトはないのであるが、インターネットのWebアーカイブにその内容が残っている。先日「プロセスプログラミングの実践方法」というエントリでデバッグの話を書いたので、それつながりということで、当時、記した日記を全文転載し、ちょっと長くなるが後書き的な解説を加えたい。文体が微妙に違うがご愛嬌と言うことでご勘弁願いたい。
転載始まり
デバッグ
誰もが使っている言葉なんだけど,実のところよく分からない言葉というのがある.少なくとも,なんとなくの定義はあるのだけど厳密な全員が納得できるような定義があるようでない言葉というのがある.
デバッグというのも実はわかったようでいてよく分からない.とりあえづ,デバッグというのはプログラムのバグを直す作業だとしよう.そうするとプログラムのバグとは何か?という当然すぎる疑問が湧く.バグというのを,仕様書と実際の動作との差という風にも定義できそうである.これはプログラムの予期せぬ動作を,「いや,それは仕様です」といういいわけに使えるので,プログラマには好まれる定義かもしれない.しかしもう少し広範囲にとらえれば,やはり,利用者の期待する動作と実際の動作の差をバグという風に言えなくもない.期待する動作より,いいほうに実際の動作があればだれも文句を言わないだろうから,不都合側の動作ということにしてみよう.
というわけで,とりあえづの定義として,デバッグという作業はそのプログラムのバグを直すことだとしよう.
さて,そのデバッグをあなたはどのようにしているのだろうか?ワークステーションの前に座って,コーヒーをがぶがぶ飲みながら時にはハンバーグをほお張りつつ何時間か格闘するといつのまにかにバグが直っている.そーゆーなぞのプロセスなのだろうか?
そのプロセスをわれわれは記述できないだろうか?どーゆーステップをもってわれわれはデバッグをしているのか?
それを記述する事にどのような意味があるのか?一つはそのようなプロセスが記述できれば,無駄や,無理や重複作業などを発見する手がかりになるのではないか?つまり理解していない事は決して改善できないのだという大前提の元,プロセスを理解すればそれを改善するきっかけをつかめるのではないかという立場である.
あるいは新人エンジニア(彼らは往々にしてデバッグ作業の効率が悪い)に対してのお手本になるのではないだろうか?
わたしは大胆にも自分のデバッグのプロセスをここで記す事を試みてみたいと思う.皆様の忌憚なきコメント,サジェスチョンを頂ければ幸いである.
バグの発見:なんらかの方法でバグが発見される.われわれはバグが誰によってどのように発見されるか実はそれほど深く理解していない事実にも驚かされる.
実のところ,その前にバグの作成というプロセスがあるのだが,ここの部分もまったくと言っていいほど解明されていない.一つだけ確かな事があるとしたら,バグが誰によって作られるかという事実である.もちろんプログラマによって作られる.すなわち,わたしや,プログラマであるあなたによって,作られるのである.作られるという受け身な態度は潔くない.バグはわたしやあなたが作るのである.バグが自然発生することは決してない.しかしながらどのようにバグを作るか,なぜ作るかという点に関してはわれわれは十分理解はしていない.
ここでは,バグがなぜ発生するかという問題にはとりあえづ触れない事にする.ともかく,誰かが作ったバグを誰かが発見する.そして誰かが直す.すなわちわたしやあなただ.
バグの再現:誰かが発見したバグの現象を再現する.ある操作をすると,システムがクラッシュすると報告されたのならその操作を繰り返してみる.それで再現できればいいのだが,タイミングや作動環境の違いで再現できない場合が多々ある.その場合は,作動環境,例えば,OSの種類や,各種ハードウェアなどをできるだけ同一の条件にする必要がある.それでも再現できなければ,バグを発見した実機の環境で同様な作業を繰り返し,バグを発生する条件を確認する.場合によってはここで座礁する事もある.試行錯誤の繰り返しでもある.
バグを再現する事に成功したとしよう.条件がよければ,エラーメッセージや,コアダンプなどの資料が入手できるかもしれない.
どこでメッセージを出しているかを見つける:どのルーチンがどのエラーメッセージを出しているか?通常はスタックフレームを見れば,どのルーチンで異常終了しているかがわかる.当面はそのルーチンの界隈から,狭義のデバッグ作業が始まる.
当該ファイルをデバッグオプションでコンパイルする:OS付属のデバッガーを利用して,デバッグオプション付きで再コンパイルしたプログラムを実行する.異常終了するルーチンにブレークポイントを設定して,異常終了する直前の各種の変数の値などを調べる.
それからのプロセスは,ちょうどプログラムの実行を逆順に戻っていく作業になる.例えば,ある変数がXなので異常終了したとしたら,なぜその変数がYでなくXになったのか?それを探っていく.変数の場合は代入されない限り,値は変更されないので,代入されている場所を特定する事がポイントになる.
情報をいかに検索するかがデバッグの効率を左右する.全体像を理解するためにソースコードの理解がかかせない.どのルーチンがどのルーチンから呼ばれているか,呼んでいるか,というコールグラフ.どの変数がどこで定義され,どこで代入され,どこで利用されているか.そのような理解をする.
原因の特定:プログラムの挙動を詳細に理解すれば,自ずとバグの原因は発見できるであろう.わたしには原因の特定の瞬間のプロセスを記述する事はできない.手に余る.ともかくわかるときにはわかるのである.
修正案の検討:バグの原因は特定できたとしよう.特定できれば,それをどのように修正すればいいかのいくつかの案を検討する.実装上のコスト,修正の容易さ,その他の要因を勘案の上,修正案を比較検討する.修正が現実的なコストでできない場合もありうる.そのコストとバグの影響と比較検討して,バグを修正しないというオプションもありうるという事に注意する.
修正:上記の修正を実施する.
テスト:修正の結果,確かにバグが直っていることを確認する.テストは原則として日々のリグレッションテストに組み入れる.
リグレッションテスト:修正が従来の機能に影響(リグレッション)を与えていない事を確認するために,リグレッションテストを流す.
ソースコードレビュー:変更したソースコードを担当のプログラマとレビューする.変更が軽微なものなら,変更分をメールで何人かのプログラマに送ってコメントをもらう.
チェックイン:修正をソースコード管理システムに登録する.
それ以降:これでバグを一つ修正した.それ以上なにが必要なのだろうか?デバッグのプロセスを通じてわたしはなにを学んだろうか?もっとうまい方法はないだろうか?この修正はベストだったのだろうか?それともデバッグというのは黒魔術と一緒で,学習可能なものではないし習得可能なものではないのだろうか?
わたしはデバッグというもっともプログラミング上で神秘的なこのプロセスをもっと深く理解したい.そしてもっと熟達したい.エキスパートになりたい.そのために,自分の作ったバグを記録し,デバッグの記録を取っている.そして記述を通して,自分の稚拙なプログラミングテクニックを再確認しいかにしてそれを向上させるかを学んでいきたい.できれば,あなたのデバッグプロセスからも学びたい.われわれがプログラミングについて理解するために,そしてそれによって少しでも賢くなるため,このような微視的な記述やデータが必要だと思うのである.
はげましのお便りは よしおかひろたか
までどーぞ.
日記のページへもどる.
一覧へもどる.
よ
シリコンバレー日記/未来のいつか
http://web.archive.org/web/20000928213350/www.best.com/~yoshioka/d/98/i980301.html
文字化けするときは、
Microsoft Internet Explore 表示>エンコード>日本語(シフトJIS)
Mozilla Firefox 表示>文字エンコーディング>日本語(Shift_JIS)
転載終わり
1998年3月1日に書いた日記である。デバッグのプロセスというのはほとんど変わっていないように思う。技術の進歩と言うのは速いのだろうか?遅いのだろうか?ソフトウェア開発に対する理解というのがこの10年どのくらい進歩したのだろうか進歩していないのだろうか?
マクロでみるとソフトウェアのテスト&デバッグのプロセスはかなり定式化できることがわかる。またある程度自動化することもできる。そしてそれがデイリービルド&リグレッションテストとしてよく知られているベストプラクティスである。
ソフトウェア開発の非常に人間的な部分であるデバッグのプロセスをもっともっと深く理解したい。その思いは10年位前と変わらない。しかしながらこの10年で自分がどれほど進歩したかと言うと正直言って忸怩たるものがある。商用ソフトウェアを作っていた当時と比べて自分の専門性がどれだけ研ぎ澄まされたかと言うとほとんど進歩していないのではないだろうか。そう考えると道はとてつもなく長く険しい。
しかし10年前と現在で大きく変わったことがある。OSSとインターネットである。
10年前わたしが記述したバグ情報はすべてプロプライエタリな情報として企業の壁の中にあり同僚以外と共有することができなかった。わたしの書いたコードは門外不出だし、変更記録も、バグデータベースの記述ももちろん知的所有権の名の元に幽閉されている。
10年前はわたしとあなたは微視的なデバッグの記述を共有できなかった。
ところが10年たってわれわれはオープンソースと出会い、わたしはわたしのコードだけではなく、わたしのつたないデバッグのプロセスをあなたや世界中の誰かと自由に分かち合うことができるようになった。
なんていうことだ。
この情報をインターネットに公開しておけば、未来のいつか、世界の誰かがこの情報を発見してくれるかもしれない。ひょっとしたらデバッグのプロセスをチューニングしてくれるかもしれない。それはあたかもソースコードを公開すれば、そのコードが利用するに値するだけの価値があり、利用者の注目を浴びて、多くの人に利用されるのならば、世界の誰かがコードを改良するという、ソフトウェア開発におけるバザールモデルのように、このデバッグというプロセスをより高度にチューニングしてくれるかもしれない、などと夢想するのである。
8年前に書いたわたしの日記を8年後に自分自身が再発見し、それをきっかけに一つのブログを書き、それを読んだあなたがひょっとしたらいつの日かソフトウェアプロセスのチューニングに参加してくれるかもしれないと考えると、インターネットというのはすごいメディアだとつくづく思うのである。世の中まだまだ捨てたものではないなあなどと妄想するのである。
デバッグのプロセスを詳細に記述する。そこからデバッグに対する深い理解が生じるようになる。
そしてその記述はインターネットによって時間と空間を越えて共有できる。それはデバッグに対する深い理解として人類共有の財産になりうる。
OSSとインターネットというのはすごい環境である。
最近のコメント