9

助けてください!私は本当に頭が痛いです。私のプログラムは、ちょっとした個人的なノート マネージャーです (Google で「cintanotes」を検索)。一部のコンピューター (もちろん私は所有していません) では、起動直後に未処理の例外でクラッシュします。AMD CPU を搭載する傾向があることを除けば、これらのコンピューターについて特別なことは何も言えません。

環境: Windows XP、Visual C++ 2005/2008、raw WinApi。

この「Heisenbug」について確かなことは次のとおりです。

1) クラッシュはリリース バージョンでのみ発生します。

2) GDI 関連のものをすべて削除すると、クラッシュはすぐになくなります。

3) BoundChecker には文句はありません。

4) ログを書くと、ローカルの int 変数の宣言でクラッシュが発生したことがわかります! それはどうしてですか?メモリの破損?

どんなアイデアでも大歓迎です!

更新: 「障害のある」PC でアプリをデバッグすることができました。結果:

「CintaNotes.exe の 0x0044a26a で未処理の例外: 0xC000001D: 不正な命令。」

そしてコードが壊れる

0044A26A cvtsi2sd xmm1,dword ptr [esp+14h]

したがって、問題は「コード生成/拡張命令セットを有効にする」コンパイラオプションにあったようです。「/arch:SSE2」に設定され、SSE2 をサポートしていないマシンでクラッシュしていました。このオプションを「未設定」に設定したところ、バグはなくなりました。ふぅ!

助けてくれてありがとう!

4

11 に答える 11

10

4)ログを書き込むと、ローカルint変数の宣言でクラッシュが発生することが示されます。どうしてそうなの?メモリの破損?

実行可能ファイル/アセンブリの基礎となるコードは何ですか?intの宣言はコードではないため、クラッシュすることはありません。どういうわけかintを初期化しますか?

クラッシュが発生したコードを確認するには、いわゆる事後分析を実行する必要があります。

Windowsエラー報告

クラッシュを分析する場合は、クラッシュダンプを取得する必要があります。このための1つのオプションは、Windowsエラー報告に登録することです-いくらかのお金(デジタルコード署名IDが必要です)といくつかのフォーム入力が必要です。詳細については、https://winqual.microsoft.com/にアクセスしてください。

WER向けのクラッシュダンプをお客様から直接入手する

もう1つのオプションは、クラッシュが発生しているユーザーに連絡を取り、WER向けのクラッシュダンプを直接取得することです。ユーザーは、クラッシュをMicrosoftに送信する前に技術的な詳細をクリックすると、これを行うことができます。クラッシュダンプファイルの場所をそこで確認できます。

あなた自身のミニダンプ

もう1つのオプションは、独自の例外ハンドラーを登録し、例外を処理して、必要な場所にミニダンプを書き込むことです。詳細な説明は、MinidumpsおよびVisualStudio.NETを使用したアプリケーションの死後デバッグのコードプロジェクトの記事に記載されています。

于 2008-09-25T08:46:59.983 に答える
5

構成がDEBUG構成の場合、クラッシュしませんか?RELEASE 構成とは異なる点が多数あります: 1.) グローバルの初期化 2.) 実際のマシン コードの生成など..

したがって、最初のステップは、DEBUG モードと比較して、RELEASE モードの各パラメーターの正確な設定を見つけることです。

-広告

于 2008-09-25T08:38:13.093 に答える
4

1) クラッシュはリリース バージョンでのみ発生します。

これは通常、保証されていない動作に依存していることを示していますが、デバッグ ビルドではたまたまそうです。たとえば、変数の初期化を忘れたり、範囲外の配列にアクセスしたりした場合です。すべてのコンパイラ チェック (/RTCsuc) がオンになっていることを確認します。また、関数パラメーターの評価の順序に依存するなどのことも確認してください (これは保証されていません)。

2) GDI 関連のものをすべて削除すると、クラッシュはすぐになくなります。

多分それは、GDI関連のもので何か間違ったことをしているというヒントですか? たとえば、解放された後に HANDLE を使用していますか?

于 2008-09-25T08:43:52.173 に答える
2

Windowsパッケージのデバッグツールをダウンロードします。シンボルパスを正しく設定してから、WinDbgでアプリケーションを実行します。ある時点で、アクセス違反で破損します。次に、コマンド「!analyze -v」を実行する必要があります。これは非常に賢く、何がうまくいかないかについてのヒントを与えるはずです。

于 2008-09-25T10:09:38.833 に答える
1

この種のものを入手したら、BoundsCheckerに対してさまざまなクラスのエラーをチェックするため、gimpels PC-Lint(静的コード分析)を介してコードを実行してみます。Boundscheckerを使用している場合は、メモリポイズニングオプションをオンにします。

あなたはAMDCPUについて言及しています。クラッシュするマシンに同様のグラフィックカード/ドライバのバージョンおよび/または構成があるかどうかを調査しましたか?これらのマシンでは常にクラッシュしますか、それともたまにクラッシュしますか?たぶん、これらのマシンでシステム情報ツールを実行して、それらに共通するものを確認してください。

于 2008-09-26T07:32:59.793 に答える
1

4)ログを書くと、ローカルのint変数の宣言でクラッシュが発生することが示されています!メモリの破損

this多数の「奇妙なクラッシュ」の原因は、オブジェクトのメンバー関数内の破損を間接参照していることであることがわかりました。

于 2008-09-25T09:05:24.773 に答える
1

Rational(IBM)PurifyPlusをお試しください。BoundsCheckerにはない多くのエラーをキャッチします。

于 2008-09-25T09:08:24.423 に答える
1

クラッシュは何と言っていますか?アクセス違反 ?例外 ?それはこれを解決するためのさらなる手がかりになるでしょう

PageHeap.exeを使用して、先行するメモリの破損がないことを確認します

スタックオーバーフローがないことを確認してください(CBig array [1000000])

初期化されていないメモリがないことを確認してください。

さらに、プロセスのデバッグシンボル(デバッグバージョンの作成とは異なります)を生成すると、デバッガー内でもリリースバージョンを実行できます。ステップスルーして、デバッガーのトレースウィンドウに警告が表示されるかどうかを確認します。

于 2008-09-25T10:02:26.477 に答える
1

ほとんどの heisenbugs / release-only bugs は、初期化されていないメモリからの読み取りに依存する制御フロー / 古いポインター / 過去のバッファーの終わり、競合状態、またはその両方が原因です。

アロケーターをオーバーライドして、割り当て時にメモリをゼロにするようにしてください。問題はなくなりましたか (または再現性が高くなりましたか?)

ログを書くと、ローカルの int 変数の宣言でクラッシュが発生したことがわかります。それはどうしてですか?メモリの破損?

スタックオーバーフロー!;)

于 2008-09-25T08:37:49.927 に答える
1

私にはスタックの破損のように聞こえます。それらを追跡するための私のお気に入りのツールはIDA Proです。もちろん、ユーザーのマシンへのアクセス権はありません。

一部のメモリ チェッカーは、スタックの破損を検出するのに苦労しています (実際にそうである場合)。私が考えるそれらを取得する最も確実な方法は、ランタイム分析です。

これは、例外が処理された場合でも、例外パスの破損が原因である可能性があります。「最初のチャンスの例外をキャッチ」をオンにしてデバッグしますか? できる限り長くする必要があります。多くの場合、しばらくすると迷惑になります。

それらのユーザーにアプリケーションのチェック済みバージョンを送信できますか? Minidumpを確認してください その例外を処理し、ダンプを書き出します。次に、WinDbgを使用してデバッグします。

もう 1 つの方法は、非常に詳細なログを作成することです。「すべてのアクションをログに記録する」オプションを作成し、ユーザーにそれをオンにして送信するように依頼します。ログにメモリをダンプします。MSDN で「_CrtDbgReport()」を確認してください。

幸運を!

編集:

コメントへの返信: ローカル変数宣言のエラーは、私にとって驚くべきことではありません。私はこれをたくさん見てきました。通常、スタックの破損が原因です。

たとえば、スタック上の一部の変数がその境界を越えて実行されている可能性があります。その後、すべての地獄が解き放たれます。次に、スタック変数の宣言がランダムなメモリ エラーをスローしたり、仮想テーブルが破損したりします。

長期間それらを見たときはいつでも、IDA Proに行かなければなりませんでした. 詳細な実行時逆アセンブル デバッグは、これらを確実に取得できる唯一の方法です。

多くの開発者は、この種の分析に WinDbg を使用しています。そのため、Minidump も提案しました。

于 2008-09-25T08:46:39.157 に答える
1

「4) ログを書き込むと、ローカルの int 変数の宣言でクラッシュが発生したことが示されます! どうしてですか? メモリの破損ですか?」

これは、ハードウェアが実際に故障しているか、過度にプッシュされていることを示している可能性があります。コンピューターがオーバークロックされているかどうかを調べます。

于 2008-09-25T12:40:24.943 に答える