Freigeben über


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 CObjectauß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 CObjectabgeleiteten Klassen aus, die Typprüfung zur Laufzeit unterstützen.
AfxDoForAllObjects Führt eine angegebene Funktion für alle CObjectabgeleiteten Objekte aus, die zugeordnet newwurden.

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 AfxDebugBreakvon ) 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, DebugBreakum 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 CObjectabgeleiteten 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 afxDumpfinden 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 AfxDumpwerden, 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 afxMemDFangegeben:

  • 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 Anrufe AfxCheckMemory 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 AfxDumpwerden, 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 AfxEnableMemoryTrackingfinden 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 newzugewiesen 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 CObjectObjekt 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 CObjectabgeleiteten 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 CObjectabgeleitete 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

Siehe auch

Makros und Globalen
CObject::D ump