この記事では、PageHeap ユーティリティを使用して、Microsoft Visual C++ プロジェクトのメモリ エラーを検出する方法について説明します。 この記事の情報は、アンマネージ Visual C++ コードにのみ適用されます。
元の製品バージョン: Visual C++
元の KB 番号: 264471
まとめ
PageHeap ユーティリティをアプリケーションに対して有効にすると、すべての malloc
、 new
、および heapAlloc
割り当てがメモリ エラーを自動的に監視できます。
PageHeap1 は、いくつかの種類のメモリ エラーを含む Visual C++ プロジェクトです。 このサンプル アプリケーションで PageHeap を有効にするには、コマンド ラインから次の内容を入力します。
pageheap /enable pgh.exe 0x01
次に、次の内容を入力します。
pageheap
Note
PageHeap が監視するアプリケーション名。
多くのアプリケーションでは、 0x01
のみが必要なフラグです。 コマンド ラインから疑問符フラグ (/?
) を指定して 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 によって Access 違反 エラーが発生します。 アプリケーションが割り当て (ガード バイトを含む) を超えて読み取りまたは書き込みを行うと、すぐに Access 違反 エラーが発生します。
PageHeap1 サンプルの使用方法
pgh プロジェクトをビルドし、pgh.exeを実行します。
Note
new
またはmalloc
を操作するには、PageHeap のリリース ビルドを実行する必要があります。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 は
new
演算子をテストし、ボタン PageAlloc はHeapAlloc
テストします。 新しい COM では、CoTaskMemAlloc
ではなく、単にnew
を呼び出す COM ダイナミック リンク ライブラリ (DLL) を呼び出します。 COM を新規にテストするには、 r1LeakMemMod.dll 登録するか、r1LeakMemMod プロジェクトをビルドする必要があります。PageHeap を動作させるには、ランタイム DLL ライブラリを使用できます。 (Visual C++ 統合開発環境 (IDE) から)、 Projects>settings>C++>Category: Code Generation>Use ランタイム ライブラリ)。
Bad Alloc/Free のチェック ボックスをオンにした後、メモリ割り当てサイズが 5 バイトの場合は、新しいボタンで選択すると、5 バイトのメモリが割り当てられ、0 が 6 バイトに書き込まれます。 6 番目のバイトへの書き込みは無効なメモリ上書きですが、ガード バイトで発生するため、メモリが削除されるまで PageHeap はこのエラーを検出しません。 削除ボタンを選択すると、PageHeap によって上書きが検出され、次の例のようなエラー メッセージ ボックスが表示されます。
例外ブレークポイントブレークポイントに達しました。 (0x80000003) は、場所0x77f9f9dfでアプリケーションで発生しました。
Visual C++ が Just-In-Time (JIT) デバッガーとして指定されている場合は、 Cancel ボタンを選択し、コード内でデバッグできます。
割り当てサイズを 8 (または 8 の倍数) に変更した場合、new、pageAlloc、または COM New ボタンを選択すると、アクセス権のないアドレスに書き込んだため、 Access 違反 エラーが発生します。 (つまり、エラーを検出するためにメモリを削除する必要はありません)。
Note
- 制限事項: PageHeap は、
malloc
ファミリ (したがって C++ 演算子new
) とheapAlloc
からのみメモリ エラーを検出できます。 多くのアプリケーションではカスタム アロケーターが使用され、PageHeap はこれらの割り当てをインターセプトできません。 - アプリケーションのテストが完了したら、コマンド ラインから
pageheap /disable <appName>
実行して、そのアプリケーションの PageHeap をオフにします。 - PageHeap 対応アプリケーションでは、PageHeap が有効になっていないと、同じアプリケーションよりもはるかに多くのメモリを消費する可能性があります。 メモリ需要の増加を満たすために、スワップ ファイルを増やす必要がある場合があります。
ここでPageheap1vcnet.exe ダウンロードできます。 マイクロソフトのサポート ファイルをダウンロードする方法の詳細については、「オンライン サービスからマイクロソフトのサポート ファイルを入手する方法」を参照してください。
4013443 「更新プログラムの表示または非表示」トラブルシューティング ツール パッケージマイクロソフトでは、アップロード時点の最新のウイルス検査プログラムを使用して、 配布ファイルのウイルス チェックを行っています。 配布ファイルはセキュリティで保護されたサーバー上に置かれており、権限のない第三者が無断でファイルを変更できないようになっています。 配布ファイルはセキュリティで保護されたサーバー上に置かれており、権限のない第三者が無断でファイルを変更できないようになっています。