1|2|34.今回の解答バグの原因は、「バッファオーバーランによるメモリ破壊」です※2)。以下、詳細を解説します。※2)バッファオーバーランは、確保しているデータ領域を超えて、隣接するデータ領域を書き換えてしまうバグです。バッファオーバーフローとか、「爆撃」とも呼びます。本プログラムは、「examdata.txt」をカンマ区切りで読み出し、コンソールに表示するプログラムです。AOI」の理科(science)のデータが正しく表示できていません。表示できない原因は、ソースコードの以下の部分です。ソースコード内の正しく表示できない原因strcpy関数は、nameにtokenの文字列をコピーする関数です。名前の変数は、name[N][15]」と宣言してあります。名前は14文字までしか入力できません。SHUICHIRO」は、18文字あり、strcpy関数を使用してしまうと、領域外の場所にデータを上書きする可能性があります。今回の場合は、メモリ上にnameの次のアドレスに理科のデータ(science)が入っており、その部分まで上書きしています。メモリ内は以下の表1のようになっており、理科のデータが壊れています※3)。SHUICHIRO」を入力したときのメモリ内の状態(クリックで拡大)※3)今回の問題は、お手持ちの環境によっては動作が一致しない可能性があります。7.3.0を使用しています。YUYA」の理科の点数が70ではなく、79となっているのは、3人目のデータのアルファベットの「O」をコピーしているためです。コンソールへの表示は、10進数表記ですから、アルファベットの「O」は、ASCIIコードで「4F」で、「4F」を10進に変換すると「79」になります。AOI」の理科の点数が0となっているのは、3人目のデータの末尾「'\0'」が入っているためです。「\0」は、ASCIIコードで0を表すので、コンソールには数字の「0」が出ます。このバグのトリッキーなところは、生徒の名前が「渡辺一郎」なら正常に表示し、「渡辺秀一郎」なら表示不正になる点です。最初の動作確認テストで、「渡辺一郎」をテストデータにしていれば「たまたま」正常動作し、プログラム作成者のAさんは「このプログラムでOK」と思ったはずです。実際のデータに「渡辺秀一郎」があると、メモリ破壊が発生し、渡辺秀一郎と関係がない生徒のデータが壊れます。この現象から「渡辺秀一郎のアルファベットの文字数が多いことが原因となり、他者のメモリを破壊した」とは思い付かないでしょう。OSのバグや、ハードウェアの不良まで疑い、Aさんは煮詰まってしまいます。「渡辺太一郎(ワタナベタイチロウ)」と「渡辺秀一郎」の場合では、データの壊れ方が異なりますし、テストで「松本明子(マツモトアキコ)」を使い、実際のデータに「松本吉彦(マツモトヨシヒコ)」が入っている場合、「2人の名前の漢字の文字数は同じで、性別が違う」とミスリードの要素が増え、「名前のアルファベットの文字数が多く、バッファを破壊した」という原因特定に至りません。バグと無関係の場所に異常現象が現れるバグは、タチが悪く、原因究明に時間がかかります※4)。上記のバグを引き起こさないためには、「配列nameの領域を増やす」「領域内までしかコピーしない」などの対策をせねばなりません。strcpy関数の使用方法を誤るとバグにつながるので、注意が必要です。〜ちょっと休憩して、バグ探しに挑戦〜」では、ミスリードが非常に多く、バグの解決に時間がかかったケースとして、筆者の体験談を取り上げました。5.自己採点シート今回の自己採点シートを以下に示します。自己採点シート6.終わりに今回は、バッファオーバーランのバグを仕込んだ、テストデータ表示プログラムを出題しました。皆さんは、バグを見つけることができたでしょうか。バッファオーバーランは、関係のない場所に異常が現れる「タチの悪いバグ」だと思います。筆者も、プログラムが想定通りにいかないことがありました。「おかしいなぁ」と数時間悩み、あらゆる場所にprintf関数を仕掛け、バッファオーバーランを見つけた経験があります。組み込みソフトの開発では、メモリ領域を参照したり、書き換えたりすることが多くあります。メモリの領域を誤って書き換えると、プログラムは通常では考えられない不可解な動作をします。筆者のように、煮詰まって苦労する前にバッファオーバーランを見つける嗅覚を備えていただければと思います。2016年より非常勤講師。〜ちょっと休憩して、バグ探しに挑戦〜あれは米国ボストンに駐在していたときのこと——。ある日、私が管理していたオフィスの入退室セキュリティシステムが動作しなくなった。その当時、大流行がウワサされていたあるウイルスの存在のせいなのか、あるいは......。バグ検出ドリル(12)コンパイルエラーにならないコンパイルエラーバグは至るところに、しかも堂々と潜んでおり、自信満々なプログラマーほど、目の前のバグに気付かないものです。「バグ検出ドリル」の第12回は、前回に引き続き「コンパイルエラー」がテーマです。コンパイルエラーにはならないのに、うまく動かないプログラムのバグを見つけ出してください!バグ検出ドリル(11)コンパイルエラーは意外に難しいバグは至るところに、しかも堂々と潜んでおり、自信満々なプログラマーほど、目の前のバグに気付かないものです。「バグ検出ドリル」の第11回では、初心者が苦労する「コンパイルエラー」がテーマです。コンパイラが指し示すエラーの箇所から、バグを見つけ出してください!バグ検出ドリル(10)“昔のバグ”は生命力が最強バグは至るところに、しかも堂々と潜んでおり、自信満々なプログラマーほど、目の前のバグに気付かないものです。「バグ検出ドリル」の第10回では、生命力最強という“昔のバグ”がテーマです。前回の第9回で扱った迷路探索プログラムの改造版からバグを見つけ出してください!バグ検出ドリル(9)デバッグの基本的な心構えは「人を見たら泥棒と思え」バグは至るところに、しかも堂々と潜んでおり、自信満々なプログラマーほど、目の前のバグに気付かないものです。SNSfacebooktwitterITmediaはアイティメディア株式会社の登録商標です。