Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
När du felsöker ett program som använder C-körningsbiblioteket kan dessa felsökningstekniker vara användbara.
CRT-felsökningsbiblioteksanvändning
CRT-biblioteket (C Runtime) ger omfattande felsökningsstöd. Om du vill använda något av CRT-felsökningsbiblioteken måste du länka till /DEBUG och kompilera med /MDd, /MTdeller /LDd.
Huvuddefinitionerna och makrona för CRT-felsökning finns i <crtdbg.h> huvudfilen.
Funktionerna i CRT-felsökningsbiblioteken kompileras med felsökningsinformation (/Z7, /Zd, /Zi, /ZI (felsökningsinformationsformat)) och utan optimering. Vissa funktioner innehåller kontroller för att verifiera parametrar som skickas till dem och källkod tillhandahålls. Med den här källkoden kan du gå in i CRT-funktioner för att bekräfta att funktionerna fungerar som förväntat och söka efter felaktiga parametrar eller minnestillstånd. (Vissa CRT-tekniker är patentskyddade och tillhandahåller inte källkod för undantagshantering, flyttal och några andra rutiner.)
Mer information om de olika körningsbibliotek som du kan använda finns i C Run-Time-bibliotek.
Makron för rapportering
För felsökning kan du använda makrona _RPTn och _RPTFn , som definieras i <crtdbg.h>, för att ersätta användningen av printf -instruktioner. Du behöver inte omsluta dem i #ifdef direktiv eftersom de automatiskt försvinner i versionsversionen när _DEBUG de inte har definierats.
| Makro | Beskrivning |
|---|---|
_RPT0, _RPT1, _RPT2, , , _RPT3_RPT4 |
Matar ut en meddelandesträng och noll till fyra argument. Till _RPT1 och med _RPT4fungerar meddelandesträngen som en formateringssträng i utskriftsformat för argumenten. |
_RPTF0, _RPTF1, _RPTF2, , , _RPTF3_RPTF4 |
Samma som _RPTn, men dessa makron matar också ut filnamnet och radnumret där makrot finns. |
Tänk på följande exempel:
#ifdef _DEBUG
if ( someVar > MAX_SOMEVAR )
printf( "OVERFLOW! In NameOfThisFunc( ),
someVar=%d, otherVar=%d.\n",
someVar, otherVar );
#endif
Den här koden matar ut värdena someVar för och otherVar till stdout. Du kan använda följande anrop för att _RPTF2 rapportera samma värden och dessutom filnamnet och radnumret:
if (someVar > MAX_SOMEVAR) _RPTF2(_CRT_WARN, "In NameOfThisFunc( ), someVar= %d, otherVar= %d\n", someVar, otherVar );
Vissa program kan behöva felsöka rapporter som makrona som medföljer C-körningsbiblioteket inte tillhandahåller. I dessa fall kan du skriva ett makro som utformats specifikt för att passa dina egna krav. I en av huvudfilerna kan du till exempel inkludera kod som följande för att definiera ett makro med namnet ALERT_IF2:
#ifndef _DEBUG /* For RELEASE builds */
#define ALERT_IF2(expr, msg, arg1, arg2) do {} while (0)
#else /* For DEBUG builds */
#define ALERT_IF2(expr, msg, arg1, arg2) \
do { \
if ((expr) && \
(1 == _CrtDbgReport(_CRT_ERROR, \
__FILE__, __LINE__, msg, arg1, arg2))) \
_CrtDbgBreak( ); \
} while (0)
#endif
Ett anrop till ALERT_IF2 kan göra alla funktioner i printf koden:
ALERT_IF2(someVar > MAX_SOMEVAR, "OVERFLOW! In NameOfThisFunc( ),
someVar=%d, otherVar=%d.\n", someVar, otherVar );
Du kan enkelt ändra ett anpassat makro för att rapportera mer eller mindre information till olika mål. Den här metoden är användbar när dina felsökningskrav utvecklas.
Felsöka hook-funktionsskrivning
Du kan skriva flera typer av anpassade felsökningskrokfunktioner som gör att du kan infoga koden i vissa fördefinierade punkter i felsökarens normala bearbetning.
Funktioner för klientblockskrok
Om du vill verifiera eller rapportera innehållet i de data som lagras i _CLIENT_BLOCK block kan du skriva en funktion specifikt för detta ändamål. Funktionen som du skriver måste ha en prototyp som liknar följande, enligt definitionen i <crtdbg.h>:
void YourClientDump(void *, size_t)
Med andra ord bör din hook-funktion acceptera en void pekare till början av allokeringsblocket, tillsammans med ett size_t typvärde som anger storleken på allokeringen och returnera void. Annars är innehållet upp till dig.
När du har installerat din hook-funktion med hjälp av _CrtSetDumpClient anropas den varje gång ett _CLIENT_BLOCK block dumpas. Du kan sedan använda _CrtReportBlockType för att få information om typen eller undertypen av dumpade block.
Pekaren till din funktion som du skickar till _CrtSetDumpClient är av typen _CRT_DUMP_CLIENT, enligt definitionen i <crtdbg.h>:
typedef void (__cdecl *_CRT_DUMP_CLIENT)
(void *, size_t);
Funktioner för allokeringskrok
En allokeringskrokfunktion som installeras med , _CrtSetAllocHookanropas varje gång minnet allokeras, omallokeras eller frigörs. Du kan använda den här typen av krok för många olika syften. Använd den för att testa hur ett program hanterar otillräckliga minnessituationer, till exempel för att undersöka allokeringsmönster eller loggallokeringsinformation för senare analys.
Anmärkning
Tänk på begränsningen om att använda C-körningsbiblioteksfunktioner i en allokeringskrokfunktion, som beskrivs i Allokeringskrokar och crt-minnesallokeringar.
En allokeringskrokfunktion bör ha en prototyp som i följande exempel:
int YourAllocHook(int nAllocType, void *pvData,
size_t nSize, int nBlockUse, long lRequest,
const unsigned char * szFileName, int nLine )
Pekaren som du skickar till _CrtSetAllocHook är av typen _CRT_ALLOC_HOOK, enligt definitionen i <crtdbg.h>:
typedef int (__cdecl * _CRT_ALLOC_HOOK)
(int, void *, size_t, int, long, const unsigned char *, int);
När körningsbiblioteket anropar din krok nAllocType anger argumentet vilken allokeringsåtgärd som ska utföras (_HOOK_ALLOC, _HOOK_REALLOCeller _HOOK_FREE). I en kostnadsfri eller i en omfördelning pvData har du en pekare till användarartikeln i blocket som är på väg att friges. Men för en allokering är den här pekaren null eftersom allokeringen inte har inträffat. De återstående argumenten innehåller storleken på allokeringen, dess blocktyp, ett sekventiellt begärandenummer och en pekare till filnamnet. Om det är tillgängligt innehåller argumenten även det radnummer där allokeringen gjordes. När hook-funktionen utför den analys och andra uppgifter som författaren vill ha, måste den antingen returnera TRUE, vilket anger att allokeringsåtgärden kan fortsätta eller FALSE, vilket indikerar att åtgärden ska misslyckas. En enkel krok av den här typen kan kontrollera mängden minne som har allokerats hittills och returnera FALSE om den mängden överskred en liten gräns. Programmet skulle då uppleva den typ av allokeringsfel som normalt bara skulle inträffa när det tillgängliga minnet var lågt. Mer komplexa krokar kan hålla reda på allokeringsmönster, analysera minnesanvändning eller rapportera när specifika situationer inträffar.
Allokeringskrokar och CRT-minnesallokeringar
En viktig begränsning för allokeringskrokfunktioner är att de uttryckligen måste ignorera _CRT_BLOCK block. Dessa block är minnesallokeringar som görs internt av C-körningsbiblioteksfunktioner om de gör några anrop till C-körningsbiblioteksfunktioner som allokerar internt minne. Du kan ignorera _CRT_BLOCK block genom att inkludera följande kod i början av allokeringskrokens funktion:
if ( nBlockUse == _CRT_BLOCK )
return( TRUE );
Om allokeringskroken inte ignorerar _CRT_BLOCK block kan alla C-körningsbiblioteksfunktioner som anropas i din krok fånga programmet i en oändlig loop. Gör printf till exempel en intern allokering. Om din krokkod anropar printfkommer den resulterande allokeringen att göra att kroken anropas igen, vilket anropar printf igen och så vidare tills stacken flödar över. Om du behöver rapportera _CRT_BLOCK allokeringsåtgärder är ett sätt att kringgå den här begränsningen att använda Windows API-funktioner i stället för C-körningsfunktioner för formatering och utdata. Eftersom Windows-API:erna inte använder C-körningsbibliotekets heap, kommer de inte att fånga allokeringskroken i en oändlig loop.
Om du undersöker källfilerna för körningsbiblioteket ser du att standardfunktionen för allokeringskroken ( _CrtDefaultAllocHook som helt enkelt returnerar TRUE) finns i en egen separat fil, debug_heap_hook.cpp. Om du vill att allokeringskroken ska anropas även för allokeringarna som görs av körningsstartkoden som körs före programmets main funktion kan du ersätta den här standardfunktionen med en egen, i stället för att använda _CrtSetAllocHook.
Rapportkrokfunktioner
En rapportkrokfunktion som installeras med , _CrtSetReportHookanropas varje gång _CrtDbgReport genererar en felsökningsrapport. Du kan bland annat använda den för att filtrera rapporter för att fokusera på specifika typer av allokeringar. En rapportkrokfunktion bör ha en prototyp som det här exemplet:
int AppReportHook(int nRptType, char *szMsg, int *retVal);
Pekaren som du skickar till _CrtSetReportHook är av typen _CRT_REPORT_HOOK, enligt definitionen i <crtdbg.h>:
typedef int (__cdecl *_CRT_REPORT_HOOK)(int, char *, int *);
När körningsbiblioteket anropar din hook-funktion nRptType innehåller argumentet kategorin för rapporten (_CRT_WARN, _CRT_ERROR, eller _CRT_ASSERT), szMsg innehåller en pekare till en fullständigt monterad rapportmeddelandesträng och retVal anger om _CrtDbgReport ska fortsätta normal körning efter att rapporten har genererats eller startat felsökningsprogrammet. (Värdet retVal noll fortsätter att köras, ett värde på 1 startar felsökningsprogrammet.)
Om kroken hanterar meddelandet i fråga helt, så att ingen ytterligare rapportering krävs, bör den returnera TRUE. Om den returnerar FALSE_CrtDbgReport rapporterar den meddelandet normalt.
I det här avsnittet
Felsöka versioner av heap-allokeringsfunktioner
Diskuterar de särskilda felsökningsversionerna av heapallokeringsfunktionerna, bland annat hur CRT mappar anrop, fördelarna med att anropa dem explicit, hur du undviker konvertering, spårar separata typer av allokeringar i klientblock och resultatet av att
_DEBUGinte definiera .Information om CRT-felsöknings-heap
Beskriver minneshantering och felsöknings heap, typer av block på felsöknings-heapen, rapporteringsfunktioner för heaptillstånd och hur du använder felsöknings-heapen för att spåra allokeringsbegäranden.
Hitta minnesläckor med hjälp av CRT-biblioteket
Omfattar tekniker för att identifiera och isolera minnesläckor med hjälp av felsökningsprogrammet och C Run-Time-biblioteket.