-1

2年前からゲームのプログラミングをしています。ときどきメモリ エラー (つまり、関数が返すはずのものではなくジャンクを返す、または Linux でのみ発生し、GDB や Windows では決して発生しないクラッシュ) がランダムに発生することがあります。つまり、私はそれを修正しようとしましたが、数か月後に同じエラーが戻ってきて私を悩ませました。

その問題を解決するのに役立つソフトウェア(Valgrindではなく、すでに試しました...エラーが見つかりません)がありますか?または、これらのエラーを解決する方法はありますか? それらを永久に修正したい。

4

5 に答える 5

3

Windowsでは、本番環境でクラッシュする例外を自動的にキャプチャし、デバッガーの下で開発者のPCでエラーが発生したかのように分析できます。これは、「ミニダンプ」ファイルを使用して行われます。基本的に、Windowsの「dbghelp.dll」DLLを使用して、スレッドスタック、ヒープの一部またはすべて、レジスタ値、ロードされたモジュール、およびクラッシュの原因となった未処理の例外のコピーを生成します。この「.dmp」ファイルは、実行可能ファイルであるかのようにMS Visual Studioデバッガーで起動でき、クラッシュが発生した場所を正確に示します。

未処理の例外のトラップを設定し、ミニダンプファイルの作成をそのトラップ内のdbghelp.dllに委任できます。デバッグエクスペリエンスを向上させるには、デプロイされたバイナリで生成された「.pdb」ファイルを保持して、メモリアドレスとソースコードの場所を一致させる必要があります。このトピックは深すぎて完全にカバーできません。このDLLに関するMicrosoftのドキュメントを参照してください。

完全にデバッグするには、クラッシュしたPCから開発環境に.dmpファイルをコピーできる必要があります。ユーザーとハンズオフの関係にある場合は、インターネット経由で別のユーティリティアプリ「phonehome」を使用して、.dmpファイルをアクセス可能な場所に転送するオプションが必要になります。.dmpファイルが生成された後、未処理の例外トラップからアプリを起動できます。ユーザーのプライバシーのために、これを行うかどうかのオプションをユーザーに提供する必要があります。

于 2010-02-10T04:23:53.217 に答える
1

プロジェクトで Hans Boehm GC を使用することもできます。リーク検出器として使用でき、疑わしいように見えるステートメントfree()deleteステートメントを削除し、それらがメモリ リークを引き起こしているかどうかを簡単に確認できます。

于 2010-02-10T23:22:23.363 に答える
1

Totalview デバッガー (商用ソフトウェア) がクラッシュをキャッチする場合があります。

Purify (商用ソフトウェア) は、メモリ リークを見つけるのに役立ちます。

コードはコンパイラの警告なしでコンパイルされますか? リントを実行しましたか?

于 2010-02-10T07:26:46.383 に答える
0

私の知る限り、WindowsのBoundscheckは非常にうまく機能します。私のプロジェクトの 1 つで、いくつかの非常に奇妙なエラーが発生しました。

于 2010-02-10T06:04:10.237 に答える
0

私自身のプロジェクト (Windows 上) でこれを回避するために、VirtualAlloc および VirtualFree と呼ばれる独自のメモリ アロケータを作成しました。リクエストごとに余分なページを割り当て、最後のページのすぐ左側に配置しVirtualProtect、最後のページにアクセスするたびに例外を生成していました。これにより、読み取りだけでも領域外アクセスがその場で検出されました。

免責事項: このアイデアを最初に思いついたのは決して私ではありません。

たとえば、ページが 4096 バイトでnew int[1]呼び出された場合、アロケータは次のようになります。

  1. 8192 バイトを割り当てます (4 バイトが必要で、これは 1 ページであり、追加のガード ページにより合計 2 ページになります)
  2. 最後のページにアクセス不可のマークを付ける
  3. 返すアドレスを決定します (最後に割り当てられたページは 4096 から始まります... 4096 - 2 = 4092)

次のコード:

main() {
    int *array = new int[10];
    return array[10];
}

その場でアクセス違反を発生させます。

割り当ての左側(つまり、array[-1])を超えたアクセスを検出する (コンパイル時) オプションもありましたが、この種のエラーはめったにないように思えたので、このオプションは使用しませんでした。

于 2010-02-10T23:19:29.840 に答える