.NET WINXP MFC です。
自作したアプリをリビルドして、使い始めたところ、エラーが発生しました。
それで、ブレークポイントをばら撒いて、デバッグを繰り返したところ、最初の2回は変数に異常値が出ましたが、3度目以降はコードを全くいじっていないにもかかわらず、異常値は出なくなりました。
時々、「デバッグ不足」とか、「十分にデバッグして」という言葉を聞きますが、リビルドだけでは不十分で、このように何度かデバッグしているうちに、EXEファイルが完全になってゆく、というようなことはあるのでしょうか。
それとも、そんなことはなくて、どこか別なところのバグが影響して、時々おかしな動きをしている、という可能性が高いのでしょうか。
アドバイスをお願いします。
> 時々、「デバッグ不足」とか、「十分にデバッグして」という言葉を聞きますが、
> リビルドだけでは不十分で、このように何度かデバッグしているうちに、
> EXEファイルが完全になってゆく、というようなことはあるのでしょうか。
プログラムは書いたようにしか動きません。
リビルドして「バグが直る」ということは、基本的にありません。
# 古いバイナリが残ってしまった場合などに、リビルドすれば
# 最新の状態にすることはできます。
# そうでない場合には、何度リビルドしようが同じ動作結果にならないと、
# おそらくどこかがおかしいです。
> このように何度かデバッグしているうちに、
> EXEファイルが完全になってゆく、
> というようなことはあるのでしょうか。
デバッグして「バグを取れば」、正しい実行ファイルに近づきますが、
> 、3度目以降はコードを全くいじっていないにもかかわらず、
> 異常値は出なくなりました。
まったく修正していないのに、バグが直ることはありえません。
私の周りでは通常、こういう状況を「再現性がない/なくなった」とか、
「(バグが)潜伏した」とか呼んでます。
(再現環境を保存してないと、かなり厄介.....
> それとも、そんなことはなくて、どこか別なところのバグが影響して、
> 時々おかしな動きをしている、という可能性が高いのでしょうか。
おそらく、この通りです。
> 、3度目以降はコードを全くいじっていないにもかかわらず、
> 異常値は出なくなりました。
よくあるのは、変数の未初期化で、最初の2回は、たまたまエラーになる値になっていたが、
3回目以降はエラーにならない値になっていただけでは?
ありがとうございました。
値を代入する直前の行で、変数に0を代入しているのに、5行先で関係ない数字になった、というナゾなのですが、デバッグ不足が原因でないとすれば、必ずバグがあるはずなので、よく調べます。
ただ、Banさんがおっしゃるように、その後何度やっても、異常は発生しません。
けっこう、頭が痛いです。
メモリ破壊とかしてると、呼び出し順番などによって壊れたり壊れなかったりとか。
ちなみに、マルチスレッドだったりしますか。
すみません。
マルチスレッドです。
あと、処理中、アニメーションを動かしています。
関係あるのでしょうか。
マルチスレッドだと、作り次第で、触ってない筈の変数も非同期で破壊できるかと。
排他制御の穴とかもはまりがち。
あとはスレッドを問わず、
既にあがってるように、未初期化参照とか、範囲外参照、メモリ破壊系か。
もしくは、ファイルとか通信とか外部要因の変化に起因してるか。
リリース/デバッグやオプションが変わってるとか…
外部要因は変わらないか確認して、メモリ参照は自動チェックを活用。
やっかいなのはやはりスレッド回りが原因の場合でしょうか。
デバッガで止めるだけで潜伏したりする…。
具体的なレスはできませんが、何か参考になれば。
マルチスレッドということなどで、ひとつ私の経験談を。
メインスレッドではなく、メインスレッドから作成されたスレッドで、
特定の変数の値が急に変な値になることがありました。
ある関数の呼び出し前で変数の値を表示するのですが、関数を呼び出したときには、
変数の値が別な値になっているという、非常に不可解なものでした。
原因は、スレッド作成時のスタックが不足していたために、
メインスレッド側からスタックを破壊されていたようでした。
対策として、スレッド作成時のスタックサイズを大きくすると問題が解決しました。
ポチョムキンさんの問題と同じことはないと思いますが、
マルチスレッドでは気をつけないといろいろと問題が起こる一例ということで。
#ちなみにこの問題が発生した環境はWindowsではありませんでしたが。。。
マルチスレッドといっても、処理中にキャンセルボタンを活かそう、というくらいなのですが。。。。
相当にしつこくデバックしたのですが、その後全く異常は発生しません。
もう少し、様子をみてみます。
たいへんありがとうございました。
おせっかいなようですが、デバッグの意味(それから、リビルドも)を理解されていないような感じなので。
デバッグとは、エラーの原因を追究し、判明した原因を
プログラムから取り除くことです。
ブレークポイント云々はいろいろあるエラー原因追求の手段の
一つに過ぎません。
まさか、デバッグ実行すれば、エラーが消えるとは思ってないだろうけど、
貴兄の書き方だとそのようにも取れる。