Använd verktyget PageHeap för att identifiera minnesfel i ett Visual C++-projekt

I den här artikeln beskrivs hur du använder verktyget PageHeap för att identifiera minnesfel i Microsoft Visual C++-projekt. Informationen i den här artikeln gäller endast ohanterad Visual C++-kod.

Ursprunglig produktversion: Visual C++
Ursprungligt KB-nummer: 264471

Sammanfattning

PageHeap-verktyget kan aktiveras för program så att alla malloc, newoch heapAlloc allokeringar övervakas automatiskt för minnesfel.

PageHeap1 är ett Visual C++-projekt med flera typer av minnesfel. Om du vill aktivera PageHeap i det här exempelprogrammet skriver du in följande innehåll från kommandoraden:

pageheap /enable pgh.exe 0x01

Skriv sedan in följande innehåll:

pageheap

Anmärkning

Programnamnet som PageHeap övervakar.

För många program 0x01 är den enda flagga du behöver. Du kan få mer information om dess användning genom att köra PageHeap med frågeteckenflaggan (/?) från kommandoraden.

Så här fungerar PageHeap

PageHeap returnerar en pekare till allokerat minne på 8 bytes gränser. Slutet på den returnerade pekaren följs av 0 till 7 vaktbyte (beroende på den begärda storleken läggs 0 byte till 7 byte till för att avrunda upp begärandestorleken så att den ligger på en gräns på 8 byte), följt av en minnessida markerad PAGE_NOACCESS (mer information finns i VirtualAlloc). Som exempel:

char * p;
p = new char[5];

PageHeap returnerar en pekare till 5 byte plus tre vaktbyte för att utgöra totalt 8 byte, till exempel..... XXX. Om minnesallokeringsstorleken är en multipel av åtta läggs inga skyddsbytes till i den returnerade pekaren.

Om slutet av allokeringen skrivs över ändras skyddsbytena, och PageHeap orsakar ett Åtkomstöverträdelse-fel när minnet frigörs. Om programmet läser eller skriver förbi allokeringen (inklusive skyddsbytes) uppstår ett omedelbart åtkomstfel.

Så här använder du PageHeap1-exempel

  1. Skapa pgh-projektet och kör pgh.exe.

    Anmärkning

    Du måste göra en versionsversion för att PageHeap ska fungera med new eller malloc.

    Starta PageHeap1.exe. Det finns en dialogruta.

  2. I dialogrutan kan du se en textruta, en Bad Alloc/Free-kryssruta och tre par knappar, ny & ta bort, PageAlloc & Heap Free och COM ny & COM borttagning. Textrutan tar in storleken på det minne som du vill ha allokerat. Om kryssrutan Felaktig Allokering/Frisläpp är markerad, allokerar varje allokeringstyp (new, PageAlloc och COM new) minne och skriver sedan bortom den allokerade minnesgränsen. Om Bad Alloc inte är markerat, sker ingen minnesöverskrivning.

    Knappen ny testar operatorn new, knappen PageAlloc testar HeapAlloc. COM new använder CoTaskMemAlloc inte utan anropar i stället ett COM Dynamic-link-bibliotek (DLL) som helt enkelt anropar new. Om du vill testa COM new måste du antingen registrera r1LeakMemMod.dll eller skapa projektet r1LeakMemMod.

    Du kan använda ett DLL-bibliotek för körtid så att PageHeap ska fungera. (Från Visual C++ Integrated Development Environment (IDE), Projects>Inställningar>C++>Kategori: Kodgenerering>Använd körningsbiblioteket).

  3. När du har markerat kryssrutan Bad Alloc/Free, om minnesallokeringsstorleken är 5 byte, välj den nya knappen; då allokeras 5 byte minne och 0 skrivs till den sjätte byn. Att skriva till den sjätte byten är en oavsiktlig minnesöverskrivning, men det sker på en guard byte, så PageHeap identifierar inte det här felet förrän minnet har tagits bort. När du väljer knappen Ta bort identifierar PageHeap överskrivningen och du ser en felmeddelanderuta som liknar följande exempel:

    Ett undantag: Brytpunkt. En brytpunkt har nåtts. (0x80000003) inträffade i programmet på adress 0x77f9f9df.

    Om du har angett Visual C++ som just-in-time (JIT) felsökningsprogram kan du välja knappen Avbryt och felsöka i koden.

    Om du ändrar allokeringsstorleken till 8 (eller någon multipel av 8) resulterar val av nya knappar, pageAlloc eller COM Nya knappar i ett omedelbart åtkomstfel eftersom du har skrivit till en adress utan åtkomst. (det är att du inte behöver ta bort minnet för att identifiera felet).

Anmärkning

  1. Begränsningar: PageHeap kan bara hitta minnesfel från malloc familjen (därav C++-operatorn new) och heapAlloc. Många program använder anpassade allokerare och PageHeap kan inte fånga upp dessa allokeringar.
  2. När du har testat ett program, kör pageheap /disable <appName> från kommandoraden för att inaktivera PageHeap för programmet.
  3. PageHeap-aktiverade program kan förbruka mycket mer minne än samma program utan att PageHeap är aktiverat. Du kan behöva öka växlingsfilen för att tillgodose det ökade minnesbehovet.

Du kan ladda ned Pageheap1vcnet.exe här. Mer information om hur du laddar ned Microsofts supportfiler finns i Hämta Microsofts supportfiler från onlinetjänster.

Microsoft genomsökt den här filen efter virus. Microsoft använde den senaste virusidentifieringsprogramvaran som var tillgänglig samma dag som filen publicerades. Filen lagras på säkerhetsförbättrade servrar som hjälper till att förhindra obehöriga ändringar i filen.