PageHeap ユーティリティを使用して、Visual C++ プロジェクトのメモリ エラーを検出する
この記事では、PageHeap ユーティリティを使用して、Microsoft Visual C++ プロジェクトのメモリ エラーを検出する方法について説明します。 この記事の情報は、アンマネージド Visual C++ コードにのみ適用されます。
元の製品バージョン: Visual C++
元の KB 番号: 264471
概要
PageHeap ユーティリティをアプリケーションに対して有効にすると、すべての malloc
、 new
、および heapAlloc
割り当てがメモリ エラーを自動的に監視できます。
PageHeap1 は、いくつかの種類のメモリ エラーを含む Visual C++ プロジェクトです。 このサンプル アプリケーションで PageHeap を有効にするには、コマンド ラインから次の内容を入力します。
pageheap /enable pgh.exe 0x01
次に、次の内容を入力します。
pageheap
注:
PageHeap が監視するアプリケーション名。
多くのアプリケーションでは、 0x01
必要なフラグは 1 つだけです。 コマンド ラインから疑問符フラグ (/?
) を指定して PageHeap を実行すると、その使用状況の詳細を取得できます。
PageHeap のしくみ
PageHeap は、8 バイト境界で割り当てられたメモリへのポインターを返します。 返されたポインターの末尾に 0 から 7 のガード バイトが続きます (要求されたサイズに応じて、8 バイト境界にある要求サイズを切り上げるには 0 バイトから 7 バイトが追加されます)、その後にマークされた PAGE_NOACCESS
メモリ ページが続きます (詳細については、「 VirtualAlloc」を参照してください)。 例:
char * p;
p = new char[5];
PageHeap は、5 バイトと 3 つのガード バイトへのポインターを返して、合計 8 バイトを構成します.....Xxx。 メモリ割り当てサイズが 8 の倍数の場合、返されるポインターにガード バイトは追加されません。
割り当ての終了が上書きされると、ガード バイトが変更され、メモリが解放されると PageHeap によって アクセス違反 エラーが発生します。 アプリケーションが割り当て (ガード バイトを含む) を超えて読み取りまたは書き込みを行うと、インスタント アクセス違反 エラーが発生します。
PageHeap1 サンプルの使用方法
pgh プロジェクトをビルドし、pgh.exe を実行します。
注:
PageHeap でまたは
malloc
を操作するには、リリース ビルドをnew
実行する必要があります。PageHeap1.exe を起動します。 ダイアログ ボックスが表示されます。
ダイアログ ボックスには、TextBox、Bad Alloc/Free チェック ボックス、3 つのボタン のペア、新しい & 削除、PageAlloc & Heap Free、COM new & COM Delete が表示されます。 TextBox は、割り当てたいメモリのサイズを受け取ります。 [Bad Alloc/Free チェック] ボックスが選択されている場合、各割り当ての種類 (new、PageAlloc、COM new) はメモリを割り当て、割り当てを超えて書き込みます。 Bad Alloc がチェックされていない場合、メモリの上書きは発生しません。
ボタン新しいテスト演算子
new
、ボタン PageAlloc テストHeapAlloc
します。 新しい COM では、 を使用CoTaskMemAlloc
するのではなく、 を呼び出す COM ダイナミック リンク ライブラリ (DLL) を呼び出しますnew
。 COM を新しくテストするには、 r1LeakMemMod.dll 登録するか、r1LeakMemMod プロジェクトをビルドする必要があります。PageHeap を動作させるには、ランタイム DLL ライブラリを使用できます。 (Visual C++ 統合開発環境 (IDE) から、 プロジェクト>設定>C++>カテゴリ: コード生成>ランタイム ライブラリを使用します)。
Bad Alloc/Free のボックスをオンにした後、メモリ割り当てサイズが 5 バイトの場合は、新しいボタンを選択すると、5 バイトのメモリが割り当てられ、0 が 6 バイト目に書き込まれます。 6 番目のバイトへの書き込みはメモリの上書きが正しくありませんが、ガード バイトで発生するため、メモリが削除されるまで PageHeap はこのエラーを検出しません。 [削除] ボタンを選択すると、PageHeap によって上書きが検出され、次の例のようなエラー メッセージ ボックスが表示されます。
例外ブレークポイント ブレークポイントに達しました。 (0x80000003) は、場所0x77f9f9dfのアプリケーションで発生しました。
Just-In-Time (JIT) デバッガーとして Visual C++ を指定している場合は、[ キャンセル ] ボタンを選択してコードにデバッグできます。
割り当てサイズを 8 (または 8 の倍数) に変更した場合、新しいボタン、pageAlloc ボタン、または COM の [新規] ボタンを選択すると、アクセス権のないアドレスに書き込まれたため、すぐに アクセス違反 エラーが発生します。 (つまり、エラーを検出するためにメモリを削除する必要はありません)。
注:
- 制限事項: PageHeap では、ファミリ (したがって C++ 演算子
new
) とheapAlloc
からのmalloc
メモリ エラーのみを検出できます。 多くのアプリケーションでカスタム アロケーターが使用されており、PageHeap はこれらの割り当てをインターセプトできません。 - アプリケーションのテストが完了したら、コマンド ラインから実行
pageheap /disable <appName>
し、そのアプリケーションの PageHeap をオフにします。 - PageHeap 対応アプリケーションでは、PageHeap が有効になっていないと、同じアプリケーションよりもはるかに多くのメモリを消費する可能性があります。 メモリ需要の増加を満たすために、スワップ ファイルを増やす必要がある場合があります。
Pageheap1vcnet.exe はこちらから ダウンロードできます。 Microsoft サポート ファイルをダウンロードする方法の詳細については、「オンライン サービスから Microsoft サポート ファイルを入手する方法」を参照してください。
Microsoft はこのファイルをスキャンしてウイルスを検出しました。 Microsoft では、ファイルが投稿された日付に利用可能な最新のウイルス検出ソフトウェアを使用しました。 ファイルは、ファイルに対する未承認の変更を防ぐのに役立つセキュリティ強化サーバーに格納されます。
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示