Diagnosedienste
Die Microsoft Foundation Class-Bibliothek bietet viele Diagnosedienste, die das Debuggen von Programmen erleichtern. Zu diesen Diagnosediensten zählen Makros und globale Funktionen, die Ihnen das Nachverfolgen der Speicherzuweisungen von Programmen, das Sichern des Inhalts von Objekten zur Laufzeit und das Ausgeben von Debugmeldungen zur Laufzeit ermöglichen. Die Makros und globalen Funktionen für Diagnosedienste sind in folgende Kategorien gruppiert:
Allgemeine Diagnosemakros
Allgemeine Diagnosefunktionen und -Variablen
Objektdiagnosefunktionen
Diese Makros und Funktionen stehen in den Debug- und den endgültigen Produktversionen von MFC für alle von CObject
abgeleiteten Klassen zur Verfügung. Alle außer DEBUG_NEW und VERIFY tun jedoch nichts in der Releaseversion.
In der Debugbibliothek werden alle zugeordneten Speicherblöcke mit einer Reihe von "Guard Bytes" in eckige Klammern gesetzt. Wenn diese Bytes durch einen fehlerhaften Speicherschreibvorgang gestört werden, können die Diagnoseroutinen ein Problem melden. Wenn Sie diese Zeile:
#define new DEBUG_NEW
in Ihrer Implementierungsdatei speichern alle Aufrufe new
den Dateinamen und die Zeilennummer, an der die Speicherzuweisung stattgefunden hat. Die Funktion CMemoryState::DumpAllObjectsSince zeigt diese Zusatzinformationen an, was Ihnen das Erkennen von Speicherverlusten ermöglicht. Weitere Informationen zur Diagnoseausgabe finden Sie auch bei der Klasse CDumpContext .
Darüber hinaus unterstützt die C-Laufzeitbibliothek auch eine Reihe von Diagnosefunktionen, die Sie zum Debuggen von Anwendungen verwenden können. Weitere Informationen finden Sie unter Debugroutinen in der Referenz zur Laufzeitbibliothek.
Allgemeine MFC-Diagnosemakros
Name | Beschreibung |
---|---|
ASSERT | Gibt eine Meldung aus und bricht dann das Programm ab, wenn der angegebene Ausdruck in der Debugversion der Bibliothek als FALSE ausgewertet wird. |
ASSERT_KINDOF | Prüft, ob ein Objekt ein Objekt der angegebenen Klasse oder einer aus der angegebenen Klasse abgeleiteten Klasse ist. |
ASSERT_VALID | Prüft die interne Gültigkeit eines Objekts durch Aufrufen seiner AssertValid -Memberfunktion; normalerweise durch CObject außer Kraft gesetzt. |
DEBUG_NEW | Gibt einen Dateinamen und eine Zeilennummer für alle Objektzuweisungen im Debugmodus an, um die Suche nach Speicherverlusten zu unterstützen. |
DEBUG_ONLY | Ähnlich wie ASSERT , prüft jedoch nicht den Wert des Ausdrucks; nützlich für Code, der nur im Debugmodus ausgeführt werden soll. |
SICHERSTELLEN und ENSURE_VALID | Wird verwendet, um die Richtigkeit der Daten zu überprüfen. |
THIS_FILE | Erweitert den Namen der Datei, die kompiliert wird. |
TRACE | Stellt eine printf -ähnliche Funktionalität in der Debugversion der Bibliothek zur Verfügung. |
VERIFY | Ähnlich wie ASSERT , wertet den Ausdruck aber sowohl in der endgültigen Version der Bibliothek als auch in der Debugversion aus. |
Allgemeine MFC-Diagnosevariablen und -Funktionen
Name | Beschreibung |
---|---|
afxDump | Globale Variable, die CDumpContext -Informationen an das Debuggerausgabefenster oder das Debugterminal sendet. |
afxMemDF | Globale Variable, die das Verhalten der Debugspeicherzuweisung steuert. |
AfxCheckError | Globale Variable, die zum Prüfen des übergebenen SCODE s verwendet wird, um festzustellen, ob es sich um einen Fehler handelt; löst in diesem Fall den entsprechenden Fehler aus. |
AfxCheckMemory | Überprüft die Integrität des gesamten derzeit zugewiesenen Speichers. |
AfxDebugBreak | Verursacht einen Bruch bei der Ausführung. |
AfxDump | Sichert bei einem Aufruf im Debugger den Status eines Objekts während des Debuggens. |
AfxDump | Interne Funktion, die den Zustand eines Objekts beim Debuggen abbildet. |
AfxDumpStack | Generiert ein Image des aktuellen Stapels. Diese Funktion wird immer statisch gelinkt. |
AfxEnableMemoryLeakDump | Ermöglicht das Sichern von Speicherverlusten. |
AfxEnableMemoryTracking | Aktiviert und deaktiviert die Arbeitsspeicher-Nachverfolgung. |
AfxIsMemoryBlock | Überprüft, ob ein Speicherblock ordnungsgemäß zugewiesen wurde. |
AfxIsValidAddress | Überprüft, ob ein Speicheradressbereich innerhalb der Grenzen des Programms liegt. |
AfxIsValidString | Bestimmt, ob ein Zeiger auf eine Zeichenfolge gültig ist. |
AfxSetAllocHook | Ermöglicht das Aufrufen einer Funktion für jede Speicherzuweisung. |
MFC-Objektdiagnosefunktionen
Name | Beschreibung |
---|---|
AfxDoForAllClasses | Führt eine angegebene Funktion für alle von CObject abgeleiteten Klassen aus, die Typprüfung zur Laufzeit unterstützen. |
AfxDoForAllObjects | Führt eine angegebene Funktion für alle CObject abgeleiteten Objekte aus, die zugeordnet new wurden. |
MFC-Kompilierungsmakros
Name | Beschreibung |
---|---|
_AFX_SECURE_NO_WARNINGS | Unterdrückt Compilerwarnungen für die Verwendung veralteter MFC-Funktionen. |
_AFX_SECURE_NO_WARNINGS
Unterdrückt Compilerwarnungen für die Verwendung veralteter MFC-Funktionen.
Syntax
_AFX_SECURE_NO_WARNINGS
Beispiel
In diesem Codebeispiel wird eine Compilerwarnung verursacht, wenn _AFX_SECURE_NO_WARNINGS
sie nicht definiert ist.
// 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
Rufen Sie diese Funktion auf, um bei der Ausführung der Debugversion Ihrer MFC-Anwendung eine Unterbrechung (an der Position des Aufrufs AfxDebugBreak
von ) zu verursachen.
Syntax
void AfxDebugBreak( );
Hinweise
AfxDebugBreak
hat keine Auswirkung in Releaseversionen einer MFC-Anwendung und sollte entfernt werden. Diese Funktion sollte nur in MFC-Anwendungen verwendet werden. Verwenden Sie die Win32-API-Version, DebugBreak
um einen Bruch in Nicht-MFC-Anwendungen zu verursachen.
Anforderungen
Kopfzeile: afxver_.h
ASSERT
Wertet das Argument aus.
ASSERT(booleanExpression)
Parameter
booleanExpression
Gibt einen Ausdruck (einschließlich Zeigerwerte) an, der als "nonzero" oder "0" ausgewertet wird.
Hinweise
Wenn das Ergebnis 0 ist, druckt das Makro eine Diagnosemeldung und bricht das Programm ab. Wenn die Bedingung ungleich Null ist, führt sie nichts aus.
Die Diagnosemeldung hat die Form
assertion failed in file <name> in line <num>
dabei ist der Name der Quelldatei, und die Zahl ist die Zeilennummer der Assertion, die in der Quelldatei fehlgeschlagen ist.
In der Releaseversion von MFC wertet ASSERT den Ausdruck nicht aus und unterbricht somit das Programm nicht. Wenn der Ausdruck unabhängig von der Umgebung ausgewertet werden muss, verwenden Sie das VERIFY-Makro anstelle von ASSERT.
Hinweis
Diese Funktion ist nur in der Debugversion von MFC verfügbar.
Beispiel
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*.
Anforderungen
Header: afx.h
ASSERT_KINDOF
Dieses Makro bestätigt, dass das objekt, auf das verwiesen wird, ein Objekt der angegebenen Klasse ist oder ein Objekt einer von der angegebenen Klasse abgeleiteten Klasse ist.
ASSERT_KINDOF(classname, pobject)
Parameter
classname
Der Name einer CObject
abgeleiteten Klasse.
pobject
Ein Zeiger auf ein Klassenobjekt.
Hinweise
Der pobject-Parameter sollte ein Zeiger auf ein Objekt sein und kann sein const
. Das Objekt, auf das verwiesen wird, und die Klasse muss Laufzeitklasseninformationen unterstützen CObject
. Um beispielsweise sicherzustellen, dass es pDocument
sich um einen Zeiger auf ein Objekt der CMyDoc
Klasse oder eines seiner Ableitungen handelt, können Sie codeieren:
ASSERT_KINDOF(CMyDoc, pDocument);
Die Verwendung des ASSERT_KINDOF
Makros entspricht genau der Codierung:
ASSERT(pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)));
Diese Funktion funktioniert nur für Klassen, die mit dem [DECLARE_DYNAMIC](run-time-object-model-services.md#declare_dynamic- oder DECLARE_SERIAL-Makro deklariert wurden.
Hinweis
Diese Funktion ist nur in der Debugversion von MFC verfügbar.
Anforderungen
Header: afx.h
ASSERT_VALID
Wird verwendet, um Die Annahmen über die Gültigkeit des internen Zustands eines Objekts zu testen.
ASSERT_VALID(pObject)
Parameter
pObject
Gibt ein Objekt einer Klasse an, die von CObject
einer überschreibenden Version der AssertValid
Memberfunktion abgeleitet ist.
Hinweise
ASSERT_VALID ruft die AssertValid
Memberfunktion des Objekts auf, das als Argument übergeben wird.
In der Releaseversion von MFC führt ASSERT_VALID nichts aus. In der Debugversion überprüft sie den Zeiger, überprüft null und ruft die eigenen AssertValid
Memberfunktionen des Objekts auf. Wenn einer dieser Tests fehlschlägt, wird eine Warnmeldung auf die gleiche Weise wie ASSERT angezeigt.
Hinweis
Diese Funktion ist nur in der Debugversion von MFC verfügbar.
Weitere Informationen und Beispiele finden Sie unter Debuggen von MFC-Anwendungen.
Beispiel
// Assure that pMyObject is a valid pointer to an
// object derived from CObject.
ASSERT_VALID(pMyObject);
Anforderungen
Header: afx.h
DEBUG_NEW
Unterstützt das Auffinden von Speicherlecks.
#define new DEBUG_NEW
Hinweise
Sie können DEBUG_NEW überall in Ihrem Programm verwenden, mit dem Sie den new
Operator normalerweise verwenden würden, um Heap-Speicher zuzuweisen.
Im Debugmodus (wenn das _DEBUG-Symbol definiert ist), verfolgt DEBUG_NEW den Dateinamen und die Zeilennummer für jedes Objekt, das sie zuweist. Wenn Sie dann die Memberfunktion "CMemoryState::D umpAllObjectsSince " verwenden, wird jedes objekt, das DEBUG_NEW zugeordnet ist, mit dem Dateinamen und der Zeilennummer angezeigt, in der es zugewiesen wurde.
Um DEBUG_NEW zu verwenden, fügen Sie die folgende Direktive in Ihre Quelldateien ein:
#define new DEBUG_NEW
Nachdem Sie diese Direktive eingefügt haben, fügt der Präprozessor DEBUG_NEW überall dort ein, wo Sie sie verwenden new
, und MFC erledigt den Rest. Wenn Sie eine Releaseversion Ihres Programms kompilieren, wird DEBUG_NEW zu einem einfachen new
Vorgang aufgelöst, und die Dateinamen- und Zeilennummerninformationen werden nicht generiert.
Hinweis
In früheren Versionen von MFC (4.1 und früher) mussten Sie die #define
Anweisung nach allen Anweisungen platzieren, die die IMPLEMENT_DYNCREATE- oder IMPLEMENT_SERIAL-Makros aufgerufen haben. Dies ist nicht mehr erforderlich.
Anforderungen
Header: afx.h
DEBUG_ONLY
Im Debugmodus (wenn das _DEBUG-Symbol definiert ist), wertet DEBUG_ONLY sein Argument aus.
DEBUG_ONLY(expression)
Hinweise
In einem Releasebuild wertet DEBUG_ONLY das Argument nicht aus. Dies ist nützlich, wenn Sie Code haben, der nur in Debugbuilds ausgeführt werden soll.
Das DEBUG_ONLY Makro entspricht dem umgebenden Ausdruck mit #ifdef _DEBUG
und #endif
.
Beispiel
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');
}
Anforderungen
Header: afx.h
SICHERSTELLEN und ENSURE_VALID
Wird verwendet, um die Richtigkeit der Daten zu überprüfen.
Syntax
ENSURE( booleanExpression )
ENSURE_VALID( booleanExpression )
Parameter
booleanExpression
Gibt einen booleschen Ausdruck an, der getestet werden soll.
Hinweise
Der Zweck dieser Makros besteht darin, die Überprüfung von Parametern zu verbessern. Die Makros verhindern die weitere Verarbeitung falscher Parameter in Ihrem Code. Im Gegensatz zu den ASSERT-Makros lösen die ENSURE-Makros zusätzlich zum Generieren einer Assertion eine Ausnahme aus.
Die Makros verhalten sich je nach Projektkonfiguration auf zwei Arten. Die Makros rufen ASSERT auf und lösen dann eine Ausnahme aus, wenn die Assertion fehlschlägt. Daher erzeugen die Makros in Debugkonfigurationen (d. a. wenn _DEBUG definiert ist) eine Assertion und Ausnahme, während die Makros in Releasekonfigurationen nur die Ausnahme erzeugen (ASSERT wertet den Ausdruck in Releasekonfigurationen nicht aus).
Das Makro ENSURE_ARG fungiert wie das ENSURE-Makro.
ENSURE_VALID ruft das ASSERT_VALID-Makro auf (das nur in Debugbuilds wirksam ist). Darüber hinaus löst ENSURE_VALID eine Ausnahme aus, wenn der Zeiger NULL ist. Der NULL-Test wird sowohl in Debug- als auch in Releasekonfigurationen ausgeführt.
Wenn einer dieser Tests fehlschlägt, wird eine Warnmeldung auf die gleiche Weise wie ASSERT angezeigt. Das Makro löst bei Bedarf eine Ausnahme für ungültige Argumente aus.
Anforderungen
Header: afx.h
THIS_FILE
Erweitert den Namen der Datei, die kompiliert wird.
Syntax
THIS_FILE
Hinweise
Die Informationen werden von den MAKROS ASSERT und VERIFY verwendet. Der Anwendungs-Assistent und die Code-Assistenten platzieren das Makro in Quellcodedateien, die sie erstellen.
Beispiel
#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.
Anforderungen
Header: afx.h
TRACE
Sendet die angegebene Zeichenfolge an den Debugger der aktuellen Anwendung.
TRACE(exp)
TRACE(DWORD category, UINT level, LPCSTR lpszFormat, ...)
Hinweise
Eine Beschreibung von TRACE finden Sie unter ATLTRACE2 . TRACE und ATLTRACE2 haben das gleiche Verhalten.
In der Debugversion von MFC sendet dieses Makro die angegebene Zeichenfolge an den Debugger der aktuellen Anwendung. In einem Releasebuild kompiliert dieses Makro nichts (es wird überhaupt kein Code generiert).
Weitere Informationen finden Sie unter Debuggen von MFC-Anwendungen.
Anforderungen
Header: afx.h
VERIFY
In der Debugversion von MFC wertet das Argument aus.
VERIFY(booleanExpression)
Parameter
booleanExpression
Gibt einen Ausdruck (einschließlich Zeigerwerte) an, der als "nonzero" oder "0" ausgewertet wird.
Hinweise
Wenn das Ergebnis 0 ist, druckt das Makro eine Diagnosemeldung und hält das Programm an. Wenn die Bedingung ungleich Null ist, führt sie nichts aus.
Die Diagnosemeldung hat die Form
assertion failed in file <name> in line <num>
dabei ist der Name der Quelldatei und die Zahl die Zeilennummer der Assertion, die in der Quelldatei fehlgeschlagen ist.
In der Releaseversion von MFC wertet VERIFY den Ausdruck aus, druckt oder unterbricht das Programm jedoch nicht. Wenn der Ausdruck beispielsweise ein Funktionsaufruf ist, wird der Aufruf ausgeführt.
Beispiel
// 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);
Anforderungen
Header: afx.h
afxDump (CDumpContext in MFC)
Stellt grundlegende Objektdumpingfunktionen in Ihrer Anwendung bereit.
CDumpContext afxDump;
Hinweise
afxDump
ist ein vordefiniertes CDumpContext-Objekt , mit dem Sie Informationen an das Ausgabefenster des Debuggers oder an ein Debugterminal senden CDumpContext
können. In der Regel geben afxDump
Sie als Parameter an CObject::Dump
.
Unter Windows NT und allen Versionen von Windows afxDump
wird die Ausgabe beim Debuggen der Anwendung an das Ausgabedebugfenster von Visual C++ gesendet.
Diese Variable wird nur in der Debugversion von MFC definiert. Weitere Informationen afxDump
finden Sie unter Debuggen von MFC-Anwendungen.
Beispiel
// 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
Anforderungen
Header: afx.h
AfxDump (Intern)
Interne Funktion, die MFC zum Abbilden des Zustands eines Objekts beim Debuggen verwendet.
Syntax
void AfxDump(const CObject* pOb);
Parameter
Pob
Ein Zeiger auf ein Objekt einer klasse, die von CObject
.
Hinweise
AfxDump
ruft die Memberfunktion eines Objekts Dump
auf und sendet die Informationen an die durch die afxDump
Variable angegebene Position. AfxDump
ist nur in der Debugversion von MFC verfügbar.
Ihr Programmcode sollte nicht aufgerufen AfxDump
werden, sondern stattdessen die Dump
Memberfunktion des entsprechenden Objekts aufrufen.
Anforderungen
Header: afx.h
afxMemDF
Auf diese Variable kann über einen Debugger oder Ihr Programm zugegriffen werden und Sie können die Zuordnungsdiagnose optimieren.
int afxMemDF;
Hinweise
afxMemDF
kann die folgenden Werte aufweisen, wie durch die Enumeration afxMemDF
angegeben:
allocMemDF
Aktiviert das Debuggen von Allocator (Standardeinstellung in der Debugbibliothek).delayFreeMemDF
Verzögert das Freigeben von Arbeitsspeicher. Während Ihr Programm einen Speicherblock freigibt, gibt der Allocator diesen Speicher nicht an das zugrunde liegende Betriebssystem zurück. Dadurch wird ihr Programm maximaler Arbeitsspeicher belastet.checkAlwaysMemDF
AnrufeAfxCheckMemory
jedes Mal, wenn Arbeitsspeicher zugewiesen oder freigegeben wird. Dadurch werden Speicherzuweisungen und Deallocations erheblich verlangsamt.
Beispiel
afxMemDF = allocMemDF | checkAlwaysMemDF;
Anforderungen
Header: afx.h
AfxCheckError
Diese Funktion testet den übergebenen SCODE, um festzustellen, ob es sich um einen Fehler handelt.
void AFXAPI AfxCheckError(SCODE sc);
throw CMemoryException*
throw COleException*
Hinweise
Wenn es sich um einen Fehler handelt, löst die Funktion eine Ausnahme aus. Wenn der übergebene SCODE E_OUTOFMEMORY ist, löst die Funktion eine CMemoryException aus, indem AfxThrowMemoryException aufgerufen wird. Andernfalls löst die Funktion eine COleException aus, indem AfxThrowOleException aufgerufen wird.
Diese Funktion kann verwendet werden, um die Rückgabewerte von Aufrufen von OLE-Funktionen in Ihrer Anwendung zu überprüfen. Indem Sie den Rückgabewert mit dieser Funktion in Ihrer Anwendung testen, können Sie ordnungsgemäß auf Fehlerbedingungen mit einer minimalen Menge an Code reagieren.
Hinweis
Diese Funktion hat den gleichen Effekt in Debug- und Nicht-Debugbuilds.
Beispiel
AfxCheckError(::CoCreateInstance(clsidWMP, NULL, CLSCTX_INPROC_SERVER,
IID_IDispatch, (LPVOID*)& pWMPDispatch));
oddWMP.AttachDispatch(pWMPDispatch, TRUE);
Anforderungen
Header: afx.h
AfxCheckMemory
Diese Funktion überprüft den freien Speicherpool und druckt Fehlermeldungen nach Bedarf.
BOOL AfxCheckMemory();
Rückgabewert
Nonzero, wenn keine Speicherfehler; andernfalls 0.
Hinweise
Wenn die Funktion keine Speicherbeschädigung erkennt, wird nichts ausgegeben.
Alle derzeit für den Heap zugewiesenen Speicherblöcke werden überprüft, einschließlich derjenigen, die durch new
direkte Aufrufe an zugrunde liegende Speicherverteiler zugewiesen werden, z. B. die Fehlerhafte Funktion oder die GlobalAlloc
Windows-Funktion. Wenn ein Block beschädigt ist, wird eine Meldung in die Debuggerausgabe gedruckt.
Wenn Sie die Zeile einschließen
#define new DEBUG_NEW
in einem Programmmodul, dann nachfolgende Aufrufe, um AfxCheckMemory
den Dateinamen und die Zeilennummer anzuzeigen, in der der Speicher zugewiesen wurde.
Hinweis
Wenn Ihr Modul eine oder mehrere Implementierungen serialisierbarer Klassen enthält, müssen Sie die #define
Zeile nach dem letzten IMPLEMENT_SERIAL Makroaufruf platzieren.
Diese Funktion funktioniert nur in der Debugversion von MFC.
Beispiel
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();
Anforderungen
Header: afx.h
AfxDump (MFC)
Rufen Sie diese Funktion im Debugger auf, um den Zustand eines Objekts beim Debuggen abzubilden.
void AfxDump(const CObject* pOb);
Parameter
Pob
Ein Zeiger auf ein Objekt einer klasse, die von CObject
.
Hinweise
AfxDump
ruft die Memberfunktion eines Objekts Dump
auf und sendet die Informationen an die durch die afxDump
Variable angegebene Position. AfxDump
ist nur in der Debugversion von MFC verfügbar.
Ihr Programmcode sollte nicht aufgerufen AfxDump
werden, sondern stattdessen die Dump
Memberfunktion des entsprechenden Objekts aufrufen.
Anforderungen
Header: afx.h
AfxDumpStack
Diese globale Funktion kann verwendet werden, um ein Bild des aktuellen Stapels zu generieren.
void AFXAPI AfxDumpStack(DWORD dwTarget = AFX_STACK_DUMP_TARGET_DEFAULT);
Parameter
dwTarget
Gibt das Ziel der Dumpausgabe an. Mögliche Werte, die mit dem Bitweise-OR(|
)-Operator kombiniert werden können, sind wie folgt:
AFX_STACK_DUMP_TARGET_TRACE Sendet die Ausgabe mithilfe des TRACE-Makros . Das TRACE-Makro generiert nur Ausgabe in Debugbuilds; es generiert keine Ausgabe in Releasebuilds. Außerdem kann TRACE neben dem Debugger an andere Ziele umgeleitet werden.
AFX_STACK_DUMP_TARGET_DEFAULT Sendet die Dumpausgabe an das Standardziel. Bei einem Debugbuild wechselt die Ausgabe zum TRACE-Makro. In einem Releasebuild wechselt die Ausgabe in die Zwischenablage.
AFX_STACK_DUMP_TARGET_CLIPBOARD Sendet nur die Ausgabe an die Zwischenablage. Die Daten werden in der Zwischenablage als Nur-Text mithilfe des CF_TEXT-Zwischenablageformats platziert.
AFX_STACK_DUMP_TARGET_BOTH sendet die Ausgabe in die Zwischenablage und an das TRACE-Makro gleichzeitig.
AFX_STACK_DUMP_TARGET_ODS Sendet die Ausgabe direkt über die Win32-Funktion
OutputDebugString()
an den Debugger. Mit dieser Option wird die Debuggerausgabe sowohl in Debug- als auch in Releasebuilds generiert, wenn ein Debugger an den Prozess angefügt ist. AFX_STACK_DUMP_TARGET_ODS den Debugger immer erreicht (wenn er angefügt ist) und kann nicht umgeleitet werden.
Hinweise
Das folgende Beispiel spiegelt eine einzelne Zeile der Ausgabe wider, die aus dem Aufrufen AfxDumpStack
eines Schaltflächenhandlers in einer MFC-Dialoganwendung generiert wird:
=== 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 ===
Jede Zeile in der obigen Ausgabe gibt die Adresse des letzten Funktionsaufrufs, den vollständigen Pfadnamen des Moduls an, das den Funktionsaufruf enthält, und den aufgerufenen Funktionsprototyp. Wenn der Funktionsaufruf im Stapel nicht an der genauen Adresse der Funktion erfolgt, wird ein Offset von Bytes angezeigt.
In der folgenden Tabelle wird beispielsweise die erste Zeile der obigen Ausgabe beschrieben:
Output | Beschreibung |
---|---|
00427D55: |
Die Absenderadresse des letzten Funktionsaufrufs. |
DUMP2\DEBUG\DUMP2.EXE! |
Der vollständige Pfadname des Moduls, das den Funktionsaufruf enthält. |
void AfxDumpStack(unsigned long) |
Der Funktionsprototyp wird aufgerufen. |
+ 181 bytes |
Der Offset in Byte von der Adresse des Funktionsprototyps (in diesem Fallvoid AfxDumpStack(unsigned long) ) zur Absenderadresse (in diesem Fall). 00427D55 |
AfxDumpStack
ist in Debug- und Nichtfehlerversionen der MFC-Bibliotheken verfügbar; Die Funktion ist jedoch immer statisch verknüpft, auch wenn ihre ausführbare Datei MFC in einer freigegebenen DLL verwendet. In Implementierungen der freigegebenen Bibliothek befindet sich die Funktion im MFCS42. LIB-Bibliothek (und deren Varianten).
So verwenden Sie diese Funktion erfolgreich:
Die Datei IMAGEHLP.DLL muss sich auf Ihrem Pfad befinden. Wenn Sie nicht über diese DLL verfügen, zeigt die Funktion eine Fehlermeldung an. Informationen zu dem von IMAGEHLP bereitgestellten Funktionssatz finden Sie in der Bildhilfebibliothek .
Die Module mit Frames im Stapel müssen Debuginformationen enthalten. Wenn sie keine Debuginformationen enthalten, generiert die Funktion weiterhin eine Stapelablaufverfolgung, die Ablaufverfolgung ist jedoch weniger detailliert.
Anforderungen
Header: afx.h
AfxEnableMemoryLeakDump
Aktiviert und deaktiviert das Speicherleckabbild im AFX_DEBUG_STATE Destruktor.
BOOL AFXAPI AfxEnableMemoryLeakDump(BOOL bDump);
Parameter
bDump
[in] TRUE gibt an, dass das Speicherleckabbild aktiviert ist; FALSE gibt an, dass das Speicherleckabbild deaktiviert ist.
Rückgabewert
Der vorherige Wert für dieses Flag.
Hinweise
Wenn eine Anwendung die MFC-Bibliothek entlädt, führt die MFC-Bibliothek eine Überprüfung auf Speicherverluste aus. An diesem Punkt werden alle Speicherverluste über das Debugfenster von Visual Studio an den Benutzer gemeldet.
Wenn Ihre Anwendung eine andere Bibliothek vor der MFC-Bibliothek lädt, werden einige Speicherbelegungen in dieser Bibliothek fälschlicherweise als Arbeitsspeicherverluste gemeldet. Wegen Arbeitsspeicherverlusten, die eigentlich keine sind, wird Ihre Anwendung möglicherweise langsam beendet, da die MFC-Bibliothek die Speicherverluste meldet. Verwenden Sie in diesem Fall AfxEnableMemoryLeakDump
, um das Speicherabbild des Arbeitsspeicherverlusts zu deaktivieren.
Hinweis
Wenn Sie diese Methode verwenden, um das Speicherabbild des Arbeitsspeicherverlusts deaktivieren, erhalten Sie keine Berichte über tatsächliche Arbeitsspeicherverluste in Ihrer Anwendung. Sie sollten diese Methode nur verwenden, wenn Sie sicher sind, dass der Bericht über die Arbeitsspeicherverluste falsche Meldungen enthält.
Anforderungen
Header: afx.h
AfxEnableMemoryTracking
Die Diagnosespeicherverfolgung ist normalerweise in der Debugversion von MFC aktiviert.
BOOL AfxEnableMemoryTracking(BOOL bTrack);
Parameter
bTrack
Durch Festlegen dieses Werts auf TRUE wird die Speichernachverfolgung aktiviert. FALSE deaktiviert sie.
Rückgabewert
Die vorherige Einstellung des Flags für die Nachverfolgungsaktivierung.
Hinweise
Verwenden Sie diese Funktion, um die Nachverfolgung in Abschnitten Ihres Codes zu deaktivieren, von denen Sie wissen, dass Blöcke ordnungsgemäß zugeordnet sind.
Weitere Informationen AfxEnableMemoryTracking
finden Sie unter Debuggen von MFC-Anwendungen.
Hinweis
Diese Funktion funktioniert nur in der Debugversion von MFC.
Beispiel
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;
}
Anforderungen
Header: afx.h
AfxIsMemoryBlock
Testet eine Speicheradresse, um sicherzustellen, dass sie einen aktuell aktiven Speicherblock darstellt, der von der Diagnoseversion new
zugewiesen wurde.
BOOL AfxIsMemoryBlock(
const void* p,
UINT nBytes,
LONG* plRequestNumber = NULL);
Parameter
p
Verweist auf den speicherblock, der getestet werden soll.
nBytes
Enthält die Länge des Speicherblocks in Bytes.
plRequestNumber
Verweist auf eine long
ganze Zahl, die mit der Zuordnungssequenznummer des Speicherblocks gefüllt wird, oder null, wenn er keinen aktuell aktiven Speicherblock darstellt.
Rückgabewert
Nonzero, wenn der Speicherblock zurzeit zugewiesen ist und die Länge korrekt ist; andernfalls 0.
Hinweise
Außerdem wird die angegebene Größe anhand der ursprünglich zugewiesenen Größe überprüft. Wenn die Funktion nonzero zurückgibt, wird die Zuordnungssequenznummer in plRequestNumber zurückgegeben. Diese Zahl stellt die Reihenfolge dar, in der der Block relativ zu allen anderen new
Zuordnungen zugeordnet wurde.
Beispiel
CAge* pcage = new CAge(21); // CAge is derived from CObject.
ASSERT(AfxIsMemoryBlock(pcage, sizeof(CAge)));
Anforderungen
Header: afx.h
AfxIsValidAddress
Testet alle Speicheradressen, um sicherzustellen, dass sie vollständig im Arbeitsspeicher des Programms enthalten ist.
BOOL AfxIsValidAddress(
const void* lp,
UINT nBytes,
BOOL bReadWrite = TRUE);
Parameter
Lp
Verweist auf die zu testende Speicheradresse.
nBytes
Enthält die Anzahl der zu testenden Bytes des Arbeitsspeichers.
bReadWrite
Gibt an, ob der Speicher sowohl für das Lesen als auch für das Schreiben (TRUE) oder nur für das Lesen (FALSE) bestimmt ist.
Rückgabewert
In Debugbuilds ist nonzero, wenn der angegebene Speicherblock vollständig im Arbeitsspeicher des Programms enthalten ist; andernfalls 0.
In Nicht-Debug-Builds ist nonzero, wenn lp nicht NULL ist; andernfalls 0.
Hinweise
Die Adresse ist nicht auf Blöcke beschränkt, die von new
.
Beispiel
// 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));
Anforderungen
Header: afx.h
AfxIsValidString
Verwenden Sie diese Funktion, um zu bestimmen, ob ein Zeiger auf eine Zeichenfolge gültig ist.
BOOL AfxIsValidString(
LPCSTR lpsz,
int nLength = -1);
Parameter
lpsz
Der zu testende Zeiger.
nLength
Gibt die Länge der zu testenden Zeichenfolge in Bytes an. Ein Wert von -1 gibt an, dass die Zeichenfolge null-beendet wird.
Rückgabewert
In Debugbuilds ist nonzero, wenn der angegebene Zeiger auf eine Zeichenfolge der angegebenen Größe zeigt; andernfalls 0.
In nicht-debug builds, nonzero if lpsz is not NULL; otherwise 0.
Beispiel
// 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));
Anforderungen
Header: afx.h
AfxSetAllocHook
Legt einen Hook fest, der das Aufrufen der angegebenen Funktion ermöglicht, bevor jeder Speicherblock zugewiesen wird.
AFX_ALLOC_HOOK AfxSetAllocHook(AFX_ALLOC_HOOK pfnAllocHook);
Parameter
pfnAllocHook
Gibt den Namen der funktion an, die aufgerufen werden soll. Informationen zum Prototyp einer Zuordnungsfunktion finden Sie in den Hinweisen.
Rückgabewert
Nonzero, wenn Sie die Zuweisung zulassen möchten; andernfalls 0.
Hinweise
Der Debugspeicher-Allocator der Microsoft Foundation-Klassenbibliothek kann eine benutzerdefinierte Hook-Funktion aufrufen, damit der Benutzer eine Speicherzuweisung überwachen und steuern kann, ob die Zuordnung zulässig ist. Zuordnungshakenfunktionen werden wie folgt prototypiert:
BOOL AFXAPI AllocHook( size_t nSize
, BOOLbObject
, LONG ); lRequestNumber
nSize
Die Größe der vorgeschlagenen Speicherzuweisung.
bObject
TRUE, wenn die Zuordnung für ein -abgeleitetes CObject
Objekt gilt; andernfalls FALSE.
lRequestNumber
Die Sequenznummer der Speicherzuordnung.
Beachten Sie, dass die AFXAPI-Aufrufkonvention impliziert, dass der Angerufene die Parameter aus dem Stapel entfernen muss.
Anforderungen
Header: afx.h
AfxDoForAllClasses
Ruft die angegebene Iterationsfunktion für alle serialisierbaren CObject
abgeleiteten Klassen im Arbeitsspeicher der Anwendung auf.
void
AFXAPI AfxDoForAllClasses(
void (* pfn)(const CRuntimeClass* pClass, void* pContext),
void* pContext);
Parameter
pfn
Verweist auf eine Iterationsfunktion, die für jede Klasse aufgerufen werden soll. Die Funktionsargumente sind ein Zeiger auf ein CRuntimeClass
Objekt und ein leerer Zeiger auf zusätzliche Daten, die der Aufrufer der Funktion bereitstellt.
pContext
Verweist auf optionale Daten, die der Aufrufer der Iterationsfunktion bereitstellen kann. Dieser Zeiger kann NULL sein.
Hinweise
Serialisierbare CObject
abgeleitete Klassen sind Klassen, die mithilfe des DECLARE_SERIAL-Makros abgeleitet werden. Der Zeiger, der AfxDoForAllClasses
in pContext übergeben wird, wird bei jedem Aufruf an die angegebene Iterationsfunktion übergeben.
Hinweis
Diese Funktion funktioniert nur in der Debugversion von MFC.
Beispiel
#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
Anforderungen
Header: afx.h
AfxDoForAllObjects
Führt die angegebene Iterationsfunktion für alle Objekte aus, die zugeordnet CObject
wurden new
.
void AfxDoForAllObjects(
void (* pfn)(CObject* pObject, void* pContext),
void* pContext);
Parameter
pfn
Verweist auf eine Iterationsfunktion, die für jedes Objekt ausgeführt werden soll. Die Funktionsargumente sind ein Zeiger auf einen CObject
und ein leerer Zeiger auf zusätzliche Daten, die der Aufrufer der Funktion bereitstellt.
pContext
Verweist auf optionale Daten, die der Aufrufer der Iterationsfunktion bereitstellen kann. Dieser Zeiger kann NULL sein.
Hinweise
Stapel-, globale oder eingebettete Objekte werden nicht aufgezählt. Der in pContext übergebene AfxDoForAllObjects
Zeiger wird bei jedem Aufruf an die angegebene Iterationsfunktion übergeben.
Hinweis
Diese Funktion funktioniert nur in der Debugversion von MFC.
Beispiel
#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