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 |
---|---|
TWIERDZIĆ | 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 CObject klasy . |
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. |
ŚLAD | Zapewnia printf funkcję podobną do funkcji w wersji debugowania biblioteki. |
ZWERYFIKOWAĆ | 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 CObject klasach pochodnych, które obsługują sprawdzanie typów w czasie wykonywania. |
AfxDoForAllObjects | Wykonuje określoną funkcję na wszystkich CObject obiektach pochodnych, które zostały przydzielone za pomocą new polecenia . |
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
TWIERDZIĆ
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
nazwa klasy
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
ZWERYFIKOWAĆ
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 afxDump
programu , 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 CObject
klasy .
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ć AfxDump
metody , 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łaniaAfxCheckMemory
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 CObject
klasy .
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ć AfxDump
metody , 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:
Wyjście | 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 AfxEnableMemoryTracking
programu , 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ę new
diagnostyczną 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 new
program .
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_t nSize
, 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ą CObject
serializacji 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ą new
polecenia .
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