プログラミング、リファクタリング、そしてすべてにおける究極の疑問: No. 36

その他インテル® DPC++/C++ コンパイラー特集

この記事は、インテル® デベロッパー・ゾーンに公開されている「The Ultimate Question of Programming, Refactoring, and Everything」の日本語参考訳です。


36. PC の動作が不安定な場合はメモリーをチェックする

ここまでさまざまなエラーパターンを見てきて、皆さんも少しお疲れでしょう。そこで、このセクションでは、コードから離れてみましょう。

プログラムが適切に動作しないが、何が起こっているのかさっぱり分からない、というのはよくある状況です。このような場合、誰かを非難するのではなく、コードに注目すると良いでしょう。99.99% のケースでは、開発チームの誰かによる非常に愚かで陳腐なバグが原因であるため、コードを確認することをお勧めします。

バグがときどき発生するという事実は、何も意味しません。単にハイゼンバグ (Heisenbugs) である可能性があります。

コンパイラーを非難するのはもっと良くありません。もちろん、コンパイラーも間違いを犯すことはありますが、非常にまれです。例えば、原因が sizeof() の不正使用であることが判明したら、決まりが悪いだけです。これについては、私のブログ「すべての責任はコンパイラーにある」 (英語) を参照してください。

しかし、いくつかの例外があります。非常にまれですが、バグがコードとは関係ないことがあります。その可能性を認識しておくべきです。そうすることで、迷宮に入り込まずに済むでしょう。

私が実際に経験したケースでこの例外について説明します。幸いにも、必要なスクリーンショットが手元にあります。

私は、Viva64 アナライザー (PVS-Studio の前身) の機能を紹介する簡単なテスト・プロジェクトを作成していましたが、プロジェクトが正しく動作しませんでした。

長く厄介な調査の後、1 つのメモリースロットがすべての問題の原因であることを突き止めました。具体的には 1 ビットです。次のスクリーンショットから分かるように、私はデバッグモードでこのメモリーセルに値 “3” を書き込んでいます。

メモリーが変更された後、デバッガーはその値を読み取り、ウィンドウに表示します。次のスクリーンショットから、その値が 2 (0x02) であることが分かります。値 “3” を設定したのにもかかわらず、下位ビットは常にゼロになります。

メモリー・テスト・プログラム (英語) でも、この問題を確認できました。PC が問題なく正常に動作していたのは不思議です。メモリーバンクを変更することで、最終的にプログラムは正しく動作するようになりました。

私は非常に運が良かったと言えるでしょう。私が扱っていたのは、簡単なテストプログラムだったからです。それでも、何が起こっているのか理解するのに長い時間を費やしました。奇妙な動作の原因を特定するため、アセンブラー・リストの調査に 2 時間以上もかかりました。そして、私もコンパイラーを非難していました。

これが実際のプログラムであったら、どれぐらい大変だったか想像できません。ほかにデバッグすべきものがなかったのは幸いでした。

推奨事項

常にコード内にエラーがないか確認します。責任を転嫁すべきではありません。

ただし、バグが 1 週間以上にわたってあなたのマシンでのみ繰り返し発生する場合、原因はコードではない可能性もあります。

バグの調査を続けるべきです。そして、帰宅する前に、夜間の RAM テストを実行します。この簡単なステップにより、神経をすり減らさずに済むかもしれません。

コンパイラーの最適化に関する詳細は、最適化に関する注意事項を参照してください。

タイトルとURLをコピーしました