Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A C futásidejű kódtárat használó programok hibakeresésekor ezek a hibakeresési technikák hasznosak lehetnek.
CRT hibakeresési kódtár használata
A C futtatókörnyezeti (CRT) kódtár széles körű hibakeresési támogatást nyújt. A CRT hibakeresési kódtárak egyikének használatához csatolnia /DEBUG kell, és össze kell állítania az /MDd, /MTdvagy /LDd.
A CRT-hibakeresés fő definíciói és makrói a <crtdbg.h> fejlécfájlban találhatók.
A CRT hibakeresési kódtárak funkciói hibakeresési adatokkal (/Z7, /Zd, /Zi, /ZI (Hibakeresési információformátum)) vannak lefordítva, optimalizálás nélkül. Egyes függvények állításokat tartalmaznak a nekik átadott paraméterek ellenőrzéséhez, és a forráskód meg van adva. Ezzel a forráskóddal a CRT-függvényekbe lépve ellenőrizheti, hogy a függvények a várt módon működnek-e, és ellenőrizze, hogy nincsenek-e rossz paraméterek vagy memóriaállapotok. (Egyes CRT-technológia védett, és nem biztosít forráskódot a kivételkezeléshez, a lebegőpontos és néhány egyéb rutinhoz.)
A különböző futásidejű kódtárakról további információt a C Run-Time-kódtárak című témakörben talál.
Makrók jelentéskészítéshez
A hibakereséshez használhatja a _RPTn benne _RPTFndefiniált makrókat és <crtdbg.h> makrókat az utasítások használatáraprintf. Nem kell azokat irányelvekbe #ifdef ágyaznia, mert azok automatikusan eltűnnek a kiadási buildben, ha _DEBUG nincs definiálva.
| Makró | Leírás |
|---|---|
_RPT0, _RPT1, _RPT2, _RPT3_RPT4 |
Egy üzenetsztringet és 0–4 argumentumot ad ki.
_RPT1Az _RPT4 üzenetsztring végig az argumentumok printf stílusú formázási sztringjeként szolgál. |
_RPTF0, _RPTF1, _RPTF2, _RPTF3_RPTF4 |
Ugyanaz, mint _RPTn, de ezek a makrók a fájlnevet és a sorszámot is kimenetként használják, ahol a makró található. |
Vegye figyelembe a következő példát:
#ifdef _DEBUG
if ( someVar > MAX_SOMEVAR )
printf( "OVERFLOW! In NameOfThisFunc( ),
someVar=%d, otherVar=%d.\n",
someVar, otherVar );
#endif
Ez a kód a következő értékeket someVarotherVarstdoutadja ki: A következő hívással _RPTF2 ugyanezeket az értékeket, valamint a fájlnevet és a sorszámot is jelentheti:
if (someVar > MAX_SOMEVAR) _RPTF2(_CRT_WARN, "In NameOfThisFunc( ), someVar= %d, otherVar= %d\n", someVar, otherVar );
Előfordulhat, hogy egyes alkalmazások hibakeresési jelentést igényelnek, amelyeket a C futásidejű tárhoz megadott makrók nem biztosítanak. Ezekben az esetekben olyan makrót írhat, amely kifejezetten a saját igényeinek megfelelően lett kialakítva. Az egyik fejlécfájlban például az alábbihoz hasonló kóddal definiálhat egy úgynevezett ALERT_IF2makrót:
#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
Egy hívással ALERT_IF2 elvégezheti a kód összes függvényét printf :
ALERT_IF2(someVar > MAX_SOMEVAR, "OVERFLOW! In NameOfThisFunc( ),
someVar=%d, otherVar=%d.\n", someVar, otherVar );
Az egyéni makrókat egyszerűen módosíthatja úgy, hogy több vagy kevesebb információt jelentsenek különböző célhelyekre. Ez a módszer a hibakeresési követelmények fejlődésével együtt hasznos.
Horogfüggvény írásának hibakeresése
Többféle egyéni hibakeresési horogfüggvényt is írhat, amelyekkel beszúrhatja a kódot a hibakereső normál feldolgozásának bizonyos előre meghatározott pontjaiba.
Ügyfélblokkok horogfüggvényei
Ha ellenőrizni vagy jelenteni szeretné a blokkokban _CLIENT_BLOCK tárolt adatok tartalmát, kifejezetten erre a célra írhat függvényt. Az ön által írt függvénynek a következőhöz hasonló prototípussal kell rendelkeznie, a következőben meghatározott módon <crtdbg.h>:
void YourClientDump(void *, size_t)
Más szóval a horogfüggvénynek el kell fogadnia a void foglalási blokk elejére mutató mutatót, valamint egy típusértéket size_t , amely a foglalás méretét jelzi, és visszaadja a függvényt void. Ellenkező esetben a tartalma Önön múlik.
Miután telepítette a horogfüggvényt _CrtSetDumpClient használatával, a rendszer minden alkalommal meghívja, amikor egy _CLIENT_BLOCK blokkot dobnak. Ezután a _CrtReportBlockType használatával információkat kaphat a dömpingelt blokkok típusáról vagy altípusáról.
A függvénynek átadott _CrtSetDumpClient mutató típusa a következőben _CRT_DUMP_CLIENTmeghatározott:<crtdbg.h>
typedef void (__cdecl *_CRT_DUMP_CLIENT)
(void *, size_t);
Kiosztási horogfüggvények
A rendszer minden alkalommal meghív egy foglalási horogfüggvényt, amelyet a rendszer _CrtSetAllocHookminden alkalommal meghív, amikor a rendszer lefoglalja, újraosztja vagy felszabadítja a memóriát. Ezt a típusú horogot számos különböző célra használhatja. Segítségével tesztelheti, hogy egy alkalmazás hogyan kezeli az elégtelen memóriahelyzeteket, például a foglalási mintákat vagy a naplólefoglalási információkat későbbi elemzéshez.
Megjegyzés:
Vegye figyelembe a C futtatókörnyezeti kódtárfüggvények foglalási horogfüggvényekben való használatára vonatkozó korlátozást, amelyet a Kiosztási horgok és a crt memóriafoglalások című cikkben ismertetünk.
A foglalási horogfüggvénynek az alábbi példához hasonló prototípussal kell rendelkeznie:
int YourAllocHook(int nAllocType, void *pvData,
size_t nSize, int nBlockUse, long lRequest,
const unsigned char * szFileName, int nLine )
Az átadott _CrtSetAllocHook mutató típusa a következőben _CRT_ALLOC_HOOKmeghatározott:<crtdbg.h>
typedef int (__cdecl * _CRT_ALLOC_HOOK)
(int, void *, size_t, int, long, const unsigned char *, int);
Amikor a futásidejű kódtár meghívja a horgot, az nAllocType argumentum jelzi, hogy milyen foglalási műveletet kell végrehajtani (_HOOK_ALLOC_HOOK_REALLOCvagy_HOOK_FREE). Szabad vagy átcsoportosítás pvData esetén a felszabadítani kívánt blokk felhasználói cikkére mutató mutató található. Foglalás esetén azonban ez a mutató null értékű, mert a foglalás nem történt meg. A fennmaradó argumentumok tartalmazzák a foglalás méretét, blokktípusát, szekvenciális kérelemszámát és a fájlnévre mutató mutatót. Ha elérhető, az argumentumok tartalmazzák azt a sorszámot is, amelyben a foglalás történt. Miután a horogfüggvény bármilyen elemzést és más feladatot végrehajt, amelyet a szerző kíván, vagy azt kell visszaadnia TRUE, hogy a foglalási művelet folytatódhat, vagy FALSEazt jelzi, hogy a műveletnek sikertelennek kell lennie. Egy ilyen típusú egyszerű horog ellenőrizheti az eddig lefoglalt memória mennyiségét, és visszaadhatja FALSE , ha ez az összeg túllépett egy kis korlátot. Az alkalmazás ekkor olyan foglalási hibákat tapasztal, amelyek általában csak akkor fordulnak elő, ha a rendelkezésre álló memória alacsony. Az összetettebb horgok nyomon követhetik a foglalási mintákat, elemezhetik a memóriahasználatot, vagy jelentést kaphatnak adott helyzetekben.
Foglalási horgok és CRT-memóriafoglalások
A kiosztási horogfüggvények fontos korlátozása, hogy explicit módon figyelmen kívül kell hagyniuk _CRT_BLOCK a blokkokat. Ezek a blokkok a C futásidejű könyvtárfüggvények által belsőleg végrehajtott memóriafoglalások, ha a belső memóriát lefoglaló C futásidejű kódtárfüggvényekre irányuló hívásokat kezdeményeznek. A blokkokat figyelmen kívül hagyhatja _CRT_BLOCK úgy, hogy az alábbi kódot a foglalási horogfüggvény elején adja meg:
if ( nBlockUse == _CRT_BLOCK )
return( TRUE );
Ha a kiosztási horog nem hagyja figyelmen kívül _CRT_BLOCK a blokkokat, akkor a horogban hívott C futásidejű kódtár-függvények végtelen hurokban képesek csapdába ejteni a programot. Például printf belső lefoglalást végez. Ha a horogkód hívások printf, akkor az eredményként kapott lefoglalás hatására a horog újra le lesz hívva, ami újra meghívja printf , és így tovább, amíg a verem túlcsordul. Ha kiosztási műveleteket kell jelentenie _CRT_BLOCK , a korlátozás megkerülésének egyik módja a Windows API-függvények használata a C futásidejű függvények helyett a formázáshoz és a kimenethez. Mivel a Windows API-k nem használják a C futásidejű kódtár halomát, nem fogják végtelen hurokba csapni a foglalási horgot.
Ha megvizsgálja a futásidejű kódtár forrásfájljait, látni fogja, _CrtDefaultAllocHook hogy az alapértelmezett foglalási horogfüggvény (amely egyszerűen visszaadjaTRUE) egy külön, saját fájlban található. debug_heap_hook.cpp Ha azt szeretné, hogy a kiosztási horog még az alkalmazás függvénye main előtt végrehajtott futásidejű indítási kód által végrehajtott foglalások esetében is le legyen hívva, ezt az alapértelmezett függvényt lecserélheti egy sajátra ahelyett, hogy használna _CrtSetAllocHook.
Jelentéshoomfüggvények
A jelentéshohorog függvényt a rendszer _CrtSetReportHookminden alkalommal meghívja, amikor _CrtDbgReport hibakeresési jelentést hoz létre. Többek között arra is használhatja, hogy a jelentések szűrésével bizonyos foglalástípusokra összpontosítson. A jelentéshook-függvénynek az alábbi példához hasonló prototípussal kell rendelkeznie:
int AppReportHook(int nRptType, char *szMsg, int *retVal);
Az átadott _CrtSetReportHook mutató típusa a következőben _CRT_REPORT_HOOKmeghatározott:<crtdbg.h>
typedef int (__cdecl *_CRT_REPORT_HOOK)(int, char *, int *);
Amikor a futásidejű kódtár meghívja a horogfüggvényt, az nRptType argumentum a jelentés kategóriáját (_CRT_WARN_CRT_ERRORvagy _CRT_ASSERT) szMsg egy teljesen összeállított jelentésüzenet-sztringre mutató mutatót tartalmaz, és retVal megadja, hogy a jelentés létrehozása vagy a hibakereső elindítása után folytatnia kell-e _CrtDbgReport a normál végrehajtást. (A retVal nulla érték folytatja a végrehajtást, az 1 érték elindítja a hibakeresőt.)
Ha a horog teljesen kezeli a szóban forgó üzenetet, így nincs szükség további jelentésre, akkor vissza kell térnie TRUE. Ha visszaérkezik FALSE, _CrtDbgReport akkor az üzenet a szokásos módon jelenik meg.
Ebben a szakaszban
A halomfoglalási függvények verzióinak hibakeresése
A halomfoglalási függvények speciális hibakeresési verzióit ismerteti, többek között a következőkről: a CRT hívásokat képez le, milyen előnyökkel jár, ha kifejezetten meghívja őket, hogyan kerülheti el az átalakítást, hogyan követheti nyomon a különböző típusú foglalásokat az ügyfélblokkokban, valamint a nem definiált
_DEBUGeredmények.CRT hibakeresési halom részletei
Ismerteti a memóriakezelést és a hibakeresési halomot, a hibakeresési halom blokkjainak típusait, a halomállapot-jelentési függvényeket, valamint a hibakeresési halom használatát a foglalási kérelmek nyomon követéséhez.
Memóriavesztések keresése a CRT-kódtár használatával
A memóriaszivárgások észlelésére és elkülönítésére szolgáló technikákat ismerteti a hibakereső és a C Run-Time könyvtár használatával.