VC++ releaseモードとdebugモードの動作差異について

解決


せいだい  2007-04-06 19:40:59  No: 64872

VC++6.0のreleaseモードだと「アプリケーション ポップアップ: xxxxxxxx.exe - アプリケーション エラー :
"0x77fcbef4" の命令が "0x05aa8002" のメモリを参照しました。メモリが
"written" になることはできませんでした。」のエラーになりますが、debugモードだと正常に動作します。テキストファイルを解析するプログラムです。入力するテキストファイルが2GB近くある大きなファイルですが、それ以外に特別なことは行っていません。また、いつもよりも少し大きな入力ファイルに対してこの現象が発生しました。何らかのバグが表面化しているのだとは思いますが、もしや、release/debugで何かリソースに違いがあるとか、そういうような情報がありますでしょうか?


tetrapod  2007-04-06 21:28:57  No: 64873

debug と release ではコンパイラ/ライブラリの挙動がかなり異なるんで
debug/release の片方では正常動作し片方ではエラーになるというのは
結構ありがちな動作。俺もなったことあるし。

潜在バグが表面化してるには俺も1票を投じる。

普段は 2GB 近く→今回は少し大きい、ファイルってことは
もしかして今回のファイルサイズは 2147483647 byte 超なのかな?
これは signed int の符号が変化して正数→負数にかわるところなんで
もろ潜在バグが出るパターン。
まずは Debug モードに 2GB 超のファイルを食わせてみるべし。


PATIO  2007-04-06 22:28:26  No: 64874

デバッグモード時はデバッグ情報が追加されたり、デバッグ用の領域が
内部でこっそり取られたりするはずなのでメモリ上での変数の配置が
リリースモードとは変わると思います。デバッグ時はこの辺の表から
見えない情報のお陰でメモリを壊したりしていても表面化しない場合が
多いです。特にローカル変数なんかはリリースモード時とデバッグモード時で
非初期化状態が違うはずですからその辺が原因になったり、
メモリ上の変数の配置が変わるためにスタック内部の状況に変化がある場合も
ありえると思います。スタック内部の状況に動作が左右されないようにするのが
本来の有るべき姿ですから、この状態はすなわち不具合と言えます。
その他、リンクされているライブラリがデバッグ用だとか諸々違うわけですから
既に挙げた内容だけが原因とは限りません。

デバッグ版とリリース版は意図通りにプログラミングされていれば、
動作は同じになるはずですけれど、バイナリファイルとして見たときは
別物になると思います。


せいだい  2007-04-06 22:36:34  No: 64875

参考になるご意見ありがとうございました。ファイルサイズはちょっと大げさでした実際は1.6GBでした。結局、腰を落ち着けてデバッグするしかないと分かりました。それにしても、releaseでOK、debugでNGなら、デバッグしやすいのですが、つらいところです。


tetrapod  2007-04-06 23:11:28  No: 64876

Release モードでも Debug 情報の付加ができるので試して味噌。
ただし最適化によってデバッガの使い勝手が悪くなる。
一部の変数が見えなくなったり、
特定行にはブレイクポイントを置けなかったり
ブレイクポイントを置いたはずが(インライン展開の結果)そこは通過しなかったり。
# 製品出荷の時には元に戻そう

警告レベルを上げてみるだけでも結構簡単に問題点が見つかる。
0円で済むのでやってみる価値はある。
お金かけていいならツール類を使おう。 Purify とか高価だけど役に立つよ。


PATIO  2007-04-07 02:19:17  No: 64877

> Release モードでも Debug 情報の付加ができるので試して味噌
確かにそうですね。要はプロジェクトの設定しだいですから。
最初から用意されているDebugとReleaseは、そのお題目に合っているであろう
設定の代表例ですからねぇ。
状況によって弄る事はありますから必ずしもDebugモードだからデバッグ情報が
付加されているとは限りませんもんね。
結局の所はプロジェクトの設定によります。
ただ、特にプロジェクトを弄らずに使っているような場合なら
私の話もあながち間違いではないでしょう。

その昔ですが、コンパイラの警告レベルは最高か最高の一つ下でやれと
よく言われてました。コンパイラにバグの予備軍を発見させる為です。
但し、出てきた警告を潰す為に機械的にキャストを使うようだと効果無しなので
その辺は出てきた警告の内容をちゃんと吟味して対応する事をお勧めします。

ちなみにPurifyよりは安い奴でInsure++って言うのがあります。
確か15万くらいだったと思います。
とはいえ、Rational PurifyPlusでも21万くらいであるのね。
前はもっと高かったような気もするけど。


_t  2022-12-07 01:03:27  No: 150707

テキスト
3072 90 0 3c 4c 
3072 90 0 3c 4c 
3245 80 0 3c 40 

コード
while(fscanf(fp, "%d %x %x %x %x ", &dwTimestamp, &bStatus, &bChannel, &bData1, &bData2) != EOF)

これをDebugでコンパイルすると値が正常
これをReleaseでコンパイルすると値が異常

明らかにバグですね


※返信する前に利用規約をご確認ください。








  このエントリーをはてなブックマークに追加