リリースモードだと死ぬ・・・ – プログラミング – Home

リリースモードだと死ぬ・・・
 
通知
すべてクリア

[解決済] リリースモードだと死ぬ・・・

固定ページ 1 / 2

大三元
 大三元
(@大三元)
ゲスト
結合: 18年前
投稿: 54
Topic starter  

こんにちわ。
Windows XP VC++6.0ダイアログアプリです。

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

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

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


引用未解決
トピックタグ
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

> ある場所で死にます。
ある場所が特定できているならば、修正できませんか?

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

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


返信引用
てんてく
 てんてく
(@てんてく)
ゲスト
結合: 20年前
投稿: 92
 

http://hata.cc/docs/Win32Map/contents.html

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


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

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

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

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


返信引用
大三元
 大三元
(@大三元)
ゲスト
結合: 18年前
投稿: 54
Topic starter  

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

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


返信引用
大三元
 大三元
(@大三元)
ゲスト
結合: 18年前
投稿: 54
Topic starter  

>Debug版で警告表示が出ていませんか?
でていません。
とりあえず、メモリのアクセスしているところを追いかけて見るしかないのかな!?


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

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

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

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



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

char* p;


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


返信引用
大三元
 大三元
(@大三元)
ゲスト
結合: 18年前
投稿: 54
Topic starter  

>回答者側に、何一つコードを載せていない以上、あなたがやるしかないです。
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
 REE
(@REE)
ゲスト
結合: 23年前
投稿: 240
 

>BYTE data;

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


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

> 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
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

提示コードにはまさにメモリ破壊のバグがありますが、お気づき?


返信引用
大三元
 大三元
(@大三元)
ゲスト
結合: 18年前
投稿: 54
Topic starter  

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

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


返信引用
え~いち
 え~いち
(@え~いち)
ゲスト
結合: 19年前
投稿: 78
 

直接の回答ではありませんが、Releaseビルドでステップ実行すればいいのでは?

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


返信引用
大三元
 大三元
(@大三元)
ゲスト
結合: 18年前
投稿: 54
Topic starter  

ちゃんとエラー判定したら、OKでした。
ありがとうございました。


返信引用
錯和
 錯和
(@錯和)
ゲスト
結合: 18年前
投稿: 5
 

> ちゃんとエラー判定したら
ってどこのアドバイスから、その回答が?


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました