SSブログ

よいバグがあるとすれば・・・(月刊ASCII 1988年2月号11) [月刊アスキー廃棄(スクラップ)]

スペシャルレポートが Edward H. Currie 氏の記事があったので抜粋してスクラップする。
ASCII1988(02)f01よいバグがあるとすれば_W520.jpg
編集部のあおり文に「プログラミングとは、1%のコーディングと99%のデバッグである」とあった。この%はもちろん時間のことだ。たった1個のバグに何日も悩んだことがあったので身に染みる。
 一般にソフトウェアを開発する場合,作業時間の割合は,製品の仕様書を作るのに30%,コーディングに20%,そして残りの50%はデバッグにあてられている.しかし,そのわりには、デバッグのテクニックは進歩が遅いし,新しい技術が一般に広まるスピードはもっと遅い.
 今のところ,デバッグは何かいかがわしい超能力や,神秘的な呪文や,悪魔払いといったものに支えられている魔術みたいに思われている.プログラミングに熟達することは、デバッグのテクニックにも長けていることだ,などと言う人はあまりいない.これまで,多くの人がデバッグに適した心理学的適性といったものを考えてきたが,あまり結論らしい結論には至っていない.よいプログラムが書ける心理状態というのは、デバッグのそれと必ずしも一致しないようである.
 (中略)
 おそらくCとアセンブリ言語のバグを生み出す要因でもっとも一般的なのは、スタックとポインタの扱いの不手際だろう.この2つの要因がきわめて油断ならないのは,プログラムに異常な動きをさせようとするからだ。たとえば,プログラムが普通に走っているときにバグが現れ,デバッグしてtraceコマンドを入れるとバグは消える.調べてみると,プログラムがソースコードの行の間で「爆発」して,めちゃくちゃになっているのが見つかったりする.プログラムによっては最初に呼び出されたときにはすべてうまくいっているように見えるのに,次に呼び出されると暴走してしまうのもある.最初にロードされたときはうまく動くのに,2度目には暴走してしまうというのもある.プログラムによっては,コンパイルの直後だけうまく動いて,つづいて何かやろうとすると暴走するというのもある.
 (中略)
 スタックポインタが適正なスタックの境界の外でメモリの一部に重ね書きしていないかどうか,あるいはスタック自体が重ね書きされていないかどうかを見極めるには,スタックやスタックポインタを調べるのもいい方法だ.
 (中略)
 プログラムがおかしな動きを示し,しかもそれが繰り返されない場合は,メモリロケーションのどこかが正しく初期値設定されていないか,スタックが重ね書きされているか(こうなっていると,適切なロケーションに帰ってこないか,あるいは全くリターンが行われなかったりする),ポインタの扱いが間違っているかだと考えていい.
 しかし,これは覚えておいてほしいのだが,すべてのバグが,質の悪いコードによってプログラムが異常動作する場合にのみ発生するとは限らない.バグの中には,単にプログラムのデザインがまずいために生じるものもある.よく知られているのは,かなり洗練されたアプリケ-ションが,何年間もうまく動いていたのに,急に「爆発」してしまったというような例だ。調べてみると,原因はバイナリサーチ・ルーチンであることがわかった。しかし,おかしなことに,このル-チン自体は狂っていなかった.ただこれを書いた設計者が,要素が1つしかないリストを探索するとき,どんなことが起こるかに注意を払わなかっただけなのだ!そのため,次の項目を指し示す経路が自分自身を指していたので、永久ループ状態に陥ってしまったわけだ.
 (中略)
 スタブはこれまでずっと,プログラマ、がコンパイラあるいはインタープリタを使っていろいろな言語でデバッグを行うのを助ける役目を果たしてきた.スタブはコードの一種で,プログラムのさまざまな場所に置かれ,プログラムが実行されているあいだに主要なパラメータの変数をダンプしながら,プログラマがプログラムの実行経路を追跡し,検査していくのを助けてくれるのだ.

printf('x=%",x); /**/

とか。

puts("made it to 1”);
puts("made it to 2”);

といったステートメントがソースコードの中にわざと置かれ,実行中にいろいろなパラメータの値を調べたり,プログラムが実行中に特定の地点に行き着くようにするために使われる.プログラムの中でスタブの位置を探すために空のコメントが使われ,スタブが必要なくなると,これで探し出して取り除く(プログラマによってはソースコードの1行ごとにスタブをはさむ人がいる.人間,必死になるととんでもないことを考えるものだ).
身に覚えがありすぎて笑ってしまった。良くやったよな。バグによる暴走は当たり前だった。
 これから挙げるのは、バグの対処法に一関する様々なヒントである.
☆バグがプログラムではなく,コンパイイラから出てきたように見えたとしても,可能性としてはコーディングにバグがあることが多い.まずコーディングのバグを探し,それからコンパイラのバグを考えるほうがよい.
☆デバッガもまたプログラムの一種であり,時としてそれ自体バグが持っていTるかもしれないことをお忘れなく.
☆バグに対処する場合,最も陥りやすい誤りのひとつは、バグをレポートそのものにあることを見逃してしまうというやつだ。それを避けるために,ユーザーからはできるかぎり詳細な報告をもらうこと.一番いい方法は、探し出して取りのぞく前に,自分で一度そのバグを体験してみることだ.
☆アセンブラとCのプログラムでは,ポインタと変数の初期値設定の間違いが,エラーの原因としては一番多い.
☆アセンブラとC言語のコードのバグで,二番目に多いのがスタックの扱い方の誤りである.
☆ソースのデバッグテクニックですべてのバグに対処できるわけではない.ハードウェアのデバッガやロジックアナライザといったバグ診断ツールも有効であり,時としてそれが,バグを持つプログラムに対抗する唯一の有効なソフトウェアのデバッグテクニックになることもある.最近,デバッグツールのデザイナーはバグ診断のパワーを高めるために,ハードとソフト両方のデバッギングテクノロジーを組み合わせたものを開発している.
☆Occamのかみそりの故事(注1)を思い出して、バグの原因を最初からあまり複雑に考えないことまず単純な原因を検討し,それが違うならより複雑なほうへと移っていくようにしたほうがいい.
編集部注
注1 「Occamのかみそり」,Occamは、14世紀イギリスのスコラ学者.Occamのかみそりとは,「存在(仮説)は必要以上に多くしてはいけない」という方法論を指すたとえ、この方法論を好んでもちいた彼の名前にちなんで付けられた.
☆(エラーの)動作が何度も繰り返されるものでない場合は,ポインタやスタック,変数の初期値設定が間違っていないかどうか調べるべし.
☆コンパイラのバグと,その対処法に関する報告に,常に注意を払うこと.プログラミングのやり方や、プログラム自体と何の関係もないような原因を探しているのかもしれないからだ。
☆最初の開発段階では,プログラム全体を一度に走らせないこと時間のロスが大きいし,モジュールをひとつずつテストすれば見えるバグが,見えなくなってしまうことにもなりがちだ.
☆バグの対処法を間違えると,次に新たなバグを生みだすことになりかねないので要注意.バグが出ては直すということを際限なく続けていると,いつまでたっても改訂版が出せないことにもなりかねない.
☆一度退治したバグは,その対処法を記録しておくことさもないと,過去のバグを振り返るのに,またいちいち面倒な手間をかけることになる.
☆バグは一度見付けたところにいつでもいるとは限らない.ライブラリは,バグがどこにあるかを探すのに役立つが,その中にバグがあると,人騒がせなポインタというやつにあちこち引きずり回されてひどい目にあうことになるだろう。
☆小さなデータについてのテストからは,.あくまで小さなデータに関して何が起こっているかしかわからない.多くのデータは時とともに増大するから,中程度のデータや巨大なデータのテストもすべきである.
☆必ずしもすべてのバグが取り除かれなければならないものとはかぎらない.なぜなら,バグ退治には常に新たな問題を引き起こす危険が伴うからだ。だからといって,「退治できないバグは機能のひとつと思えばいい」という格言をあてにしてはならない.一番大切なのは、バグのドキュメントを作ることで,その次が退治することだといってもいいだろう.たいていのユーザーは、次のバージョンで直される予定の公開されたバグには対処できるが,存在が知られていないバグには対処できないから,そのバグは狂暴に暴れ回りユーザーをひどい目にあわせる.
☆Illegal system callも,よく問題を起こす原因になる.マルチタスクのOSが普及するにつれて,ますますそれが甚だしくなってきている.BIOSを通さずに直接ハードウェアを操作している場合には,このことは必ず記録しておかなければならない.なぜならそれはいずれトラブルの原因になるからだ。
☆きちんと動いているプログラムにパッチをあてる場合は,同時にソースコードにもその変更点を書き込んでおくことバグ退治に何をしたか忘れてしまうのはたやすいが,次に別のバグが出たとき,やっかいなことになるだろう。
☆いつでもソースコードとアセンブリ言語のレベルの両方でデバッグを行うべきだ.b ☆ときにはバグを直すより,最初からやり直したほうが手っ取り早く,効果的なこともある.
 (中略)
バグに対処する一番いい方法は,まず最初の段階でバグが出ないように注意することだ一度プログラムに入り込んでしまうと,完全に退治することはできないし,そのバグを殺しても,別のバグがいくつもできてしまうことだってある.つまり,『死んでいるバグだけがよいバグなのである』ということなのだ。そして,最もよいバグというのは,そもそも最初から存在しないバグのことだ!
読んでみて激しく同意することや経験してきたことばかりだったのでスクラップしてしまった。

nice!(0)  コメント(0) 

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。