リリースモードだと死ぬ・・・

[戻る]
大三元 2006/06/27(火) 14:40:54
こんにちわ。
Windows XP VC++6.0ダイアログアプリです。

をリリース版EXEを実行するとある場所で死にます。
エラー内容を送信する/しない のボタンがあるダイアログがでてきます。

ダイアログAのOKボタンを押し、OnOK関数が実行され、
最後の行のCDialog::OnOK();も実行されています。
しかし、WM_DESTROY関数がコールされる前に死んでいます。

デバッグモードではこういうことは起きないのですが・・・
なぜでしょう?
誰か何かわかるかたいませんか?

Blue 2006/06/27(火) 14:49:29
> ある場所で死にます。
ある場所が特定できているならば、修正できませんか?

Debugで落ちなくて、Releaseで落ちる場合、メモリ関係で不正にアクセスしているとい
うのがほとんどです。


というか、あまり「死ぬ」という表現はやめたほうがいいです。
(以前も同じような表現を使っていましたよね?)

てんてく 2006/06/27(火) 14:59:12
http://hata.cc/docs/Win32Map/contents.html

Release でのみアプリケーションが終了するような場合(Debugできない場合)
このような方法で原因を特定できる場合がありますよ。

tetrapod 2006/06/27(火) 15:01:15
>ある場所が特定できているならば、修正できませんか?
そこが原因ならね。
メモリ破壊→一見全く関係ない場所でクラッシュ発生、ってのがメモリ破壊の典型パターン
ですから(たいてい、クラッシュ報告が出てる場所は一切バグっていない)

Debug版で警告表示が出ていませんか?出ていればバグの可能性が極めて高いです。
無視せず追求すべし。

多くの場合、こういうのって自動変数配列のオーバーランだったりするんだが
これだと警告なしにクラッシュすることが多くて困りものですな。

大三元 2006/06/27(火) 15:03:04
>Debugで落ちなくて、Releaseで落ちる場合、メモリ関係で不正にアクセスしているとい
>うのがほとんどです。
おそらくそうだとは思うのですが・・・
リリースなんでブレーク当てられないので、
メッセージボックスを表示させて追いかけたところ、
OnOK関数最終行のCDialog::OnOK();の後では表示されました。
ですが、OnDestroy関数の先頭のメッセージボックスは表示されませんでした。

>ある場所が特定できているならば、修正できませんか?
落ちえいる場所が自分が記述したコードの場所ではないので
よくわかりません。
実行時エラーのようにファイル名と行の記述もないので・・・
こういう場合どうしたらいいのでしょう?

大三元 2006/06/27(火) 15:07:07
>Debug版で警告表示が出ていませんか?
でていません。
とりあえず、メモリのアクセスしているところを追いかけて見るしかないのかな!?

Blue 2006/06/27(火) 15:22:18
> とりあえず、メモリのアクセスしているところを追いかけて見るしかないのかな!?
そうですね。
回答者側に、何一つコードを載せていない以上、あなたがやるしかないです。

まずは
tetrapodさんもおっしゃっていますが、配列の上限を超えて格納をしていないかチェッ
クしてみてはどうでしょうか?

例)
int a[ 10 ];
int i = 0;

・
・
a[ i ] = 10; // i>=10になっているとか

char* p;
・
・
char s[ 10 ];
strcpy( s, p ); // コピーする文字数が格納領域を超えているとか

大三元 2006/06/27(火) 15:34:42
>回答者側に、何一つコードを載せていない以上、あなたがやるしかないです。
OnOK関数は以下のコードです。

CString str;
BYTE data;

// エディットボックスの文字列を取得する
m_Edt1_Ctl.GetWindowText(str);
str.TrimLeft();
str.TrimRight();

// 2文字より多い時はリターン
if( 2 < str.GetLength() ){
    AfxMessageBox("16進数2桁で入力して下さい", MB_ICONSTOP, MB_OK);
    return;
}

// 16進数変換できなければリターン
if( 0 == sscanf(str,"%02X",&data) ){
    AfxMessageBox("16進数2桁で入力して下さい", MB_ICONSTOP, MB_OK);
    return;
}

m_CmdNum = data;

CDialog::OnOK();

>tetrapodさんもおっしゃっていますが、配列の上限を超えて格納をしていないかチェ
>ッ
>クしてみてはどうでしょうか?
別の場所のチェックをしてみます。

REE 2006/06/27(火) 15:41:00
>BYTE data;

>if( 0 == sscanf(str,"%02X",&data) ){
ここで普通にバッファオーバーフローしています。
sscanfはdata変数の位置にint型のサイズで書き込みを行うでしょう。

Blue 2006/06/27(火) 15:41:11
>     AfxMessageBox("16進数2桁で入力して下さい", MB_ICONSTOP, MB_OK);
>    AfxMessageBox("16進数2桁で入力して下さい", MB_ICONSTOP, MB_OK);
あんまり関係なさそうですが、これ間違っていない?
第3引数は「メッセージのヘルプ コンテキスト ID」ですよ。
(たまたまMB_OKが0であるからうまく動いているけど。)
MB_OKとMB_ICONSTOPの場合は、第2引数に | 演算子で指定します。

AfxMessageBox( "16進数2桁で入力して下さい", MB_ICONSTOP | MB_OK );

tetrapod 2006/06/27(火) 15:43:34
提示コードにはまさにメモリ破壊のバグがありますが、お気づき?

大三元 2006/06/27(火) 15:57:17
>sscanfはdata変数の位置にint型のサイズで書き込みを行うでしょう。
なに〜知りませんでした・・・
INT型に直したら、このクラスは通過しました(^o^)
でも、DoModal以下で落ちてます。
とりあえず心当たりがあるので、追いかけて見ます。

ちなみに、
AfxMessageBoxとCWnd::MessageBoxがごっちゃになっていたみたいです。
みんなはどっちを使ってるのかな?
どっちでも同じだと思ってました。

え〜いち 2006/06/27(火) 16:15:15
直接の回答ではありませんが、Releaseビルドでステップ実行すればいいのでは?

プロジェクトの設定−C/C++のカテゴリ一般の最適化を「無効(デバック時)」
プロジェクトの設定−C/C++のカテゴリ一般のデバック情報を「しない」以外に
プロジェクトの設定−リンクのカテゴリ一般の「デバック情報を生成する」をONに

大三元 2006/06/27(火) 16:43:07
[[解決]]
ちゃんとエラー判定したら、OKでした。
ありがとうございました。

錯和 2006/06/27(火) 16:47:05
> ちゃんとエラー判定したら
ってどこのアドバイスから、その回答が?

asd 2006/06/27(火) 17:50:16
>大三元さん
結局どこにどういう問題があって、如何に解決したのかをフィードバックしてもらえませ
んか?

大三元 2006/06/27(火) 18:36:28
[[解決]]
>結局どこにどういう問題があって、如何に解決したのかをフィードバックしてもらえま
>せんか?
sscanfで取り込む変数の型をINT型にして解決しました。

古いスレッドには追加発言できません。