2

ヒープの破損を特定するために PageHeap を使用しています。アプリケーションのヒープが破損しています。ただし、メソッドに渡された文字列の stl オブジェクトを作成すると、アプリケーションが (クラッシュにより) 中断します。クラッシュ場所の近くに目に見えるメモリの問題は見られません。ヒープの破損を検出するためにフル ページ ヒープを有効にし、スタックの破損を検出するために /RTC を有効にしました。

ヒープの破損が発生した正確な場所でブレークするにはどうすればよいですか?

4

2 に答える 2

1

FULL ページヒープを有効にすると、デバッガーがヒープの破損をキャッチする可能性が高くなります。

gflags /p /enable /full <processname>

また、どのアドレスが上書きされているかがわかれば、windbg でメモリアクセスにブレークポイントを設定できます。VS デバッガーに同じ機能があるかどうかはわかりません。

于 2011-07-20T19:54:33.140 に答える
0

ページヒープは、ヒープの破損が発生した瞬間に正確に検出するとは限りません。

ページヒープは、割り当ての直後に無効なページを挿入します。したがって、割り当てられたブロックをオーバーランするたびに、AV が発生します。しかし、他にも考えられるケースがあります。1 つの例は、ヒープ ブロック ヘッダー データ構造を破壊する割り当てられたブロックの直前に書き込むことです。ヒープ ブロック ヘッダーは有効な書き込み可能なメモリです (ほとんどの場合、割り当てられたブロックと同じページにあります)。次の例を検討してください。

#include <stdlib.h>

int
main()
{
    void* block = malloc(100);
    int* intPtr = (int*)block;

    *(intPtr-1) = 0x12345; // no crash

    free(block); // crash

    return 0;
}

したがって、割り当てられたブロックが通過する直前にガベージを書き込んでも問題ありません。Pageheapを有効にすると、この例は呼び出し内で壊れますfree()。コールスタックは次のとおりです。

    verifier.dll!_VerifierStopMessage@40()  + 0x206 bytes   
    verifier.dll!_AVrfpDphReportCorruptedBlock@16()  + 0x239 bytes  
    verifier.dll!_AVrfpDphCheckNormalHeapBlock@16()  + 0x11a bytes  
    verifier.dll!_AVrfpDphNormalHeapFree@16()  + 0x22 bytes 
    verifier.dll!_AVrfDebugPageHeapFree@12()  + 0xe3 bytes  
    ntdll.dll!_RtlDebugFreeHeap@12()  + 0x2f bytes  
    ntdll.dll!@RtlpFreeHeap@16()  + 0x36919 bytes   
    ntdll.dll!_RtlFreeHeap@12()  + 0x722 bytes  
    heapripper.exe!free(void * pBlock=0x0603bf98)  Line 110 C
>   heapripper.exe!main()  Line 11 + 0x9 bytes  C++
    heapripper.exe!__tmainCRTStartup()  Line 266 + 0x12 bytes   C
    kernel32.dll!@BaseThreadInitThunk@12()  + 0xe bytes 
    ntdll.dll!___RtlUserThreadStart@8()  + 0x27 bytes   
    ntdll.dll!__RtlUserThreadStart@8()  + 0x1b bytes    

Pageheapは厳密なヒープ整合性チェックを有効にしますが、チェックは他のヒープ API が呼び出されるまで開始されません。チェック ルーチンはスタックに表示されます。( Pageheapがなければ、アプリケーションはおそらく無効なポインターを使用しようとするヒープ実装の AV になります。)

そのため、Pageheapは、破損が発生した瞬間に正確に破損をキャッチすることを 100% 保証するものではありません。すべてのメモリ アクセスを追跡するPurifyValgrindなどのツールが必要です。

誤解しないでほしいのですが、 Pageheapは今でも非常に便利だと思います。前述のPurifyValgrindと比較してパフォーマンスの低下がはるかに少ないため、より複雑なシナリオを実行できます。

于 2013-09-07T23:33:29.277 に答える