0

これは私の前の質問に関連しています。 ベクトルとスタックのオーバーフロー

しかし、うまくいけば、新しい状況(そして私の新しい質問)を説明するでしょう。だから昨日、私はこのスタックオーバーフローの例外に突破口があると思った、私はそれを解決したと思った。その時、私はとても疲れていて、かなりの数のコードがコメントアウトされていましたが。

今朝、ゲームをやり直して、すべてを元に戻すことから始めました。たった30分ほど前に絶望して、昨日克服したと思った血まみれのエラーメッセージが表示されました:/。

残念ながら、最初の質問に戻りましたが、前の質問への回答に移り、敵のアニメーションであると私が信じている根本的な原因を見つけようともう一度考えています。以下は、敵とアニメーションクラスのヘッダーファイルです。

Anim- http://pastebin.com/uKQB1RVq

敵-http ://pastebin.com/pktA1vXi

私の敵のクラスでわかるように、アニメーションを除いて、この例外を引き起こしていると私が感じていることについて話す価値のあるメモは実際にはありません。(他の唯一のものは私のタイマーのクラスです。これはほんの数intとboolであり、これも私がメモリを大量に消費すると見なすことができるものは何もありません。)

だから私の質問はこれです。

  1. どうすればこれについて100%ポジティブになることができますか?IDE(Visual C ++ 2010)に、使用されているスタックメモリの量を確認する方法はありますか?
  2. qから続く。1、この問題の解決策は何でしょうか。たとえば、アニメーションが実際に例外の原因であるかどうかは100%確信できませんが、アニメーションをコメントアウトして、アニメーションのベクトルを作成すると、問題なく正常にコンパイルされます。それが進むべき道でしょうか?

*テストシナリオを設定しました。Vector2とRectArrayの配列を20ではなく15に減らすと、プレーンな古い4つのアニメーション呼び出しを使用することがわかります(これらは単純な構造体であり、プレーンな古いxのintを含みます) &y、次にx、y、width、heightの場合)ゲームは正常にコンパイルされます(これが、問題であるAnimationクラスに傾倒している主な理由である可能性が高いです)。を使用して、それをアニメーションのベクトル配列の作成で使用するものと比較すると、これがより重要な問題であるかどうか、または実際に何か他のものであるかどうかを適切に判断できるようになるはずです。

編集:オーバーフローをさらに調べて、ゲームの分解情報を調べています。スタックオーバーフロー固有は、オーバーフローが発生する特定のアドレスを指します。 0xC0000005

そのアドレスを検索すると、このビューが表示されます。 ここに画像の説明を入力してください

これらのアドレスに保持されているものをどうすればよいかわかりません。カーソルを合わせると、非常に多くの番号が表示されます。私が言えるのは、これらの「???」がたくさんあるということだけです。しかし、私はそれらが何かを意味する可能性があると思います。

4

1 に答える 1

1

以前の投稿への回答で述べたように、スタックオーバーフローエラーを取得する方法は基本的に3つあります。

  1. 無限再帰。これは非常に簡単に特定できます。再帰関数が正しく機能し、状況によっては常に終了する場合は、すべての再帰関数を確認してください。

  2. スタックに巨大な変数を割り当てます。これは実際には最初の問題に関連しています。別の再帰呼び出しのローカル変数用のスペースがスタックにないため、再帰スタックオーバーフローが発生します。また、簡単に特定できます。問題を引き起こすには、静的に配置された多数の(または少数ですが大きい)配列(コンパイル時にサイズがわかっている)または構造体を使用する必要があります。

  3. Buferオーバーラン。実際の問題はその原因のずっと後に発生する可能性があるため、これは追跡するのに最悪の悪夢です。

次の方法で問題を突き止めようとすることをお勧めします。

  • 問題がまだ発生している間に、できるだけ多くのコードをコメントアウトします。運が良ければ、実際に問題を引き起こしている場所をコメントアウトします。そうしないと、分析するコードが大幅に少なくなります。
  • WinDbg(プラットフォームSDKで利用可能)を使用して、クラッシュの瞬間に詳細な呼び出しスタックを取得します。次のエントリをシステムレジストリに追加して、オペレーティングシステムに、部分的または完全なプロセスメモリダンプをファイルに収集させることができます。これにより、事後分析を実行できます。

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\YourAppName.exe] "DumpFolder"=hex(2):63,00,3a,00,5c,00,44,00,75,00,6d,00,70,00,73,00,00,00 "DumpType"=dword:00000002 "DumpCount"=dword:0000000F

この変更により、アプリケーションがクラッシュするたびにac:\dumpsフォルダーに完全にダンプされます。

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\YourAppName.exe] "DumpFolder"=hex(2):63,00,3a,00,5c,00,44,00,75,00,6d,00,70,00,73,00,00,00 "DumpType"=dword:00000001 "DumpCount"=dword:000000FF

この変更により、アプリケーションがクラッシュするたびに、ac:\ dumpsフォルダーに小さなダンプ(〜40 Mb)が作成されます。

  • Application Verifierツールを使用して、スタックに格納されているリターンアドレスを損傷する可能性のある潜在的なバッファオーバーランを追跡します。

  • 構造とクラスのいくつかの重要なフィールドにガードを追加します。

const char * sentry1 = "0123456789";
void * vitalField;
const char * sentry2 = "0123456789";

特にクラス、構造、メソッドの最初と最後に使用してください。デバッグモードを使用して、オプティマイザがそれらを(未使用として)最適化しないようにします。

クラッシュ後、メモリダンプを収集し、すべてのガードが変更されていないかどうかを確認してください(これは難しいかもしれませんが、不可能ではありません)。

  • 最後に、非常に詳細なコードレビューを実行して、バッファオーバーランが発生しないことを確認できます。


編集:

次の方法で、WinDbgダンプテストをもう少し自動化できます。

  • 次の環境変数を設定します。

_NT_SYMBOL_PATH=symsrv*symsrv.dll*c:\symbols*http://msdl.microsoft.com/download/symbols

WinDbg、Visual Studio、およびProcessExplorerで使用されます

  • WinDbgディレクトリに次のファイルを作成します。

コマンド.txt

.sympath+.
.reload
kb

  • 次のエントリをレジストリに追加します(システムが32ビットか64ビットかを確認し、必要に応じて変更します)。

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT.dmp] @="Debugger.Dump"

[HKEY_CLASSES_ROOT\Debugger.Dump]

[HKEY_CLASSES_ROOT\Debugger.Dump\Shell]

[HKEY_CLASSES_ROOT\Debugger.Dump\Shell\Debug_Without_Remote] @="WinDbg This Dump"

[HKEY_CLASSES_ROOT\Debugger.Dump\Shell\Debug_Without_Remote\Command] @="\"C:\Program Files\Debugging Tools for Windows (x64)\windbg\" -z \"%1\" -QY -c \"$<C:\Program Files\Debugging Tools for Windows (x64)\commands.txt\""

幸運を :)

于 2012-07-24T10:19:38.480 に答える