Udostępnij za pośrednictwem


Usługi diagnostyczne

Biblioteka klas programu Microsoft Foundation udostępnia wiele usług diagnostycznych, które ułatwiają debugowanie programów. Te usługi diagnostyczne obejmują makra i funkcje globalne, które umożliwiają śledzenie alokacji pamięci programu, zrzut zawartości obiektów w czasie wykonywania i drukowanie komunikatów debugowania w czasie wykonywania. Makra i funkcje globalne dla usług diagnostycznych są pogrupowane w następujące kategorie:

  • Ogólne makra diagnostyczne

  • Ogólne funkcje diagnostyczne i zmienne

  • Funkcje diagnostyczne obiektu

Te makra i funkcje są dostępne dla wszystkich klas pochodzących z CObject wersji debugowania i wydania MFC. Jednak wszystkie z wyjątkiem DEBUG_NEW i VERIFY nic nie robią w wersji wydania.

W bibliotece debugowania wszystkie przydzielone bloki pamięci są w nawiasach z serią "bajtów chronionych". Jeśli te bajty są zakłócone przez błędne zapisy pamięci, procedury diagnostyczne mogą zgłosić problem. Jeśli dołączysz wiersz:

#define new DEBUG_NEW

w pliku implementacji wszystkie wywołania programu będą przechowywać new nazwę pliku i numer wiersza, w którym odbywała się alokacja pamięci. Funkcja CMemoryState::D umpAllObjectsSince wyświetli dodatkowe informacje, co pozwoli zidentyfikować przecieki pamięci. Zapoznaj się również z klasą CDumpContext , aby uzyskać dodatkowe informacje na temat danych wyjściowych diagnostyki.

Ponadto biblioteka języka C w czasie wykonywania obsługuje również zestaw funkcji diagnostycznych, których można użyć do debugowania aplikacji. Aby uzyskać więcej informacji, zobacz Procedury debugowania w dokumentacji biblioteki czasu wykonywania.

Ogólne makra diagnostyczne MFC

Nazwa/nazwisko opis
ASSERT Drukuje komunikat, a następnie przerywa program, jeśli określone wyrażenie zwróci wartość FALSE w wersji debugowania biblioteki.
ASSERT_KINDOF Sprawdza, czy obiekt jest obiektem określonej klasy lub klasy pochodzącej z określonej klasy.
ASSERT_VALID Sprawdza wewnętrzną ważność obiektu, wywołując jego AssertValid funkcję składową; zazwyczaj zastępowana z CObjectklasy .
DEBUG_NEW Dostarcza nazwę pliku i numer wiersza dla wszystkich alokacji obiektów w trybie debugowania, aby ułatwić znalezienie przecieków pamięci.
DEBUG_ONLY Podobnie jak funkcja ASSERT, ale nie testuje wartości wyrażenia; przydatne w przypadku kodu, który powinien być wykonywany tylko w trybie debugowania.
ZAPEWNIANIE I ENSURE_VALID Użyj polecenia , aby zweryfikować poprawność danych.
THIS_FILE Rozwija się do nazwy kompilowanego pliku.
ŚLEDZENIA Zapewnia printffunkcję podobną do funkcji w wersji debugowania biblioteki.
SPRAWDŹ Podobnie jak funkcja ASSERT, ale oblicza wyrażenie w wersji release biblioteki, a także w wersji debugowania.

Ogólne zmienne diagnostyczne i funkcje MFC

Nazwa/nazwisko opis
afxDump Zmienna globalna, która wysyła informacje CDumpContext do okna danych wyjściowych debugera lub do terminalu debugowania.
Afxmemdf Zmienna globalna, która kontroluje zachowanie alokatora pamięci debugowania.
AfxCheckError Zmienna globalna używana do testowania przekazanego kodu SCODE w celu sprawdzenia, czy jest to błąd, a jeśli tak, zgłasza odpowiedni błąd.
AfxCheckMemory Sprawdza integralność wszystkich aktualnie przydzielonych pamięci.
AfxDebugBreak Powoduje przerwanie wykonywania.
AfxDump Jeśli jest wywoływana podczas debugera, zrzutuje stan obiektu podczas debugowania.
AfxDump Funkcja wewnętrzna, która zrzutuje stan obiektu podczas debugowania.
AfxDumpStack Wygeneruj obraz bieżącego stosu. Ta funkcja jest zawsze połączona statycznie.
AfxEnableMemoryLeakDump Włącza zrzut wycieku pamięci.
AfxEnableMemoryTracking Włącza i wyłącza śledzenie pamięci.
AfxIsMemoryBlock Sprawdza, czy blok pamięci został prawidłowo przydzielony.
AfxIsValidAddress Sprawdza, czy zakres adresów pamięci znajduje się w granicach programu.
AfxIsValidString Określa, czy wskaźnik do ciągu jest prawidłowy.
AfxSetAllocHook Umożliwia wywoływanie funkcji w każdej alokacji pamięci.

Funkcje diagnostyczne obiektów MFC

Nazwa/nazwisko opis
AfxDoForAllClasses Wykonuje określoną funkcję we wszystkich CObjectklasach pochodnych, które obsługują sprawdzanie typów w czasie wykonywania.
AfxDoForAllObjects Wykonuje określoną funkcję na wszystkich CObjectobiektach pochodnych, które zostały przydzielone za pomocą newpolecenia .

Makra kompilacji MFC

Nazwa/nazwisko opis
_AFX_SECURE_NO_WARNINGS Pomija ostrzeżenia kompilatora dotyczące używania przestarzałych funkcji MFC.

_AFX_SECURE_NO_WARNINGS

Pomija ostrzeżenia kompilatora dotyczące używania przestarzałych funkcji MFC.

Składnia

_AFX_SECURE_NO_WARNINGS

Przykład

Ten przykładowy kod powoduje ostrzeżenie kompilatora, jeśli _AFX_SECURE_NO_WARNINGS nie jest zdefiniowane.

// 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

Wywołaj tę funkcję, aby spowodować przerwanie (w lokalizacji wywołania metody AfxDebugBreak) w wykonaniu wersji debugowania aplikacji MFC.

Składnia

void AfxDebugBreak( );

Uwagi

AfxDebugBreak nie ma wpływu na wersje wydania aplikacji MFC i należy je usunąć. Ta funkcja powinna być używana tylko w aplikacjach MFC. Użyj wersji interfejsu API Win32, DebugBreak, aby spowodować przerwę w aplikacjach innych niż MFC.

Wymagania

Nagłówek: afxver_.h

ASSERT

Ocenia jego argument.

ASSERT(booleanExpression)

Parametry

wartość logicznaExpression
Określa wyrażenie (w tym wartości wskaźnika), które daje wartość niezerową lub 0.

Uwagi

Jeśli wynik wynosi 0, makro wyświetla komunikat diagnostyczny i przerywa program. Jeśli warunek jest niezerowy, nie robi nic.

Komunikat diagnostyczny ma formularz

assertion failed in file <name> in line <num>

gdzie nazwa jest nazwą pliku źródłowego, a num jest numerem wiersza potwierdzenia, które nie powiodło się w pliku źródłowym.

W wersji wydania MFC funkcja ASSERT nie ocenia wyrażenia i w związku z tym nie przerywa programu. Jeśli wyrażenie musi być oceniane niezależnie od środowiska, użyj makra VERIFY zamiast funkcji ASSERT.

Uwaga

Ta funkcja jest dostępna tylko w wersji debugowania MFC.

Przykład

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*.   

Wymagania

Nagłówek: afx.h

ASSERT_KINDOF

To makro potwierdza, że obiekt wskazywany jest obiektem określonej klasy lub jest obiektem klasy pochodzącej z określonej klasy.

ASSERT_KINDOF(classname, pobject)

Parametry

Classname
Nazwa klasy pochodnej CObject.

Pobject
Wskaźnik do obiektu klasy.

Uwagi

Parametr pobject powinien być wskaźnikiem do obiektu i może być const. Obiekt wskazywany i klasa musi obsługiwać CObject informacje o klasie czasu wykonywania. Na przykład, aby upewnić się, że pDocument jest wskaźnikiem do obiektu CMyDoc klasy lub któregokolwiek z jego pochodnych, możesz kodować:

ASSERT_KINDOF(CMyDoc, pDocument);

Użycie makra ASSERT_KINDOF jest dokładnie takie samo jak kodowanie:

ASSERT(pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)));

Ta funkcja działa tylko dla klas zadeklarowanych za pomocą makra [DECLARE_DYNAMIC](run-time-object-model-services.md#declare_dynamic lub DECLARE_SERIAL makra.

Uwaga

Ta funkcja jest dostępna tylko w wersji debugowania MFC.

Wymagania

Nagłówek: afx.h

ASSERT_VALID

Służy do testowania założeń dotyczących ważności stanu wewnętrznego obiektu.

ASSERT_VALID(pObject)

Parametry

Pobject
Określa obiekt klasy pochodzącej z CObject klasy, która ma zastępowającą wersję funkcji składowej AssertValid .

Uwagi

ASSERT_VALID wywołuje AssertValid funkcję składową obiektu przekazanego jako argument.

W wersji wydania MFC ASSERT_VALID nic nie robi. W wersji debugowania sprawdza wskaźnik, sprawdza wartość NULL i wywołuje własne AssertValid funkcje członkowskie obiektu. Jeśli którykolwiek z tych testów zakończy się niepowodzeniem, zostanie wyświetlony komunikat alertu w taki sam sposób jak ASSERT.

Uwaga

Ta funkcja jest dostępna tylko w wersji debugowania MFC.

Aby uzyskać więcej informacji i przykładów, zobacz Debugowanie aplikacji MFC.

Przykład

// Assure that pMyObject is a valid pointer to an
// object derived from CObject.
ASSERT_VALID(pMyObject);

Wymagania

Nagłówek: afx.h

DEBUG_NEW

Pomaga w znalezieniu przecieków pamięci.

#define  new DEBUG_NEW

Uwagi

Możesz użyć DEBUG_NEW wszędzie w programie, który zwykle używa new operatora do przydzielania magazynu stertowego.

W trybie debugowania (po zdefiniowaniu symbolu _DEBUG ) DEBUG_NEW śledzi nazwę pliku i numer wiersza dla każdego przydzielanego obiektu. Następnie, gdy używasz funkcji składowej CMemoryState::D umpAllObjectsSince , każdy obiekt przydzielony DEBUG_NEW jest wyświetlany z nazwą pliku i numerem wiersza, w którym został przydzielony.

Aby użyć DEBUG_NEW, wstaw następującą dyrektywę do plików źródłowych:

#define new DEBUG_NEW

Po wstawieniu tej dyrektywy preprocesor wstawi DEBUG_NEW wszędzie tam, gdzie jest używana new, a MFC wykonuje resztę. Podczas kompilowania wersji programu DEBUG_NEW rozpoznaje prostą new operację, a informacje o nazwie pliku i numerze wiersza nie są generowane.

Uwaga

W poprzednich wersjach MFC (4.1 i starszych) trzeba było umieścić instrukcję #define po wszystkich instrukcjach, które nazwały makra IMPLEMENT_DYNCREATE lub IMPLEMENT_SERIAL. Te ustawienia nie są już obsługiwane.

Wymagania

Nagłówek: afx.h

DEBUG_ONLY

W trybie debugowania (po zdefiniowaniu symbolu _DEBUG ) DEBUG_ONLY oblicza jego argument.

DEBUG_ONLY(expression)

Uwagi

W kompilacji wydania DEBUG_ONLY nie ocenia argumentu. Jest to przydatne, gdy masz kod, który powinien być wykonywany tylko w kompilacjach debugowania.

Makro DEBUG_ONLY jest równoważne otaczającemu wyrażeniu z elementami #ifdef _DEBUG i #endif.

Przykład

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');
}

Wymagania

Nagłówek: afx.h

ZAPEWNIANIE I ENSURE_VALID

Użyj polecenia , aby zweryfikować poprawność danych.

Składnia

ENSURE(  booleanExpression )
ENSURE_VALID( booleanExpression  )

Parametry

wartość logicznaExpression
Określa wyrażenie logiczne do przetestowania.

Uwagi

Celem tych makr jest ulepszenie weryfikacji parametrów. Makra uniemożliwiają dalsze przetwarzanie nieprawidłowych parametrów w kodzie. W przeciwieństwie do makr ASSERT makra ENSURE zgłaszają wyjątek oprócz generowania asercji.

Makra zachowują się na dwa sposoby zgodnie z konfiguracją projektu. Makra wywołają funkcję ASSERT, a następnie zgłaszają wyjątek, jeśli potwierdzenie zakończy się niepowodzeniem. W związku z tym w konfiguracjach debugowania (czyli w przypadku, gdy _DEBUG jest definiowana) makra generują asercji i wyjątku, podczas gdy w konfiguracjach wydania makra generują tylko wyjątek (ASSERT nie ocenia wyrażenia w konfiguracjach wydania).

Makro ENSURE_ARG działa jak makro ENSURE.

ENSURE_VALID wywołuje makro ASSERT_VALID (które ma wpływ tylko w kompilacjach debugowania). Ponadto ENSURE_VALID zgłasza wyjątek, jeśli wskaźnik ma wartość NULL. Test null jest wykonywany zarówno w konfiguracjach debugowania, jak i wydania.

Jeśli którykolwiek z tych testów zakończy się niepowodzeniem, zostanie wyświetlony komunikat alertu w taki sam sposób jak ASSERT. W razie potrzeby makro zgłasza nieprawidłowy wyjątek argumentu.

Wymagania

Nagłówek: afx.h

THIS_FILE

Rozwija się do nazwy kompilowanego pliku.

Składnia

THIS_FILE

Uwagi

Te informacje są używane przez makra ASSERT i VERIFY. Kreator aplikacji i kreatory kodu umieszczają makro w tworzonych plikach kodu źródłowego.

Przykład

#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.

Wymagania

Nagłówek: afx.h

TRACE

Wysyła określony ciąg do debugera bieżącej aplikacji.

TRACE(exp)
TRACE(DWORD  category,  UINT  level, LPCSTR lpszFormat, ...)

Uwagi

Aby uzyskać opis funkcji TRACE, zobacz ATLTRACE2 . Funkcja TRACE i ATLTRACE2 mają takie samo zachowanie.

W wersji debugowania MFC to makro wysyła określony ciąg do debugera bieżącej aplikacji. W kompilacji wydania to makro kompiluje się do niczego (w ogóle nie jest generowany kod).

Aby uzyskać więcej informacji, zobacz Debugowanie aplikacji MFC.

Wymagania

Nagłówek: afx.h

SPRAWDŹ

W wersji debugowania MFC ocenia swój argument.

VERIFY(booleanExpression)

Parametry

wartość logicznaExpression
Określa wyrażenie (w tym wartości wskaźnika), które daje wartość niezerową lub 0.

Uwagi

Jeśli wynik wynosi 0, makro wyświetla komunikat diagnostyczny i zatrzymuje program. Jeśli warunek jest niezerowy, nie robi nic.

Komunikat diagnostyczny ma formularz

assertion failed in file <name> in line <num>

gdzie nazwa to nazwa pliku źródłowego, a liczba to numer wiersza potwierdzenia, który zakończył się niepowodzeniem w pliku źródłowym.

W wersji wydania MFC funkcja VERIFY ocenia wyrażenie, ale nie wyświetla ani nie przerywa działania programu. Jeśli na przykład wyrażenie jest wywołaniem funkcji, wywołanie zostanie wykonane.

Przykład

// 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);

Wymagania

Nagłówek: afx.h

afxDump (CDumpContext w MFC)

Zapewnia podstawową możliwość dumpingu obiektów w aplikacji.

CDumpContext  afxDump;

Uwagi

afxDump to wstępnie zdefiniowany obiekt CDumpContext , który umożliwia wysyłanie CDumpContext informacji do okna danych wyjściowych debugera lub do terminalu debugowania. Zazwyczaj należy podać afxDump jako parametr .CObject::Dump

W obszarze Windows NT i wszystkich wersji systemu Windows afxDump dane wyjściowe są wysyłane do okna Output-Debug programu Visual C++ podczas debugowania aplikacji.

Ta zmienna jest definiowana tylko w wersji debugowania MFC. Aby uzyskać więcej informacji na temat afxDumpprogramu , zobacz Debugowanie aplikacji MFC.

Przykład

// 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

Wymagania

Nagłówek: afx.h

AfxDump (wewnętrzny)

Funkcja wewnętrzna używana przez MFC do zrzutu stanu obiektu podczas debugowania.

Składnia

void AfxDump(const CObject* pOb);

Parametry

Pob
Wskaźnik do obiektu klasy pochodzącej z CObjectklasy .

Uwagi

AfxDump wywołuje funkcję składową obiektu Dump i wysyła informacje do lokalizacji określonej przez zmienną afxDump . AfxDump jest dostępny tylko w wersji debugowania MFC.

Kod programu nie powinien wywoływać AfxDumpmetody , ale zamiast tego powinien wywołać Dump funkcję składową odpowiedniego obiektu.

Wymagania

Nagłówek: afx.h

Afxmemdf

Ta zmienna jest dostępna z debugera lub programu i umożliwia dostosowanie diagnostyki alokacji.

int  afxMemDF;

Uwagi

afxMemDF może mieć następujące wartości określone przez wyliczenie afxMemDF:

  • allocMemDF Włącza alokator debugowania (ustawienie domyślne w bibliotece debugowania).

  • delayFreeMemDF Opóźnia zwalnianie pamięci. Podczas gdy program zwalnia blok pamięci, alokator nie zwraca tej pamięci do bazowego systemu operacyjnego. Spowoduje to maksymalne obciążenie pamięci w programie.

  • checkAlwaysMemDF Wywołania AfxCheckMemory za każdym razem, gdy pamięć jest przydzielana lub zwalniana. Spowoduje to znaczne spowolnienie alokacji pamięci i cofania przydziałów.

Przykład

afxMemDF = allocMemDF | checkAlwaysMemDF;

Wymagania

Nagłówek: afx.h

AfxCheckError

Ta funkcja testuje przekazany kod SCODE, aby sprawdzić, czy jest to błąd.

void AFXAPI AfxCheckError(SCODE sc);
throw CMemoryException*
throw COleException*

Uwagi

Jeśli wystąpi błąd, funkcja zgłasza wyjątek. Jeśli przekazany kod SCODE jest E_OUTOFMEMORY, funkcja zgłasza wyjątek CMemoryException przez wywołanie AfxThrowMemoryException. W przeciwnym razie funkcja zgłasza wyjątek COleException, wywołując wyjątek AfxThrowOleException.

Ta funkcja może służyć do sprawdzania zwracanych wartości wywołań do funkcji OLE w aplikacji. Testując wartość zwracaną za pomocą tej funkcji w aplikacji, można prawidłowo reagować na warunki błędów przy użyciu minimalnej ilości kodu.

Uwaga

Ta funkcja ma taki sam efekt w kompilacjach debugowania i bez debugowania.

Przykład

AfxCheckError(::CoCreateInstance(clsidWMP, NULL, CLSCTX_INPROC_SERVER,
   IID_IDispatch, (LPVOID*)& pWMPDispatch));

oddWMP.AttachDispatch(pWMPDispatch, TRUE);

Wymagania

Nagłówek: afx.h

AfxCheckMemory

Ta funkcja weryfikuje bezpłatną pulę pamięci i wyświetla komunikaty o błędach zgodnie z potrzebami.

BOOL  AfxCheckMemory();

Wartość zwracana

Bezzerowe, jeśli nie występują błędy pamięci; w przeciwnym razie 0.

Uwagi

Jeśli funkcja nie wykryje uszkodzenia pamięci, nic nie wyświetla.

Wszystkie bloki pamięci przydzielone obecnie na stercie są sprawdzane, w tym te przydzielone przez, ale nie przydzielone przez new bezpośrednie wywołania do podstawowych alokatorów pamięci, takich jak funkcja malloc lub GlobalAlloc funkcja systemu Windows. Jeśli jakikolwiek blok zostanie uszkodzony, zostanie wyświetlony komunikat do danych wyjściowych debugera.

Jeśli dołączysz wiersz

#define new DEBUG_NEW

w module programu, a następnie kolejne wywołania, aby wyświetlić AfxCheckMemory nazwę pliku i numer wiersza, w którym przydzielono pamięć.

Uwaga

Jeśli moduł zawiera co najmniej jedną implementację klas możliwych do serializacji, należy umieścić #define wiersz po ostatnim wywołaniu makra IMPLEMENT_SERIAL.

Ta funkcja działa tylko w wersji debugowania MFC.

Przykład

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();

Wymagania

Nagłówek: afx.h

AfxDump (MFC)

Wywołaj tę funkcję podczas debugera, aby zrzucić stan obiektu podczas debugowania.

void AfxDump(const CObject* pOb);

Parametry

Pob
Wskaźnik do obiektu klasy pochodzącej z CObjectklasy .

Uwagi

AfxDump wywołuje funkcję składową obiektu Dump i wysyła informacje do lokalizacji określonej przez zmienną afxDump . AfxDump jest dostępny tylko w wersji debugowania MFC.

Kod programu nie powinien wywoływać AfxDumpmetody , ale zamiast tego powinien wywołać Dump funkcję składową odpowiedniego obiektu.

Wymagania

Nagłówek: afx.h

AfxDumpStack

Ta funkcja globalna może służyć do generowania obrazu bieżącego stosu.

void AFXAPI AfxDumpStack(DWORD dwTarget = AFX_STACK_DUMP_TARGET_DEFAULT);

Parametry

dwTarget
Wskazuje element docelowy danych wyjściowych zrzutu. Możliwe wartości, które można połączyć za pomocą operatora bitowego OR (|) są następujące:

  • AFX_STACK_DUMP_TARGET_TRACE Wysyła dane wyjściowe za pomocą makra TRACE . Makro TRACE generuje dane wyjściowe tylko w kompilacjach debugowania; nie generuje żadnych danych wyjściowych w kompilacjach wydania. Ponadto funkcja TRACE może być przekierowywana do innych obiektów docelowych oprócz debugera.

  • AFX_STACK_DUMP_TARGET_DEFAULT Wysyła dane wyjściowe zrzutu do domyślnego miejsca docelowego. W przypadku kompilacji debugowania dane wyjściowe są wyświetlane w makrze TRACE. W kompilacji wydania dane wyjściowe trafiają do Schowka.

  • AFX_STACK_DUMP_TARGET_CLIPBOARD Wysyła dane wyjściowe tylko do Schowka. Dane są umieszczane w Schowku jako zwykły tekst przy użyciu formatu schowka CF_TEXT.

  • AFX_STACK_DUMP_TARGET_BOTH Wysyła dane wyjściowe do Schowka i do makra TRACE, jednocześnie.

  • AFX_STACK_DUMP_TARGET_ODS Wysyła dane wyjściowe bezpośrednio do debugera za pomocą funkcji OutputDebugString()Win32 . Ta opcja spowoduje wygenerowanie danych wyjściowych debugera zarówno w kompilacjach debugowania, jak i wydania, gdy debuger jest dołączony do procesu. AFX_STACK_DUMP_TARGET_ODS zawsze dociera do debugera (jeśli jest dołączony) i nie można go przekierować.

Uwagi

Poniższy przykład odzwierciedla pojedynczy wiersz danych wyjściowych wygenerowanych z wywołania AfxDumpStack z programu obsługi przycisków w aplikacji dialogowej 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 ===

Każdy wiersz w danych wyjściowych powyżej wskazuje adres ostatniego wywołania funkcji, pełną nazwę ścieżki modułu zawierającego wywołanie funkcji i prototyp funkcji o nazwie. Jeśli wywołanie funkcji na stosie nie występuje pod dokładnym adresem funkcji, wyświetlane jest przesunięcie bajtów.

Na przykład w poniższej tabeli opisano pierwszy wiersz powyższych danych wyjściowych:

Dane wyjściowe opis
00427D55: Adres zwrotny ostatniego wywołania funkcji.
DUMP2\DEBUG\DUMP2.EXE! Pełna nazwa ścieżki modułu zawierającego wywołanie funkcji.
void AfxDumpStack(unsigned long) Prototyp funkcji o nazwie.
+ 181 bytes Przesunięcie w bajtach z adresu prototypu funkcji (w tym przypadku void AfxDumpStack(unsigned long)) na adres zwrotny (w tym przypadku 00427D55).

AfxDumpStack jest dostępny w wersjach debugowania i innych niż wersje bibliotek MFC; jednak funkcja jest zawsze połączona statycznie, nawet jeśli plik wykonywalny używa MFC w udostępnionej bibliotece DLL. W implementacjach bibliotek udostępnionych funkcja znajduje się w MFCS42. Biblioteka LIB (i jej warianty).

Aby pomyślnie użyć tej funkcji:

  • Plik IMAGEHLP.DLL musi znajdować się w ścieżce. Jeśli nie masz tej biblioteki DLL, funkcja wyświetli komunikat o błędzie. Aby uzyskać informacje na temat zestawu funkcji dostarczonego przez program IMAGEHLP, zobacz Biblioteka Pomocy obrazów.

  • Moduły, które mają ramki na stosie, muszą zawierać informacje debugowania. Jeśli nie zawierają informacji o debugowaniu, funkcja będzie nadal generować ślad stosu, ale ślad będzie mniej szczegółowy.

Wymagania

Nagłówek: afx.h

AfxEnableMemoryLeakDump

Włącza i wyłącza zrzut wycieku pamięci w destruktorze AFX_DEBUG_STATE.

BOOL AFXAPI AfxEnableMemoryLeakDump(BOOL bDump);

Parametry

bDump
[in] Wartość TRUE wskazuje, że zrzut wycieku pamięci jest włączony; FAŁSZ wskazuje, że zrzut wycieku pamięci jest wyłączony.

Wartość zwracana

Poprzednia wartość tej flagi.

Uwagi

Gdy aplikacja zwalnia bibliotekę MFC, biblioteka MFC sprawdza przecieki pamięci. W tym momencie wszelkie przecieki pamięci są zgłaszane użytkownikowi za pośrednictwem okna Debugowanie programu Visual Studio.

Jeśli aplikacja ładuje inną bibliotekę przed biblioteką MFC, niektóre alokacje pamięci w tej bibliotece będą niepoprawnie zgłaszane jako przecieki pamięci. Fałszywe przecieki pamięci mogą spowodować powolne zamknięcie aplikacji, ponieważ biblioteka MFC zgłasza je. W takim przypadku użyj polecenia AfxEnableMemoryLeakDump , aby wyłączyć zrzut wycieku pamięci.

Uwaga

Jeśli używasz tej metody do wyłączenia zrzutu przecieku pamięci, nie otrzymasz raportów o prawidłowych przeciekach pamięci w aplikacji. Tej metody należy używać tylko wtedy, gdy masz pewność, że raport przecieku pamięci zawiera fałszywe przecieki pamięci.

Wymagania

Nagłówek: afx.h

AfxEnableMemoryTracking

Śledzenie pamięci diagnostycznej jest zwykle włączone w wersji debugowania MFC.

BOOL AfxEnableMemoryTracking(BOOL bTrack);

Parametry

bTrack
Ustawienie tej wartości na WARTOŚĆ TRUE powoduje włączenie śledzenia pamięci; Wartość FALSE powoduje wyłączenie.

Wartość zwracana

Poprzednie ustawienie flagi włączania śledzenia.

Uwagi

Ta funkcja służy do wyłączania śledzenia sekcji kodu, które wiesz, że przydzielane bloki są poprawnie przydzielane.

Aby uzyskać więcej informacji na temat AfxEnableMemoryTrackingprogramu , zobacz Debugowanie aplikacji MFC.

Uwaga

Ta funkcja działa tylko w wersji debugowania MFC.

Przykład

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;
}

Wymagania

Nagłówek: afx.h

AfxIsMemoryBlock

Testuje adres pamięci, aby upewnić się, że reprezentuje obecnie aktywny blok pamięci przydzielony przez wersję newdiagnostyczną programu .

BOOL AfxIsMemoryBlock(
    const void* p,
    UINT nBytes,
    LONG* plRequestNumber = NULL);

Parametry

p
Wskazuje blok pamięci do przetestowania.

nBajty
Zawiera długość bloku pamięci w bajtach.

plRequestNumber
long Wskazuje liczbę całkowitą, która zostanie wypełniona numerem sekwencji alokacji bloku pamięci lub zero, jeśli nie reprezentuje obecnie aktywnego bloku pamięci.

Wartość zwracana

Niezerowe, jeśli blok pamięci jest obecnie przydzielony i długość jest poprawna; w przeciwnym razie 0.

Uwagi

Sprawdza również określony rozmiar względem oryginalnego przydzielonego rozmiaru. Jeśli funkcja zwraca wartość nonzero, numer sekwencji alokacji jest zwracany w pliku plRequestNumber. Ta liczba reprezentuje kolejność przydzielania bloku względem wszystkich innych new alokacji.

Przykład

CAge* pcage = new CAge(21); // CAge is derived from CObject.
ASSERT(AfxIsMemoryBlock(pcage, sizeof(CAge)));

Wymagania

Nagłówek: afx.h

AfxIsValidAddress

Sprawdza każdy adres pamięci, aby upewnić się, że jest on całkowicie zawarty w przestrzeni pamięci programu.

BOOL AfxIsValidAddress(
    const void* lp,
    UINT nBytes,
    BOOL bReadWrite = TRUE);

Parametry

Lp
Wskazuje adres pamięci do przetestowania.

nBajty
Zawiera liczbę bajtów pamięci do przetestowania.

bReadWrite
Określa, czy pamięć jest zarówno do odczytu, jak i zapisu (PRAWDA), czy po prostu odczyt (FALSE).

Wartość zwracana

W kompilacjach debugowania niezero, jeśli określony blok pamięci jest całkowicie zawarty w przestrzeni pamięci programu; w przeciwnym razie 0.

W kompilacjach innych niż debugowanie niezero, jeśli lp nie ma wartości NULL; w przeciwnym razie 0.

Uwagi

Adres nie jest ograniczony do bloków przydzielonych przez newprogram .

Przykład

// 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));

Wymagania

Nagłówek: afx.h

AfxIsValidString

Użyj tej funkcji, aby określić, czy wskaźnik do ciągu jest prawidłowy.

BOOL  AfxIsValidString(
    LPCSTR lpsz,
    int nLength = -1);

Parametry

lpsz
Wskaźnik do przetestowania.

nLength
Określa długość ciągu do przetestowania w bajtach. Wartość -1 wskazuje, że ciąg zostanie zakończony wartością null.

Wartość zwracana

W kompilacjach debugowania, nonzero, jeśli określony wskaźnik wskazuje ciąg określonego rozmiaru; w przeciwnym razie 0.

W kompilacjach innych niż debugowanie niezero, jeśli lpsz nie ma wartości NULL; w przeciwnym razie 0.

Przykład

// 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));

Wymagania

Nagłówek: afx.h

AfxSetAllocHook

Ustawia punkt zaczepienia, który umożliwia wywoływanie określonej funkcji przed przydzieleniu każdego bloku pamięci.

AFX_ALLOC_HOOK AfxSetAllocHook(AFX_ALLOC_HOOK pfnAllocHook);

Parametry

pfnAllocHook
Określa nazwę funkcji do wywołania. Zobacz uwagi dotyczące prototypu funkcji alokacji.

Wartość zwracana

Nonzero, jeśli chcesz zezwolić na alokację; w przeciwnym razie 0.

Uwagi

Alokator debugowania pamięci biblioteki klas programu Microsoft Foundation może wywołać funkcję punktu zaczepienia zdefiniowanego przez użytkownika, aby umożliwić użytkownikowi monitorowanie alokacji pamięci i kontrolowanie, czy alokacja jest dozwolona. Funkcje punktu zaczepienia alokacji są prototypowane w następujący sposób:

BOOL AFXAPI AllocHook( size_tnSize, BOOLbObject, LONG);lRequestNumber

nSize
Rozmiar proponowanej alokacji pamięci.

bObject
WARTOŚĆ TRUE, jeśli alokacja dotyczy obiektu pochodnego CObject; w przeciwnym razie WARTOŚĆ FALSE.

lRequestNumber
Numer sekwencji alokacji pamięci.

Należy pamiętać, że konwencja wywoływania AFXAPI oznacza, że obiekt wywoływany musi usunąć parametry ze stosu.

Wymagania

Nagłówek: afx.h

AfxDoForAllClasses

Wywołuje określoną funkcję iteracji dla wszystkich klas serializacji CObject-pochodnych w przestrzeni pamięci aplikacji.

void
AFXAPI AfxDoForAllClasses(
    void (* pfn)(const CRuntimeClass* pClass, void* pContext),
    void* pContext);

Parametry

Pfn
Wskazuje na funkcję iteracji, która ma być wywoływana dla każdej klasy. Argumenty funkcji są wskaźnikiem do CRuntimeClass obiektu i wskaźnikiem void do dodatkowych danych, które obiekt wywołujący dostarcza do funkcji.

Pcontext
Wskazuje na opcjonalne dane, które obiekt wywołujący może dostarczyć do funkcji iteracji. Ten wskaźnik może mieć wartość NULL.

Uwagi

Klasy pochodne z możliwością CObjectserializacji to klasy pochodne przy użyciu makra DECLARE_SERIAL. Wskaźnik przekazywany do AfxDoForAllClasses elementu pContext jest przekazywany do określonej funkcji iteracji za każdym razem, gdy jest wywoływany.

Uwaga

Ta funkcja działa tylko w wersji debugowania MFC.

Przykład

#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

Wymagania

Nagłówek: afx.h

AfxDoForAllObjects

Wykonuje określoną funkcję iteracji dla wszystkich obiektów pochodnych, CObject które zostały przydzielone za pomocą newpolecenia .

void AfxDoForAllObjects(
    void (* pfn)(CObject* pObject, void* pContext),
    void* pContext);

Parametry

Pfn
Wskazuje funkcję iteracji do wykonania dla każdego obiektu. Argumenty funkcji są wskaźnikiem do CObject wskaźnika i wskaźnika void do dodatkowych danych, które obiekt wywołujący dostarcza do funkcji.

Pcontext
Wskazuje na opcjonalne dane, które obiekt wywołujący może dostarczyć do funkcji iteracji. Ten wskaźnik może mieć wartość NULL.

Uwagi

Obiekty stosu, globalne lub osadzone nie są wyliczane. Wskaźnik przekazywany do AfxDoForAllObjects elementu pContext jest przekazywany do określonej funkcji iteracji za każdym razem, gdy jest wywoływany.

Uwaga

Ta funkcja działa tylko w wersji debugowania MFC.

Przykład

#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

Zobacz też

Makra i globalne
CObject::D ump