Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Wanneer u fouten opspoort in een programma dat gebruikmaakt van de C-runtimebibliotheek, kunnen deze foutopsporingstechnieken nuttig zijn.
Gebruik van CRT-foutopsporingsbibliotheek
De C Runtime-bibliotheek (CRT) biedt uitgebreide ondersteuning voor foutopsporing. Als u een van de CRT-foutopsporingsbibliotheken wilt gebruiken, moet u een koppeling maken met /DEBUG en compileren met /MDd, /MTdof /LDd.
De belangrijkste definities en macro's voor CRT-foutopsporing vindt u in het <crtdbg.h> headerbestand.
De functies in de CRT-foutopsporingsbibliotheken worden gecompileerd met foutopsporingsgegevens (/Z7, /Zd, /Zi, /ZI (Debug Information Format)) en zonder optimalisatie. Sommige functies bevatten asserties om te controleren of parameters worden doorgegeven en broncode wordt opgegeven. Met deze broncode kunt u in CRT-functies stappen om te bevestigen dat de functies werken zoals verwacht en controleren op slechte parameters of geheugenstatussen. (Sommige CRT-technologie is eigendom en biedt geen broncode voor het verwerken van uitzonderingen, drijvende komma en een paar andere routines.)
Zie C Run-Time Bibliotheken voor meer informatie over de verschillende runtimebibliotheken die u kunt gebruiken.
Macro's voor rapportage
Voor foutopsporing kunt u de _RPTn en _RPTFn macro's, gedefinieerd in <crtdbg.h>, gebruiken om het gebruik van printf instructies te vervangen. U hoeft ze niet in #ifdef instructies te zetten, omdat ze automatisch verdwijnen in uw release-build wanneer _DEBUG deze niet zijn gedefinieerd.
| Macroniveau | Beschrijving | 
|---|---|
              _RPT0
              _RPT1, _RPT2, _RPT3_RPT4 | 
Hiermee wordt een berichttekenreeks en nul tot vier argumenten uitgevoerd. 
              _RPT1De _RPT4 tekenreeks van het bericht fungeert als een tekenreeks voor afdrukstijl voor de argumenten. | 
              _RPTF0
              _RPTF1, _RPTF2, _RPTF3_RPTF4 | 
Hetzelfde als _RPTn, maar deze macro's voeren ook de bestandsnaam en het regelnummer uit waar de macro zich bevindt. | 
Bekijk het volgende voorbeeld:
#ifdef _DEBUG
    if ( someVar > MAX_SOMEVAR )
        printf( "OVERFLOW! In NameOfThisFunc( ),
               someVar=%d, otherVar=%d.\n",
               someVar, otherVar );
#endif
Met deze code worden de waarden van someVar en otherVar naar stdoutuitgevoerd. U kunt de volgende aanroep gebruiken om dezelfde waarden te _RPTF2 rapporteren en daarnaast de bestandsnaam en het regelnummer:
if (someVar > MAX_SOMEVAR) _RPTF2(_CRT_WARN, "In NameOfThisFunc( ), someVar= %d, otherVar= %d\n", someVar, otherVar );
Voor sommige toepassingen is mogelijk foutopsporing vereist die de macro's die zijn geleverd bij de C-runtimebibliotheek, niet bieden. In deze gevallen kunt u een macro schrijven die speciaal is ontworpen om aan uw eigen vereisten te voldoen. In een van uw koptekstbestanden kunt u bijvoorbeeld code als het volgende opnemen om een macro met de naam ALERT_IF2te definiëren:
#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
Eén aanroep om alle functies van de ALERT_IF2 code uit te printf voeren:
ALERT_IF2(someVar > MAX_SOMEVAR, "OVERFLOW! In NameOfThisFunc( ),
someVar=%d, otherVar=%d.\n", someVar, otherVar );
U kunt een aangepaste macro eenvoudig wijzigen om meer of minder informatie naar verschillende bestemmingen te rapporteren. Deze benadering is handig naarmate uw foutopsporingsvereisten zich ontwikkelen.
Foutopsporing van hook-functie schrijven
U kunt verschillende soorten aangepaste foutopsporingshookfuncties schrijven waarmee u uw code kunt invoegen in een aantal vooraf gedefinieerde punten in de normale verwerking van het foutopsporingsprogramma.
Clientblokhookfuncties
Als u de inhoud van de gegevens die zijn opgeslagen in _CLIENT_BLOCK blokken wilt valideren of rapporteren, kunt u een functie schrijven die specifiek voor dit doel is bedoeld. De functie die u schrijft, moet een prototype hebben dat lijkt op het volgende, zoals gedefinieerd in <crtdbg.h>:
void YourClientDump(void *, size_t)
Met andere woorden, uw haakfunctie moet een void aanwijzer accepteren aan het begin van het toewijzingsblok, samen met een size_t typewaarde die de grootte van de toewijzing aangeeft en retourneert void. Anders is de inhoud aan u.
Zodra u de hook-functie hebt geïnstalleerd met behulp van _CrtSetDumpClient, wordt deze aangeroepen telkens wanneer een _CLIENT_BLOCK blok wordt gedumpt. Vervolgens kunt u _CrtReportBlockType gebruiken om informatie op te halen over het type of subtype van gedumpte blokken.
De aanwijzer naar uw functie waarnaar u doorgeeft _CrtSetDumpClient , is van het type _CRT_DUMP_CLIENT, zoals gedefinieerd in <crtdbg.h>:
typedef void (__cdecl *_CRT_DUMP_CLIENT)
   (void *, size_t);
Toewijzinghookfuncties
Een toewijzingshookfunctie, geïnstalleerd met behulp van _CrtSetAllocHook, wordt aangeroepen telkens wanneer geheugen wordt toegewezen, opnieuw toegewezen of vrijgemaakt. U kunt dit type haak gebruiken voor veel verschillende doeleinden. Gebruik deze functie om te testen hoe een toepassing onvoldoende geheugensituaties verwerkt, zoals het onderzoeken van toewijzingspatronen of logboektoewijzingsgegevens voor latere analyse.
Opmerking
Houd rekening met de beperking voor het gebruik van C Runtime-bibliotheekfuncties in een toewijzingshookfunctie, beschreven in Toewijzingshaken en crt-geheugentoewijzingen.
Een toewijzingshookfunctie moet een prototype hebben zoals in het volgende voorbeeld:
int YourAllocHook(int nAllocType, void *pvData,
        size_t nSize, int nBlockUse, long lRequest,
        const unsigned char * szFileName, int nLine )
De aanwijzer waarnaar u doorgeeft _CrtSetAllocHook , is van het type _CRT_ALLOC_HOOK, zoals gedefinieerd in <crtdbg.h>:
typedef int (__cdecl * _CRT_ALLOC_HOOK)
    (int, void *, size_t, int, long, const unsigned char *, int);
Wanneer de runtimebibliotheek uw hook aanroept, geeft het nAllocType argument aan welke toewijzingsbewerking moet worden uitgevoerd (_HOOK_ALLOC, _HOOK_REALLOCof)._HOOK_FREE In een gratis of in een herlocatie heeft pvData u een aanwijzer naar het gebruikersartikel van het blok dat binnenkort wordt vrijgemaakt. Voor een toewijzing is deze aanwijzer echter null, omdat de toewijzing niet is opgetreden. De resterende argumenten bevatten de grootte van de toewijzing, het bloktype, een opeenvolgend aanvraagnummer en een aanwijzer naar de bestandsnaam. Indien beschikbaar, bevatten de argumenten ook het regelnummer waarin de toewijzing is gemaakt. Nadat de hook-functie elke analyse heeft uitgevoerd en andere taken die de auteur wil uitvoeren, moet deze een van beide retourneren TRUE, waarmee wordt aangegeven dat de toewijzingsbewerking kan worden voortgezet of FALSE, waarmee wordt aangegeven dat de bewerking moet mislukken. Een eenvoudige hook van dit type kan de hoeveelheid toegewezen geheugen tot nu toe controleren en retourneren FALSE als die hoeveelheid een kleine limiet heeft overschreden. De toepassing ondervindt dan het soort toewijzingsfouten dat normaal gesproken alleen optreedt wanneer het beschikbare geheugen laag was. Complexere hooks kunnen toewijzingspatronen bijhouden, geheugengebruik analyseren of rapporteren wanneer er specifieke situaties optreden.
Toewijzingshaken en CRT-geheugentoewijzingen
Een belangrijke beperking voor toewijzingshookfuncties is dat ze blokken expliciet moeten negeren _CRT_BLOCK . Deze blokken zijn de geheugentoewijzingen die intern zijn gemaakt door C-runtimebibliotheekfuncties als ze C-runtimebibliotheekfuncties aanroepen die intern geheugen toewijzen. U kunt blokken negeren _CRT_BLOCK door de volgende code toe te voegen aan het begin van de toewijzingshookfunctie:
if ( nBlockUse == _CRT_BLOCK )
    return( TRUE );
Als uw toewijzingshook geen blokken negeert _CRT_BLOCK , kan een C-runtimebibliotheekfunctie die in uw hook wordt aangeroepen, het programma in een eindeloze lus onderschekken. Maakt bijvoorbeeld printf een interne toewijzing. Als uw hookcode aanroept printf, wordt de resulterende toewijzing ervoor zorgen dat uw hook opnieuw wordt aangeroepen, waardoor deze opnieuw wordt aangeroepen printf , enzovoort, totdat de stack overloopt. Als u toewijzingsbewerkingen moet rapporteren _CRT_BLOCK , kunt u deze beperking omzeilen door Windows API-functies te gebruiken in plaats van C-runtimefuncties voor opmaak en uitvoer. Omdat de Windows-API's de heap van de C-runtimebibliotheek niet gebruiken, worden uw toewijzingshook niet in een eindeloze lus getrapt.
Als u de bronbestanden van de runtimebibliotheek bekijkt, ziet u dat de standaardtoewijzingshookfunctie ( _CrtDefaultAllocHook die simpelweg wordt geretourneerdTRUE), zich in een afzonderlijk bestand bevindt. debug_heap_hook.cpp Als u wilt dat uw toewijzingshook wordt aangeroepen, zelfs voor de toewijzingen die zijn gemaakt door de runtime-opstartcode die wordt uitgevoerd voordat de functie van main uw toepassing wordt uitgevoerd, kunt u deze standaardfunctie vervangen door een van uw eigen, in plaats van te gebruiken _CrtSetAllocHook.
Rapporthookfuncties
Een rapporthookfunctie, geïnstalleerd met behulp van _CrtSetReportHook, wordt elke keer aangeroepen wanneer _CrtDbgReport een foutopsporingsrapport wordt gegenereerd. U kunt deze functie onder andere gebruiken om rapporten te filteren op specifieke typen toewijzingen. Een rapporthookfunctie moet een prototype hebben zoals in dit voorbeeld:
int AppReportHook(int nRptType, char *szMsg, int *retVal);
De aanwijzer waarnaar u doorgeeft _CrtSetReportHook , is van het type _CRT_REPORT_HOOK, zoals gedefinieerd in <crtdbg.h>:
typedef int (__cdecl *_CRT_REPORT_HOOK)(int, char *, int *);
Wanneer de runtimebibliotheek uw hook-functie aanroept, bevat het nRptType argument de categorie van het rapport (_CRT_WARN, _CRT_ERRORof _CRT_ASSERT), szMsg een aanwijzer naar een volledig samengestelde rapportberichttekenreeks en retVal geeft u aan of _CrtDbgReport de normale uitvoering moet worden voortgezet nadat het rapport is gegenereerd of het foutopsporingsprogramma moet worden gestart. (Een retVal waarde van nul blijft uitvoeren, een waarde van 1 start het foutopsporingsprogramma.)
Als de haak het betreffende bericht volledig afhandelt, zodat er geen verdere rapportage vereist is, moet het bericht worden geretourneerd TRUE. Als het bericht wordt geretourneerd FALSE, _CrtDbgReport wordt het bericht normaal weergegeven.
In deze sectie
Fouten opsporen in versies van heap-toewijzingsfuncties
Beschrijft de speciale foutopsporingsversies van de heap-toewijzingsfuncties, waaronder: hoe de CRT aanroepen toedeelt, de voordelen van het expliciet aanroepen ervan, het voorkomen van conversie, het bijhouden van de afzonderlijke typen toewijzingen in clientblokken en de resultaten van het niet definiëren
_DEBUG.- 
Beschrijft geheugenbeheer en de heap voor foutopsporing, de typen blokken voor de foutopsporings-heap, heap-statusrapportagefuncties en het gebruik van de heap voor foutopsporing om toewijzingsaanvragen bij te houden.
 Geheugenlekken zoeken met behulp van de CRT-bibliotheek
Behandelt technieken voor het detecteren en isoleren van geheugenlekken met behulp van het foutopsporingsprogramma en de C Run-Time Library.