Servizi diagnostici
La libreria Microsoft Foundation Class fornisce numerosi servizi di diagnostica che semplificano il debug dei programmi. I servizi di diagnostica includono macro e funzioni globali che consentono di tenere traccia delle allocazioni della memoria del programma, scaricare il contenuto degli oggetti in fase di esecuzione e stampare i messaggi di debug in fase di esecuzione. Le macro e funzioni globali per servizi di diagnostica sono raggruppate nelle categorie seguenti:
Macro diagnostiche generali
Funzioni e variabili di diagnostica generale
Funzioni di diagnostica oggetti
Queste macro e funzioni sono disponibili per tutte le classi derivate da CObject
nelle versioni di debug e rilascio di MFC. Tuttavia, tutti tranne DEBUG_NEW e VERIFY non eseguono alcuna operazione nella versione di rilascio.
Nella libreria debug tutti i blocchi di memoria allocati sono racchiusi tra parentesi con una serie di "byte di protezione". Se questi byte sono disturbati da una scrittura di memoria errante, le routine di diagnostica possono segnalare un problema. Se si include la riga:
#define new DEBUG_NEW
nel file di implementazione tutte le chiamate a new
archivieranno il nome file e il numero di riga in cui è stata eseguita l'allocazione di memoria. La funzione CMemoryState:: DumpAllObjectsSince visualizzerà queste informazioni aggiuntive, che consentono di identificare le perdite di memoria. Per altre informazioni sull'output di diagnostica vedere anche la classe CDumpContext .
Inoltre, la libreria di runtime C supporta anche un set di funzioni di diagnostica che è possibile usare per eseguire il debug delle applicazioni. Per altre informazioni, vedere Routine di debug in Riferimenti alla libreria di runtime.
Macro diagnostiche generali in MFC
Nome | Descrizione |
---|---|
ASSERT | Stampa un messaggio e quindi arresta il programma se l'espressione specificata restituisce FALSE nella versione di debug della libreria. |
ASSERT_KINDOF | Verifica se un oggetto è un oggetto della classe specificata o di una classe derivata dalla classe specificata. |
ASSERT_VALID | Verifica la validità interna di un oggetto chiamando la relativa funzione membro AssertValid ; in genere sottoposta a override da CObject . |
DEBUG_NEW | Fornisce un nome file e un numero di riga per tutte le allocazioni di oggetti in modalità di debug per trovare perdite di memoria. |
DEBUG_ONLY | Simile ad ASSERT ma non verifica il valore dell'espressione; utile per il codice che deve essere eseguito solo in modalità di debug. |
ENSURE e ENSURE_VALID | Usare per convalidare la correttezza dei dati. |
THIS_FILE | Espande fino al nome del file in fase di compilazione. |
TRACE | Fornisce una funzionalità simile a printf -nella versione di debug della libreria. |
VERIFY | Simile ad ASSERT ma valuta l'espressione nella versione di rilascio della libreria oltre che nella versione di debug. |
Funzioni e variabili di diagnostica generale in MFC
Nome | Descrizione |
---|---|
afxDump | Variabile globale che invia informazioni CDumpContext alla finestra di output o al terminale di debug. |
afxMemDF | Variabile globale che controlla il comportamento dell'allocatore di memoria di debug. |
AfxCheckError | Variabile globale usata per verificare l'oggetto SCODE passato per verificare se è un errore; in caso affermativo, genera l'errore appropriato. |
AfxCheckMemory | Controlla l'integrità di tutta la memoria attualmente allocata. |
AfxDebugBreak | Causa un'interruzione nell'esecuzione. |
AfxDump | Se viene chiamato quando nel debugger, esegue il dump dello stato di un oggetto durante il debug. |
AfxDump | Funzione interna che esegue il dump dello stato di un oggetto durante il debug. |
AfxDumpStack | Genera un'immagine dello stack corrente. Questa funzione è sempre collegata staticamente. |
AfxEnableMemoryLeakDump | Consente il dump della perdita di memoria. |
AfxEnableMemoryTracking | Attiva e disattiva rilevamento della memoria. |
AfxIsMemoryBlock | Verifica che un blocco di memoria sia stato allocato in modo corretto. |
AfxIsValidAddress | Verifica che un intervallo di indirizzi di memoria si trovi all'interno dei limiti del programma. |
AfxIsValidString | Determina se un puntatore a una stringa è valido. |
AfxSetAllocHook | Consente la chiamata di una funzione in ogni allocazione di memoria. |
Funzioni di diagnostica oggetti in MFC
Nome | Descrizione |
---|---|
AfxDoForAllClasses | Esegue una funzione specificata su tutte le classi derivate da CObject che supportano il controllo del tipo in fase di esecuzione. |
AfxDoForAllObjects | Esegue una funzione specificata su tutti gli CObject oggetti derivati da che sono stati allocati con new . |
Macro di compilazione MFC
Nome | Descrizione |
---|---|
_AFX_SECURE_NO_WARNINGS | Elimina gli avvisi del compilatore per l'uso di funzioni MFC deprecate. |
_AFX_SECURE_NO_WARNINGS
Elimina gli avvisi del compilatore per l'uso di funzioni MFC deprecate.
Sintassi
_AFX_SECURE_NO_WARNINGS
Esempio
Questo esempio di codice genera un avviso del compilatore se _AFX_SECURE_NO_WARNINGS
non è definito.
// define this before including any afx files in *pch.h* (*stdafx.h* in Visual Studio 2017 and earlier)
#define _AFX_SECURE_NO_WARNINGS
// . . .
CRichEditCtrl* pRichEdit = new CRichEditCtrl;
pRichEdit->Create(WS_CHILD|WS_VISIBLE|WS_BORDER|ES_MULTILINE,
CRect(10,10,100,200), pParentWnd, 1);
char sz[256];
pRichEdit->GetSelText(sz);
AfxDebugBreak
Chiamare questa funzione per causare un'interruzione (nella posizione della chiamata a AfxDebugBreak
) nell'esecuzione della versione di debug dell'applicazione MFC.
Sintassi
void AfxDebugBreak( );
Osservazioni:
AfxDebugBreak
non ha alcun effetto nelle versioni di rilascio di un'applicazione MFC e deve essere rimosso. Questa funzione deve essere usata solo nelle applicazioni MFC. Usare la versione dell'API Win32, DebugBreak
, per causare un'interruzione nelle applicazioni non MFC.
Requisiti
Intestazione: afxver_.h
ASSERT
Valuta il relativo argomento.
ASSERT(booleanExpression)
Parametri
booleanExpression
Specifica un'espressione (inclusi i valori del puntatore) che restituisce un valore diverso da zero o 0.
Osservazioni:
Se il risultato è 0, la macro stampa un messaggio di diagnostica e interrompe il programma. Se la condizione è diversa da zero, non esegue alcuna operazione.
Il messaggio di diagnostica presenta la forma seguente:
assertion failed in file <name> in line <num>
dove name è il nome del file di origine e num è il numero di riga dell'asserzione non riuscita nel file di origine.
Nella versione release di MFC ASSERT non valuta l'espressione e pertanto non interromperà il programma. Se l'espressione deve essere valutata indipendentemente dall'ambiente, usare la macro VERIFY al posto di ASSERT.
Nota
Questa funzione è disponibile solo nella versione Debug di MFC.
Esempio
CAge* pcage = new CAge(21); // CAge is derived from CObject.
ASSERT(pcage != NULL);
ASSERT(pcage->IsKindOf(RUNTIME_CLASS(CAge)));
// Terminates program only if pcage is NOT a CAge*.
Requisiti
Intestazione: afx.h
ASSERT_KINDOF
Questa macro afferma che l'oggetto a cui punta è un oggetto della classe specificata o è un oggetto di una classe derivata dalla classe specificata.
ASSERT_KINDOF(classname, pobject)
Parametri
nomeclasse
Nome di una CObject
classe derivata da .
pobject
Puntatore a un oggetto classe.
Osservazioni:
Il parametro pobject deve essere un puntatore a un oggetto e può essere const
. L'oggetto a cui punta e la classe deve supportare CObject
le informazioni sulla classe di runtime. Ad esempio, per assicurarsi che pDocument
sia un puntatore a un oggetto della CMyDoc
classe o a uno dei relativi derivati, è possibile codificare:
ASSERT_KINDOF(CMyDoc, pDocument);
L'uso della ASSERT_KINDOF
macro equivale esattamente alla codifica:
ASSERT(pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)));
Questa funzione funziona solo per le classi dichiarate con la macro [DECLARE_DYNAMIC](run-time-object-model-services.md#declare_dynamic o DECLARE_SERIAL .
Nota
Questa funzione è disponibile solo nella versione Debug di MFC.
Requisiti
Intestazione: afx.h
ASSERT_VALID
Usare per testare i presupposti sulla validità dello stato interno di un oggetto.
ASSERT_VALID(pObject)
Parametri
pObject
Specifica un oggetto di una classe derivata da CObject
che ha una versione di override della AssertValid
funzione membro.
Osservazioni:
ASSERT_VALID chiama la AssertValid
funzione membro dell'oggetto passato come argomento.
Nella versione release di MFC ASSERT_VALID non esegue alcuna operazione. Nella versione di debug convalida il puntatore, verifica la presenza di VALORI NULL e chiama le funzioni AssertValid
membro dell'oggetto. Se uno di questi test ha esito negativo, viene visualizzato un messaggio di avviso nello stesso modo di ASSERT.
Nota
Questa funzione è disponibile solo nella versione Debug di MFC.
Per altre informazioni ed esempi, vedere Debug di applicazioni MFC.
Esempio
// Assure that pMyObject is a valid pointer to an
// object derived from CObject.
ASSERT_VALID(pMyObject);
Requisiti
Intestazione: afx.h
DEBUG_NEW
Aiuta a trovare perdite di memoria.
#define new DEBUG_NEW
Osservazioni:
È possibile usare DEBUG_NEW ovunque nel programma che si userebbe normalmente l'operatore per allocare l'archiviazione dell'heap new
.
In modalità di debug (quando viene definito il simbolo di _DEBUG ), DEBUG_NEW tiene traccia del nome file e del numero di riga per ogni oggetto allocato. Quindi, quando si usa la funzione membro CMemoryState::D umpAllObjectsSince , ogni oggetto allocato con DEBUG_NEW viene visualizzato con il nome file e il numero di riga in cui è stato allocato.
Per usare DEBUG_NEW, inserire la direttiva seguente nei file di origine:
#define new DEBUG_NEW
Dopo aver inserito questa direttiva, il preprocessore inserisce DEBUG_NEW ovunque si usi new
e MFC esegue il resto. Quando si compila una versione di rilascio del programma, DEBUG_NEW si risolve in un'operazione semplice new
e le informazioni sul nome file e sul numero di riga non vengono generate.
Nota
Nelle versioni precedenti di MFC (4.1 e versioni precedenti) è necessario inserire l'istruzione #define
dopo tutte le istruzioni che hanno chiamato le macro IMPLEMENT_DYNCREATE o IMPLEMENT_SERIAL. Questa operazione non è più necessaria.
Requisiti
Intestazione: afx.h
DEBUG_ONLY
In modalità di debug (quando viene definito il simbolo di _DEBUG ), DEBUG_ONLY valuta il relativo argomento.
DEBUG_ONLY(expression)
Osservazioni:
In una build di versione, DEBUG_ONLY non valuta il relativo argomento. Ciò è utile quando si dispone di codice che deve essere eseguito solo nelle compilazioni di debug.
La macro DEBUG_ONLY equivale all'espressione circostante con #ifdef _DEBUG
e #endif
.
Esempio
void ExampleFunc(char* p, int size, char fill)
{
char* q; // working copy of pointer
VERIFY(q = p); // copy buffer pointer and validate
ASSERT(size >= 100); // make sure buffer is at least 100 bytes
ASSERT(isalpha(fill)); // make sure fill character is alphabetic
// if fill character is invalid, substitute 'X' so we can continue
// debugging after the preceding ASSERT fails.
DEBUG_ONLY(fill = (isalpha(fill)) ? fill : 'X');
}
Requisiti
Intestazione: afx.h
ENSURE e ENSURE_VALID
Usare per convalidare la correttezza dei dati.
Sintassi
ENSURE( booleanExpression )
ENSURE_VALID( booleanExpression )
Parametri
booleanExpression
Specifica un'espressione booleana da testare.
Osservazioni:
Lo scopo di queste macro è migliorare la convalida dei parametri. Le macro impediscono un'ulteriore elaborazione di parametri non corretti nel codice. A differenza delle macro ASSERT, le macro ENSURE generano un'eccezione oltre a generare un'asserzione.
Le macro si comportano in due modi, in base alla configurazione del progetto. Le macro chiamano ASSERT e quindi generano un'eccezione se l'asserzione non riesce. Pertanto, nelle configurazioni di debug (ovvero, dove è definito _DEBUG) le macro producono un'asserzione ed eccezione mentre nelle configurazioni release le macro producono solo l'eccezione (ASSERT non valuta l'espressione nelle configurazioni release).
La macro ENSURE_ARG agisce come la macro ENSURE.
ENSURE_VALID chiama la macro ASSERT_VALID (che ha un effetto solo nelle compilazioni di debug). Inoltre, ENSURE_VALID genera un'eccezione se il puntatore è NULL. Il test NULL viene eseguito sia nelle configurazioni di debug che di rilascio.
Se uno di questi test ha esito negativo, viene visualizzato un messaggio di avviso nello stesso modo di ASSERT. Se necessario, la macro genera un'eccezione di argomento non valida.
Requisiti
Intestazione: afx.h
THIS_FILE
Espande fino al nome del file in fase di compilazione.
Sintassi
THIS_FILE
Osservazioni:
Le informazioni vengono utilizzate dalle macro ASSERT e VERIFY. La Creazione guidata applicazione e le procedure guidate di codice inseriscono la macro nei file di codice sorgente creati.
Esempio
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// __FILE__ is one of the six predefined ANSI C macros that the
// compiler recognizes.
Requisiti
Intestazione: afx.h
TRACE
Invia la stringa specificata al debugger dell'applicazione corrente.
TRACE(exp)
TRACE(DWORD category, UINT level, LPCSTR lpszFormat, ...)
Osservazioni:
Per una descrizione di TRACE, vedere ATLTRACE2 . TRACE e ATLTRACE2 hanno lo stesso comportamento.
Nella versione di debug di MFC questa macro invia la stringa specificata al debugger dell'applicazione corrente. In una build di versione, questa macro viene compilata in nulla (non viene generato alcun codice).
Per altre informazioni, vedere Debug di applicazioni MFC.
Requisiti
Intestazione: afx.h
VERIFY
Nella versione debug di MFC valuta il relativo argomento.
VERIFY(booleanExpression)
Parametri
booleanExpression
Specifica un'espressione (inclusi i valori del puntatore) che restituisce un valore diverso da zero o 0.
Osservazioni:
Se il risultato è 0, la macro stampa un messaggio di diagnostica e interrompe il programma. Se la condizione è diversa da zero, non esegue alcuna operazione.
Il messaggio di diagnostica presenta la forma seguente:
assertion failed in file <name> in line <num>
dove name è il nome del file di origine e num è il numero di riga dell'asserzione non riuscita nel file di origine.
Nella versione release di MFC, VERIFY valuta l'espressione ma non stampa o interrompe il programma. Ad esempio, se l'espressione è una chiamata di funzione, verrà eseguita la chiamata.
Esempio
// VERIFY can be used for things that should never fail, though
// you may want to make sure you can provide better error recovery
// if the error can actually cause a crash in a production system.
// It _is_ possible that GetDC() may fail, but the out-of-memory
// condition that causes it isn't likely. For a test application,
// this use of VERIFY() is fine. For any production code, this
// usage is dubious.
// get the display device context
HDC hdc;
VERIFY((hdc = ::GetDC(hwnd)) != NULL);
// give the display context back
::ReleaseDC(hwnd, hdc);
Requisiti
Intestazione: afx.h
afxDump (CDumpContext in MFC)
Fornisce funzionalità di base per il dump di oggetti nell'applicazione.
CDumpContext afxDump;
Osservazioni:
afxDump
è un oggetto CDumpContext predefinito che consente di inviare CDumpContext
informazioni alla finestra di output del debugger o a un terminale di debug. In genere, si specifica afxDump
come parametro a CObject::Dump
.
In Windows NT e in tutte le versioni di Windows, afxDump
l'output viene inviato alla finestra Output-Debug di Visual C++ quando si esegue il debug dell'applicazione.
Questa variabile è definita solo nella versione Debug di MFC. Per altre informazioni su afxDump
, vedere Debug di applicazioni MFC.
Esempio
// example for afxDump
CPerson* pMyPerson = new CPerson;
// set some fields of the CPerson object...
//..
// now dump the contents
#ifdef _DEBUG
afxDump << _T("Dumping myPerson:\n");
pMyPerson->Dump(afxDump);
afxDump << _T("\n");
#endif
Requisiti
Intestazione: afx.h
AfxDump (interno)
Funzione interna usata da MFC per eseguire il dump dello stato di un oggetto durante il debug.
Sintassi
void AfxDump(const CObject* pOb);
Parametri
Pob
Puntatore a un oggetto di una classe derivata da CObject
.
Osservazioni:
AfxDump
chiama la funzione membro di Dump
un oggetto e invia le informazioni alla posizione specificata dalla afxDump
variabile. AfxDump
è disponibile solo nella versione debug di MFC.
Il codice del programma non deve chiamare AfxDump
, ma deve invece chiamare la Dump
funzione membro dell'oggetto appropriato.
Requisiti
Intestazione: afx.h
afxMemDF
Questa variabile è accessibile da un debugger o dal programma e consente di ottimizzare la diagnostica dell'allocazione.
int afxMemDF;
Osservazioni:
afxMemDF
può avere i valori seguenti, come specificato dall'enumerazione afxMemDF
:
allocMemDF
Attiva il debug dell'allocatore (impostazione predefinita nella libreria di debug).delayFreeMemDF
Ritarda la liberazione della memoria. Mentre il programma libera un blocco di memoria, l'allocatore non restituisce tale memoria al sistema operativo sottostante. In questo modo, lo stress di memoria massimo verrà posto sul programma.checkAlwaysMemDF
ChiamaAfxCheckMemory
ogni volta che la memoria viene allocata o liberata. Ciò rallenta significativamente le allocazioni di memoria e le deallocazione.
Esempio
afxMemDF = allocMemDF | checkAlwaysMemDF;
Requisiti
Intestazione: afx.h
AfxCheckError
Questa funzione verifica il codice SCODE passato per verificare se si tratta di un errore.
void AFXAPI AfxCheckError(SCODE sc);
throw CMemoryException*
throw COleException*
Osservazioni:
Se si tratta di un errore, la funzione genera un'eccezione. Se l'oggetto SCODE passato è E_OUTOFMEMORY, la funzione genera un'eccezione CMemoryException chiamando AfxThrowMemoryException. In caso contrario, la funzione genera un'eccezione COleException chiamando AfxThrowOleException.
Questa funzione può essere usata per controllare i valori restituiti delle chiamate alle funzioni OLE nell'applicazione. Testando il valore restituito con questa funzione nell'applicazione, è possibile reagire correttamente alle condizioni di errore con una quantità minima di codice.
Nota
Questa funzione ha lo stesso effetto nelle compilazioni di debug e non di debug.
Esempio
AfxCheckError(::CoCreateInstance(clsidWMP, NULL, CLSCTX_INPROC_SERVER,
IID_IDispatch, (LPVOID*)& pWMPDispatch));
oddWMP.AttachDispatch(pWMPDispatch, TRUE);
Requisiti
Intestazione: afx.h
AfxCheckMemory
Questa funzione convalida il pool di memoria libera e stampa i messaggi di errore in base alle esigenze.
BOOL AfxCheckMemory();
Valore restituito
Diverso da zero se non sono presenti errori di memoria; in caso contrario, 0.
Osservazioni:
Se la funzione non rileva alcun danneggiamento della memoria, non stampa nulla.
Tutti i blocchi di memoria attualmente allocati nell'heap vengono controllati, inclusi quelli allocati da new
ma non da quelli allocati dalle chiamate dirette agli allocatori di memoria sottostanti, ad esempio la funzione malloc o la GlobalAlloc
funzione Windows. Se viene rilevato un blocco danneggiato, viene stampato un messaggio nell'output del debugger.
Se si include la riga
#define new DEBUG_NEW
in un modulo di programma, quindi chiamate successive per AfxCheckMemory
visualizzare il nome file e il numero di riga in cui è stata allocata la memoria.
Nota
Se il modulo contiene una o più implementazioni di classi serializzabili, è necessario inserire la #define
riga dopo l'ultima chiamata di macro IMPLEMENT_SERIAL.
Questa funzione funziona solo nella versione Debug di MFC.
Esempio
CAge* pcage = new CAge(21); // CAge is derived from CObject.
Age* page = new Age(22); // Age is NOT derived from CObject.
*(((char*)pcage) - 1) = 99; // Corrupt preceding guard byte
*(((char*)page) - 1) = 99; // Corrupt preceding guard byte
AfxCheckMemory();
Requisiti
Intestazione: afx.h
AfxDump (MFC)
Chiamare questa funzione mentre si trova nel debugger per eseguire il dump dello stato di un oggetto durante il debug.
void AfxDump(const CObject* pOb);
Parametri
Pob
Puntatore a un oggetto di una classe derivata da CObject
.
Osservazioni:
AfxDump
chiama la funzione membro di Dump
un oggetto e invia le informazioni alla posizione specificata dalla afxDump
variabile. AfxDump
è disponibile solo nella versione debug di MFC.
Il codice del programma non deve chiamare AfxDump
, ma deve invece chiamare la Dump
funzione membro dell'oggetto appropriato.
Requisiti
Intestazione: afx.h
AfxDumpStack
Questa funzione globale può essere usata per generare un'immagine dello stack corrente.
void AFXAPI AfxDumpStack(DWORD dwTarget = AFX_STACK_DUMP_TARGET_DEFAULT);
Parametri
dwTarget
Indica la destinazione dell'output del dump. I valori possibili, che possono essere combinati usando l'operatore OR bit per bit (|
), sono i seguenti:
AFX_STACK_DUMP_TARGET_TRACE Invia l'output tramite la macro TRACE . La macro TRACE genera l'output solo nelle compilazioni di debug; non genera alcun output nelle build di versione. Inoltre, TRACE può essere reindirizzato ad altre destinazioni oltre al debugger.
AFX_STACK_DUMP_TARGET_DEFAULT Invia l'output del dump alla destinazione predefinita. Per una compilazione di debug, l'output passa alla macro TRACE. In una build di versione, l'output passa agli Appunti.
AFX_STACK_DUMP_TARGET_CLIPBOARD Invia l'output solo agli Appunti. I dati vengono inseriti negli Appunti come testo normale usando il formato CF_TEXT Appunti.
AFX_STACK_DUMP_TARGET_BOTH Invia l'output agli Appunti e alla macro TRACE contemporaneamente.
AFX_STACK_DUMP_TARGET_ODS Invia l'output direttamente al debugger tramite la funzione
OutputDebugString()
Win32 . Questa opzione genererà l'output del debugger nelle compilazioni di debug e versione quando un debugger è collegato al processo. AFX_STACK_DUMP_TARGET_ODS raggiunge sempre il debugger (se è collegato) e non può essere reindirizzato.
Osservazioni:
L'esempio seguente riflette una singola riga dell'output generato dalla chiamata AfxDumpStack
da un gestore di pulsanti in un'applicazione di dialogo MFC:
=== begin AfxDumpStack output ===
00427D55: DUMP2\DEBUG\DUMP2.EXE! void AfxDumpStack(unsigned long) + 181 bytes
0040160B: DUMP2\DEBUG\DUMP2.EXE! void CDump2Dlg::OnClipboard(void) + 14 bytes
0044F884: DUMP2\DEBUG\DUMP2.EXE! int _AfxDispatchCmdMsg(class CCmdTarget *,
unsigned int,int,void ( CCmdTarget::*)(void),void *,unsigned int,struct
AFX_CMDHANDLE
0044FF7B: DUMP2\DEBUG\DUMP2.EXE! virtual int CCmdTarget::OnCmdMsg(unsigned
int,int,void *,struct AFX_CMDHANDLERINFO *) + 626 bytes
00450C71: DUMP2\DEBUG\DUMP2.EXE! virtual int CDialog::OnCmdMsg(unsigned
int,int,void *,struct AFX_CMDHANDLERINFO *) + 36 bytes
00455B27: DUMP2\DEBUG\DUMP2.EXE! virtual int CWnd::OnCommand(unsigned
int,long) + 312 bytes
00454D3D: DUMP2\DEBUG\DUMP2.EXE! virtual int CWnd::OnWndMsg(unsigned
int,unsigned int,long,long *) + 83 bytes
00454CC0: DUMP2\DEBUG\DUMP2.EXE! virtual long CWnd::WindowProc(unsigned
int,unsigned int,long) + 46 bytes
004528D9: DUMP2\DEBUG\DUMP2.EXE! long AfxCallWndProc(class CWnd *,struct
HWND__ *,unsigned int,unsigned int,long) + 237 bytes
00452D34: DUMP2\DEBUG\DUMP2.EXE! long AfxWndProc(struct HWND__ *,unsigned
int,unsigned int,long) + 129 bytes
BFF73663: WINDOWS\SYSTEM\KERNEL32.DLL! ThunkConnect32 + 2148 bytes
BFF928E0: WINDOWS\SYSTEM\KERNEL32.DLL! UTUnRegister + 2492 bytes
=== end AfxDumpStack() output ===
Ogni riga nell'output precedente indica l'indirizzo dell'ultima chiamata di funzione, il nome del percorso completo del modulo che contiene la chiamata di funzione e il prototipo di funzione chiamato. Se la chiamata di funzione nello stack non si verifica all'indirizzo esatto della funzione, viene visualizzato un offset di byte.
Ad esempio, la tabella seguente descrive la prima riga dell'output precedente:
Output | Descrizione |
---|---|
00427D55: |
Indirizzo restituito dell'ultima chiamata di funzione. |
DUMP2\DEBUG\DUMP2.EXE! |
Nome del percorso completo del modulo che contiene la chiamata di funzione. |
void AfxDumpStack(unsigned long) |
Prototipo di funzione chiamato. |
+ 181 bytes |
Offset in byte dall'indirizzo del prototipo di funzione (in questo caso , void AfxDumpStack(unsigned long) ) all'indirizzo restituito (in questo caso, 00427D55 ). |
AfxDumpStack
è disponibile nelle versioni di debug e non diebug delle librerie MFC; Tuttavia, la funzione viene sempre collegata in modo statico, anche quando il file eseguibile usa MFC in una DLL condivisa. Nelle implementazioni della libreria condivisa, la funzione si trova in MFCS42. Libreria LIB (e le relative varianti).
Per usare correttamente questa funzione:
Il file IMAGEHLP.DLL deve trovarsi nel percorso. Se questa DLL non è disponibile, la funzione visualizzerà un messaggio di errore. Per informazioni sul set di funzioni fornito da IMAGEHLP, vedere Raccolta guida immagini.
I moduli con frame nello stack devono includere informazioni di debug. Se non contengono informazioni di debug, la funzione genererà comunque un'analisi dello stack, ma la traccia sarà meno dettagliata.
Requisiti
Intestazione: afx.h
AfxEnableMemoryLeakDump
Abilita e disabilita il dump della perdita di memoria nel distruttore AFX_DEBUG_STATE.
BOOL AFXAPI AfxEnableMemoryLeakDump(BOOL bDump);
Parametri
bDump
[in] TRUE indica che il dump della perdita di memoria è abilitato; FALSE indica che il dump della perdita di memoria è disabilitato.
Valore restituito
Il valore precedente per questo flag.
Osservazioni:
Quando un'applicazione scarica la libreria MFC, quest'ultima controlla se si sono verificate perdite di memoria. A questo punto, eventuali perdite di memoria vengono segnalate all'utente tramite la finestra Debug di Visual Studio.
Se l'applicazione carica un'altra libreria prima della libreria MFC, alcune allocazioni di memoria in tale libreria verranno segnalate erroneamente come perdite di memoria. Per effetto di queste segnalazioni errate, è possibile che l'applicazione venga chiusa lentamente a mano a mano che le perdite vengono segnalate dalla libreria MFC. In tal caso, usare AfxEnableMemoryLeakDump
per disabilitare il dump delle perdite di memoria.
Nota
Se si usa questo metodo per disabilitare il dump delle perdite di memoria, nell'applicazione non si riceveranno i report delle perdite di memoria effettive. È consigliabile usare questo metodo solo se si è certi che il report contenga informazioni errate sulle perdite di memoria.
Requisiti
Intestazione: afx.h
AfxEnableMemoryTracking
Il rilevamento della memoria diagnostica è in genere abilitato nella versione debug di MFC.
BOOL AfxEnableMemoryTracking(BOOL bTrack);
Parametri
bTrack
L'impostazione di questo valore su TRUE attiva il rilevamento della memoria; FALSE lo disattiva.
Valore restituito
Impostazione precedente del flag di abilitazione del rilevamento.
Osservazioni:
Usare questa funzione per disabilitare il rilevamento nelle sezioni del codice che si sa stanno allocando correttamente i blocchi.
Per altre informazioni su AfxEnableMemoryTracking
, vedere Debug di applicazioni MFC.
Nota
Questa funzione funziona solo nella versione Debug di MFC.
Esempio
BOOL CMyWinApp::InitInstance()
{
#ifdef _DEBUG
// Disable tracking of memory for the scope of the InitInstance()
AfxEnableMemoryTracking(FALSE);
#endif // _DEBUG
// ...
#ifdef _DEBUG
// Re-enable tracking of memory
AfxEnableMemoryTracking(TRUE);
#endif // _DEBUG
return TRUE;
}
Requisiti
Intestazione: afx.h
AfxIsMemoryBlock
Verifica un indirizzo di memoria per assicurarsi che rappresenti un blocco di memoria attualmente attivo allocato dalla versione diagnostica di new
.
BOOL AfxIsMemoryBlock(
const void* p,
UINT nBytes,
LONG* plRequestNumber = NULL);
Parametri
p
Punta al blocco di memoria da testare.
nBytes
Contiene la lunghezza del blocco di memoria in byte.
plRequestNumber
Punta a un long
numero intero che verrà compilato con il numero di sequenza di allocazione del blocco di memoria oppure zero se non rappresenta un blocco di memoria attualmente attivo.
Valore restituito
Diverso da zero se il blocco di memoria è attualmente allocato e la lunghezza è corretta; in caso contrario, 0.
Osservazioni:
Controlla anche le dimensioni specificate rispetto alle dimensioni allocate originali. Se la funzione restituisce un valore diverso da zero, il numero di sequenza di allocazione viene restituito in plRequestNumber. Questo numero rappresenta l'ordine in cui il blocco è stato allocato rispetto a tutte le altre new
allocazioni.
Esempio
CAge* pcage = new CAge(21); // CAge is derived from CObject.
ASSERT(AfxIsMemoryBlock(pcage, sizeof(CAge)));
Requisiti
Intestazione: afx.h
AfxIsValidAddress
Verifica qualsiasi indirizzo di memoria per assicurarsi che sia contenuto interamente all'interno dello spazio di memoria del programma.
BOOL AfxIsValidAddress(
const void* lp,
UINT nBytes,
BOOL bReadWrite = TRUE);
Parametri
Lp
Punta all'indirizzo di memoria da testare.
nBytes
Contiene il numero di byte di memoria da testare.
bReadWrite
Specifica se la memoria è sia per la lettura che per la scrittura (TRUE) o solo per la lettura (FALSE).
Valore restituito
Nelle compilazioni di debug, diverso da zero se il blocco di memoria specificato è contenuto interamente all'interno dello spazio di memoria del programma; in caso contrario, 0.
Nelle compilazioni non di debug, diverso da zero se lp non è NULL; in caso contrario, 0.
Osservazioni:
L'indirizzo non è limitato ai blocchi allocati da new
.
Esempio
// Allocate a 5 character array, which should have a valid memory address.
char* arr = new char[5];
// Create a null pointer, which should be an invalid memory address.
char* null = (char*)0x0;
ASSERT(AfxIsValidAddress(arr, 5));
ASSERT(!AfxIsValidAddress(null, 5));
Requisiti
Intestazione: afx.h
AfxIsValidString
Utilizzare questa funzione per determinare se un puntatore a una stringa è valido.
BOOL AfxIsValidString(
LPCSTR lpsz,
int nLength = -1);
Parametri
lpsz
Puntatore da testare.
nLength
Specifica la lunghezza della stringa da testare, in byte. Il valore -1 indica che la stringa verrà terminata con null.
Valore restituito
Nelle compilazioni di debug, diverso da zero se il puntatore specificato punta a una stringa delle dimensioni specificate; in caso contrario, 0.
Nelle compilazioni non di debug, diverso da zero se lpsz non è NULL; in caso contrario, 0.
Esempio
// Create a character string which should be valid.
char str[12] = "hello world";
// Create a null pointer, which should be an invalid string.
char* null = (char*)0x0;
ASSERT(AfxIsValidString(str, 12));
ASSERT(!AfxIsValidString(null, 5));
Requisiti
Intestazione: afx.h
AfxSetAllocHook
Imposta un hook che consente di chiamare la funzione specificata prima che ogni blocco di memoria venga allocato.
AFX_ALLOC_HOOK AfxSetAllocHook(AFX_ALLOC_HOOK pfnAllocHook);
Parametri
pfnAllocHook
Specifica il nome della funzione da chiamare. Vedere le osservazioni per il prototipo di una funzione di allocazione.
Valore restituito
Diverso da zero se si vuole consentire l'allocazione; in caso contrario, 0.
Osservazioni:
L'allocatore di debug della memoria di Microsoft Foundation Class Library può chiamare una funzione hook definita dall'utente per consentire all'utente di monitorare un'allocazione di memoria e di controllare se l'allocazione è consentita. Le funzioni hook di allocazione vengono prototipi come indicato di seguito:
BOOL AFXAPI AllocHook( size_t nSize
, BOOLbObject
, LONG ); lRequestNumber
nSize
Dimensioni dell'allocazione di memoria proposta.
bObject
TRUE se l'allocazione è per un CObject
oggetto derivato da ; in caso contrario, FALSE.
lRequestNumber
Numero di sequenza dell'allocazione della memoria.
Si noti che la convenzione di chiamata AFXAPI implica che il chiamato deve rimuovere i parametri dallo stack.
Requisiti
Intestazione: afx.h
AfxDoForAllClasses
Chiama la funzione di iterazione specificata per tutte le classi derivate da serializzabili CObject
nello spazio di memoria dell'applicazione.
void
AFXAPI AfxDoForAllClasses(
void (* pfn)(const CRuntimeClass* pClass, void* pContext),
void* pContext);
Parametri
pfn
Punta a una funzione di iterazione da chiamare per ogni classe. Gli argomenti della funzione sono un puntatore a un CRuntimeClass
oggetto e un puntatore void a dati aggiuntivi forniti dal chiamante alla funzione.
pContext
Punta a dati facoltativi che il chiamante può fornire alla funzione di iterazione. Questo puntatore può essere NULL.
Osservazioni:
Le classi derivate da serializzabili CObject
sono classi derivate tramite la macro DECLARE_SERIAL. Il puntatore passato a AfxDoForAllClasses
in pContext viene passato alla funzione di iterazione specificata ogni volta che viene chiamato.
Nota
Questa funzione funziona solo nella versione Debug di MFC.
Esempio
#ifdef _DEBUG
void DoForAllClasses(const CRuntimeClass* pClass, void* pContext)
{
ASSERT(pContext != NULL);
CString* pStr = (CString*)pContext;
*pStr += pClass->m_lpszClassName;
*pStr += _T("\n");
}
#endif
#ifdef _DEBUG
CString cStr;
AfxDoForAllClasses(DoForAllClasses, &cStr);
AfxMessageBox(cStr);
#endif
Requisiti
Intestazione: afx.h
AfxDoForAllObjects
Esegue la funzione di iterazione specificata per tutti gli oggetti derivati da CObject
allocati con new
.
void AfxDoForAllObjects(
void (* pfn)(CObject* pObject, void* pContext),
void* pContext);
Parametri
pfn
Punta a una funzione di iterazione da eseguire per ogni oggetto. Gli argomenti della funzione sono un puntatore a un CObject
e un puntatore void a dati aggiuntivi forniti dal chiamante alla funzione.
pContext
Punta a dati facoltativi che il chiamante può fornire alla funzione di iterazione. Questo puntatore può essere NULL.
Osservazioni:
Gli oggetti stack, globali o incorporati non vengono enumerati. Il puntatore passato a AfxDoForAllObjects
in pContext viene passato alla funzione di iterazione specificata ogni volta che viene chiamato.
Nota
Questa funzione funziona solo nella versione Debug di MFC.
Esempio
#ifdef _DEBUG
void DoForAllObjects(CObject* pObject, void* pContext)
{
int* pnCount = (int*)pContext;
pObject->AssertValid();
if (pnCount != NULL)
(*pnCount)++;
}
#endif // _DEBUG
#ifdef _DEBUG
//AfxDoForAllObjects will call the function DoForAllObjects
//For each CObject-derived object that is allocated on the heap
int nCount = 0;
AfxDoForAllObjects(DoForAllObjects, &nCount);
TRACE("%d Objects Checked\n", nCount);
#endif