Servicios de diagnóstico
La biblioteca MFC (Microsoft Foundation Class) ofrece muchos servicios de diagnóstico que facilitan la depuración de los programas con mayor facilidad. Estos servicios de diagnóstico incluyen macros y funciones globales que le permiten realizar un seguimiento de las asignaciones de memoria de su programa, volcar el contenido de los objetos en tiempo de ejecución e imprimir mensajes de depuración en tiempo de ejecución. Las macros y funciones globales para servicios de diagnóstico se agrupan en las siguientes categorías:
Macros de diagnóstico generales
Funciones y variables de diagnóstico general
Funciones de diagnóstico de objetos
Estas macros y funciones están disponibles para todas las clases derivadas de CObject
en las versiones de lanzamiento y depuración de MFC. Pero todas excepto DEBUG_NEW y VERIFY no hacen nada en la versión de lanzamiento.
En la biblioteca de depuración, todos los bloques de memoria asignados están entre corchetes con una serie de "bytes de protección". Si una escritura de memoria errante afecta a estos bytes, las rutinas de diagnóstico pueden notificar un problema. Si incluye la línea:
#define new DEBUG_NEW
en el archivo de implementación, todas las llamadas a new
almacenarán el nombre de archivo y el número de línea en el que se realizó la asignación de memoria. La función CMemoryState::DumpAllObjectsSince mostrará esta información adicional, lo que le permitirá identificar fugas de memoria. Consulte también la clase CDumpContext para información adicional sobre el resultado de diagnóstico.
Además, la biblioteca de tiempo de ejecución de C también admite un conjunto de funciones de diagnóstico que puede usar para depurar sus aplicaciones. Para más información, vea Rutinas de depuración en la Referencia de la biblioteca en tiempo de ejecución.
Macros de diagnóstico generales de MFC
Nombre | Descripción |
---|---|
ASSERT | Imprime un mensaje y luego anula el programa si la expresión especificada se evalúa como FALSE en la versión de depuración de la biblioteca. |
ASSERT_KINDOF | Prueba que un objeto es un objeto de la clase especificada o de una clase derivada de la clase especificada. |
ASSERT_VALID | Prueba la validez interna de un objeto llamando a su función de miembro AssertValid ; normalmente invalidada desde CObject . |
DEBUG_NEW | Ofrece un nombre de archivo y un número de línea para todas las asignaciones de objetos en modo de depuración para ayudar a encontrar fugas de memoria. |
DEBUG_ONLY | Similar a ASSERT pero no prueba el valor de la expresión; útil para código que se debe ejecutar solo en modo de depuración. |
ENSURE y ENSURE_VALID | Úselos para validar la corrección de los datos. |
THIS_FILE | Se expande al nombre del archivo que se está compilando. |
TRACE | Ofrece capacidad similar a printf en la versión de depuración de la biblioteca. |
VERIFY | Similar a ASSERT pero evalúa la expresión en la versión de lanzamiento de la biblioteca, así como en la versión de depuración. |
Funciones y variables de diagnóstico general de MFC
Nombre | Descripción |
---|---|
afxDump | Variable global que envía información de CDumpContext a la ventana de salida del depurador o al terminal de depuración. |
afxMemDF | Variable global que controla el comportamiento del asignador de memoria de depuración. |
AfxCheckError | Variable global que se usa para probar el SCODE pasado para ver si es un error y, si es así, genera el error correspondiente. |
AfxCheckMemory | Comprueba la integridad de toda la memoria asignada actualmente. |
AfxDebugBreak | Provoca una interrupción en la ejecución. |
AfxDump | Si se llama mientras se encuentra en el depurador, vuelca el estado de un objeto durante la depuración. |
AfxDump | Función interna que realiza un volcado de memoria del estado de un objeto durante la depuración. |
AfxDumpStack | Genera una imagen de la pila actual. Esta función siempre está vinculada estáticamente. |
AfxEnableMemoryLeakDump | Habilita el volcado de fuga de memoria. |
AfxEnableMemoryTracking | Activa y desactiva el seguimiento de la memoria. |
AfxIsMemoryBlock | Comprueba que se ha asignado correctamente un bloque de memoria. |
AfxIsValidAddress | Comprueba que un intervalo de direcciones de memoria se encuentra dentro de los límites del programa. |
AfxIsValidString | Determina si un puntero a una cadena es válido. |
AfxSetAllocHook | Permite la llamada de una función en cada asignación de memoria. |
Funciones de diagnóstico de objetos de MFC
Nombre | Descripción |
---|---|
AfxDoForAllClasses | Realiza una función especificada en todas las clases derivadas por CObject que admiten la comprobación de tipos en tiempo de ejecución. |
AfxDoForAllObjects | Realiza una función especificada en todos los objetos derivados por CObject asignados con new . |
Macros de compilación MFC
Nombre | Descripción |
---|---|
_AFX_SECURE_NO_WARNINGS | Suprime las advertencias del compilador por el uso de funciones MFC en desuso. |
_AFX_SECURE_NO_WARNINGS
Suprime las advertencias del compilador por el uso de funciones MFC en desuso.
Sintaxis
_AFX_SECURE_NO_WARNINGS
Ejemplo
Este ejemplo de código produce una advertencia del compilador si _AFX_SECURE_NO_WARNINGS
no está definido.
// 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
Llame a esta función para provocar una interrupción (en la ubicación de la llamada a AfxDebugBreak
) en la ejecución de la versión de depuración de la aplicación MFC.
Sintaxis
void AfxDebugBreak( );
Comentarios
AfxDebugBreak
no tiene ningún efecto en las versiones de lanzamiento de una aplicación MFC y debe quitarse. Esta función solo debe usarse en aplicaciones MFC. Use la versión de API Win32, DebugBreak
, para provocar una interrupción en las aplicaciones que no son MFC.
Requisitos
Encabezado: afxver_.h
ASSERT
Evalúa su argumento.
ASSERT(booleanExpression)
Parámetros
booleanExpression
Especifica una expresión (incluidos los valores de puntero) que se evalúa como distinto de cero o 0.
Comentarios
Si el resultado es 0, la macro imprime un mensaje de diagnóstico y anula el programa. Si la condición es distinta de cero, no hace nada.
El mensaje de diagnóstico tiene la forma
assertion failed in file <name> in line <num>
donde name es el nombre del archivo de código fuente y num es el número de línea de la aserción que produjo un error en el archivo de código fuente.
En la versión de lanzamiento de MFC, ASSERT no evalúa la expresión y, por tanto, no interrumpirá el programa. Si la expresión se debe evaluar independientemente del entorno, use la macro VERIFY en lugar de ASSERT.
Nota:
Esta función solo está disponible en la versión de depuración de MFC.
Ejemplo
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*.
Requisitos
Encabezado: afx.h
ASSERT_KINDOF
Esta macro afirma que el objeto al que se apunta es un objeto de la clase especificada o es un objeto de una clase derivada de la clase especificada.
ASSERT_KINDOF(classname, pobject)
Parámetros
classname
Nombre de una clase derivada de CObject
.
pobject
Puntero a un objeto de clase.
Comentarios
El pobject debe ser un puntero a un objeto y puede ser const
. El objeto al que apunta y la clase deben admitir información de clase en tiempo de ejecución de CObject
. Por ejemplo, para asegurarse de que pDocument
es un puntero a un objeto de la clase CMyDoc
, o cualquiera de sus derivados, puede programar lo siguiente:
ASSERT_KINDOF(CMyDoc, pDocument);
El uso del macro ASSERT_KINDOF
es exactamente igual que programar lo siguiente:
ASSERT(pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)));
Esta función solo funciona para las clases declaradas con la macro [DECLARE_DYNAMIC](run-time-object-model-services.md#declare_dynamic o DECLARE_SERIAL.
Nota:
Esta función solo está disponible en la versión de depuración de MFC.
Requisitos
Encabezado: afx.h
ASSERT_VALID
Úselo para probar sus suposiciones sobre la validez del estado interno de un objeto.
ASSERT_VALID(pObject)
Parámetros
pObject
Especifica un objeto de una clase derivada de CObject
que tiene una versión reemplazada de la función miembro AssertValid
.
Comentarios
ASSERT_VALID llama a la función miembro AssertValid
del objeto pasado como argumento.
En la versión de lanzamiento de MFC, ASSERT_VALID no hace nada. En la versión de depuración, valida el puntero, comprueba NULL y llama a las funciones miembro AssertValid
del objeto. Si se produce un error en cualquiera de estas pruebas, se muestra un mensaje de alerta de la misma forma que ASSERT.
Nota:
Esta función solo está disponible en la versión de depuración de MFC.
Para más información y ejemplos, vea Técnicas de depuración de MFC.
Ejemplo
// Assure that pMyObject is a valid pointer to an
// object derived from CObject.
ASSERT_VALID(pMyObject);
Requisitos
Encabezado: afx.h
DEBUG_NEW
Ayuda a encontrar fugas de memoria.
#define new DEBUG_NEW
Comentarios
Puede usar DEBUG_NEW en todas las partes del programa que normalmente usarían el operador new
para asignar almacenamiento del montón.
En modo de depuración (cuando se define el símbolo _DEBUG), DEBUG_NEW realiza un seguimiento del nombre de archivo y el número de línea de cada objeto que asigna. Después, cuando se usa la función miembro CMemoryState::DumpAllObjectsSince, cada objeto asignado con DEBUG_NEW se muestra con el nombre de archivo y el número de línea donde se asignó.
Para usar DEBUG_NEW, inserte la siguiente directiva en los archivos de origen:
#define new DEBUG_NEW
Una vez haya insertado esta directiva, el preprocesador insertará DEBUG_NEW dondequiera que use new
, y MFC hará el resto. Al compilar una versión de lanzamiento del programa, DEBUG_NEW se resuelve en una operación new
sencilla y no se genera la información de nombre de archivo y número de línea.
Nota:
En versiones anteriores de MFC (4.1 y versiones anteriores) era necesario colocar la instrucción #define
después de todas las instrucciones que llamaban a las macros IMPLEMENT_DYNCREATE o IMPLEMENT_SERIAL. Ya no es necesario.
Requisitos
Encabezado: afx.h
DEBUG_ONLY
En el modo de depuración (cuando se define el símbolo _DEBUG), DEBUG_ONLY evalúa su argumento.
DEBUG_ONLY(expression)
Comentarios
En una compilación de versión, DEBUG_ONLY no evalúa su argumento. Esto resulta útil cuando tiene código que solo se debe ejecutar en compilaciones de depuración.
La macro DEBUG_ONLY es equivalente a rodear expression con #ifdef _DEBUG
y #endif
.
Ejemplo
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');
}
Requisitos
Encabezado: afx.h
ENSURE y ENSURE_VALID
Úselos para validar la corrección de los datos.
Sintaxis
ENSURE( booleanExpression )
ENSURE_VALID( booleanExpression )
Parámetros
booleanExpression
Especifica una expresión booleana que se va a probar.
Comentarios
El propósito de estas macros es mejorar la validación de los parámetros. Las macros impiden el procesamiento adicional de parámetros incorrectos en el código. A diferencia de las macros ASSERT, las macros ENSURE inician una excepción además de generar una aserción.
Las macros se comportan de dos maneras, según la configuración del proyecto. Las macros llaman a ASSERT y, después, inician una excepción si se produce un error en la aserción. Por lo tanto, en las configuraciones de depuración (es decir, donde se define _DEBUG), las macros generan una aserción y una excepción, mientras que en las configuraciones de versión, las macros generan solo la excepción (ASSERT no evalúa la expresión en las configuraciones de versión).
La macro ENSURE_ARG actúa como la macro ENSURE.
ENSURE_VALID llama a la macro ASSERT_VALID (que solo tiene efecto en las compilaciones de depuración). Además, ENSURE_VALID produce una excepción si el puntero es NULL. La prueba NULL se realiza en las configuraciones de depuración y de versión.
Si se produce un error en cualquiera de estas pruebas, se muestra un mensaje de alerta de la misma forma que ASSERT. La macro produce una excepción de argumento no válido si es necesario.
Requisitos
Encabezado: afx.h
THIS_FILE
Se expande al nombre del archivo que se está compilando.
Sintaxis
THIS_FILE
Comentarios
Las macros ASSERT y VERIFY usan la información. El Asistente para aplicaciones y los asistentes para código colocan la macro en los archivos de código fuente que crean.
Ejemplo
#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.
Requisitos
Encabezado: afx.h
TRACE
Envía la cadena especificada al depurador de la aplicación actual.
TRACE(exp)
TRACE(DWORD category, UINT level, LPCSTR lpszFormat, ...)
Comentarios
Vea ATLTRACE2 para una descripción de TRACE. TRACE y ATLTRACE2 tienen el mismo comportamiento.
En la versión de depuración de MFC, esta macro envía la cadena especificada al depurador de la aplicación actual. En una compilación de versión, esta macro no se compila en nada (no se genera ningún código).
Para más información, vea Técnicas de depuración de MFC.
Requisitos
Encabezado: afx.h
VERIFY
En la versión de depuración de MFC, evalúa su argumento.
VERIFY(booleanExpression)
Parámetros
booleanExpression
Especifica una expresión (incluidos los valores de puntero) que se evalúa como distinto de cero o 0.
Comentarios
Si el resultado es 0, la macro imprime un mensaje de diagnóstico y detiene el programa. Si la condición es distinta de cero, no hace nada.
El mensaje de diagnóstico tiene la forma
assertion failed in file <name> in line <num>
donde name es el nombre del archivo de código fuente y num es el número de línea de la aserción que produjo un error en el archivo de código fuente.
En la versión de lanzamiento de MFC, VERIFY evalúa la expresión, pero no imprime ni interrumpe el programa. Por ejemplo, si la expresión es una llamada de función, se realizará la llamada.
Ejemplo
// 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);
Requisitos
Encabezado: afx.h
afxDump (CDumpContext en MFC)
Proporciona la funcionalidad básica de volcado de memoria de objetos en la aplicación.
CDumpContext afxDump;
Comentarios
afxDump
es un objeto CDumpContext predefinido que permite enviar información CDumpContext
a la ventana de salida del depurador o a un terminal de depuración. Normalmente, se proporciona afxDump
como parámetro para CObject::Dump
.
En Windows NT y todas las versiones de Windows, la salida afxDump
se envía a la ventana Output-Debug (Depuración de salida) de Visual C++ al depurar la aplicación.
Esta variable solo se define en la versión de depuración de MFC. Para más información sobre afxDump
, vea Técnicas de depuración de MFC.
Ejemplo
// 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
Requisitos
Encabezado: afx.h
AfxDump (interno)
Función interna que usa MFC para realizar un volcado de memoria del estado de un objeto durante la depuración.
Sintaxis
void AfxDump(const CObject* pOb);
Parámetros
pOb
Puntero a un objeto de una clase derivada de CObject
.
Comentarios
AfxDump
llama a la función miembro Dump
de un objeto y envía la información a la ubicación especificada por la variable afxDump
. AfxDump
solo está disponible en la versión de depuración de MFC.
El código de programa no debe llamar a AfxDump
, sino que debe llamar a la función miembro Dump
del objeto adecuado.
Requisitos
Encabezado: afx.h
afxMemDF
Esta variable es accesible desde un depurador o el programa y permite optimizar los diagnósticos de asignación.
int afxMemDF;
Comentarios
afxMemDF
puede tener los siguientes valores según lo especificado por la enumeración afxMemDF
:
allocMemDF
Activa el asignador de depuración (configuración predeterminada en la biblioteca de depuración).delayFreeMemDF
Retrasa la liberación de memoria. Aunque el programa libera un bloque de memoria, el asignador no devuelve esa memoria al sistema operativo subyacente. Esto colocará el esfuerzo máximo de memoria en el programa.checkAlwaysMemDF
Llama aAfxCheckMemory
cada vez que se asigna o libera memoria. Esto ralentizará significativamente las asignaciones y desasignaciones de memoria.
Ejemplo
afxMemDF = allocMemDF | checkAlwaysMemDF;
Requisitos
Encabezado: afx.h
AfxCheckError
Esta función prueba el SCODE que ha pasado para ver si se trata de un error.
void AFXAPI AfxCheckError(SCODE sc);
throw CMemoryException*
throw COleException*
Comentarios
Si se trata de un error, la función produce una excepción. Si el SCODE pasado es E_OUTOFMEMORY, la función inicia una excepción CMemoryException mediante una llamada a AfxThrowMemoryException. De lo contrario, la función produce una excepción COleException mediante una llamada a AfxThrowOleException.
Esta función se puede usar para comprobar los valores devueltos de las llamadas a funciones OLE en la aplicación. Al probar el valor devuelto con esta función en la aplicación, puede reaccionar correctamente a las condiciones de error con una cantidad mínima de código.
Nota:
Esta función tiene el mismo efecto en las compilaciones de depuración y no depuración.
Ejemplo
AfxCheckError(::CoCreateInstance(clsidWMP, NULL, CLSCTX_INPROC_SERVER,
IID_IDispatch, (LPVOID*)& pWMPDispatch));
oddWMP.AttachDispatch(pWMPDispatch, TRUE);
Requisitos
Encabezado: afx.h
AfxCheckMemory
Esta función valida el grupo de memoria libre e imprime los mensajes de error según sea necesario.
BOOL AfxCheckMemory();
Valor devuelto
Distinto de cero si no hay errores de memoria; de lo contrario, 0.
Comentarios
Si la función no detecta daños en la memoria, no imprime nada.
Se comprueban todos los bloques de memoria asignados actualmente en el montón, incluidos los asignados por new
, pero no los asignados por llamadas directas a asignadores de memoria subyacentes, como la función malloc o la función GlobalAlloc
de Windows. Si se encuentra algún bloque dañado, se imprime un mensaje en la salida del depurador.
Si incluye la línea
#define new DEBUG_NEW
en un módulo de programa, las llamadas posteriores a AfxCheckMemory
muestran el nombre de archivo y el número de línea donde se asignó la memoria.
Nota:
Si el módulo contiene una o varias implementaciones de clases que se pueden serializar, debe colocar la línea #define
después de la última llamada de macro de IMPLEMENT_SERIAL.
Esta función solo funciona en la versión de depuración de MFC.
Ejemplo
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();
Requisitos
Encabezado: afx.h
AfxDump (MFC)
Llame a esta función mientras está en el depurador para realizar un volcado de memoria en el estado de un objeto durante la depuración.
void AfxDump(const CObject* pOb);
Parámetros
pOb
Puntero a un objeto de una clase derivada de CObject
.
Comentarios
AfxDump
llama a la función miembro Dump
de un objeto y envía la información a la ubicación especificada por la variable afxDump
. AfxDump
solo está disponible en la versión de depuración de MFC.
El código de programa no debe llamar a AfxDump
, sino que debe llamar a la función miembro Dump
del objeto adecuado.
Requisitos
Encabezado: afx.h
AfxDumpStack
Esta función global se puede usar para generar una imagen de la pila actual.
void AFXAPI AfxDumpStack(DWORD dwTarget = AFX_STACK_DUMP_TARGET_DEFAULT);
Parámetros
dwTarget
Indica el destino de la salida del volcado de memoria. Los valores posibles, que se pueden combinar mediante el operador OR bit a bit (|
), son los siguientes:
AFX_STACK_DUMP_TARGET_TRACE Envía la salida mediante la macro TRACE. La macro TRACE solo genera resultados en compilaciones de depuración; no genera ninguna salida en las compilaciones de versión. Además, TRACE se puede redirigir a otros destinos además del depurador.
AFX_STACK_DUMP_TARGET_DEFAULT Envía la salida de volcado de memoria al destino predeterminado. Para una compilación de depuración, la salida va a la macro TRACE. En una compilación de versión, la salida va al Portapapeles.
AFX_STACK_DUMP_TARGET_CLIPBOARD Envía la salida solo al Portapapeles. Los datos se colocan en el Portapapeles como texto sin formato con el formato de Portapapeles CF_TEXT.
AFX_STACK_DUMP_TARGET_BOTH Envía la salida al Portapapeles y a la macro TRACE de forma simultánea.
AFX_STACK_DUMP_TARGET_ODS Envía la salida directamente al depurador mediante la función
OutputDebugString()
de Win32. Esta opción generará la salida del depurador tanto en las compilaciones de depuración como en las de versión cuando se adjunta un depurador al proceso. AFX_STACK_DUMP_TARGET_ODS siempre llega al depurador (si está asociado) y no se puede redirigir.
Comentarios
En el ejemplo siguiente se refleja una sola línea de la salida generada al llamar a AfxDumpStack
desde un controlador de botón en una aplicación MFC de diálogo:
=== 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 ===
Cada línea de la salida anterior indica la dirección de la última llamada de función, el nombre de la ruta de acceso completa del módulo que contiene la llamada de función y el prototipo de función llamado. Si la llamada de función en la pila no se realiza en la dirección exacta de la función, se muestra un desplazamiento de bytes.
Por ejemplo, en la tabla siguiente se describe la primera línea de la salida anterior:
Output | Descripción |
---|---|
00427D55: |
Dirección de retorno de la última llamada de función. |
DUMP2\DEBUG\DUMP2.EXE! |
Nombre de ruta de acceso completa del módulo que contiene la llamada de función. |
void AfxDumpStack(unsigned long) |
Prototipo de función llamado. |
+ 181 bytes |
Desplazamiento en bytes desde la dirección del prototipo de función (en este caso, void AfxDumpStack(unsigned long) ) a la dirección de devolución (en este caso, 00427D55 ). |
AfxDumpStack
está disponible en las versiones de depuración y no depuración de las bibliotecas MFC; pero la función siempre está vinculada de forma estática, incluso cuando el archivo ejecutable usa MFC en una DLL compartida. En las implementaciones de biblioteca compartida, la función se encuentra en MFCS42. Biblioteca LIB (y sus variantes).
Para usar esta función correctamente tenga en cuenta lo siguiente:
El archivo IMAGEHLP.DLL debe estar en la ruta de acceso. Si no tiene esta DLL, la función mostrará un mensaje de error. Consulte Biblioteca de ayuda de imágenes para obtener información sobre el conjunto de funciones proporcionado por IMAGEHLP.
Los módulos que tienen marcos en la pila deben incluir información de depuración. Si no contienen información de depuración, la función seguirá generando un seguimiento de pila, pero será menos detallado.
Requisitos
Encabezado: afx.h
AfxEnableMemoryLeakDump
Habilita y deshabilita el volcado de pérdida de memoria en el destructor AFX_DEBUG_STATE.
BOOL AFXAPI AfxEnableMemoryLeakDump(BOOL bDump);
Parámetros
bDump
[in] TRUE indica que el volcado de fuga de memoria está habilitado, mientras que FALSE indica que está deshabilitado.
Valor devuelto
Valor anterior de esta marca.
Comentarios
Cuando una aplicación descarga la biblioteca MFC, esta comprueba si hay pérdidas de memoria. En este punto, las fugas de memoria se notifican al usuario mediante la ventana Depuración de Visual Studio.
Si la aplicación carga otra biblioteca antes que la biblioteca MFC, algunas asignaciones de memoria de la biblioteca se notificarán incorrectamente como pérdidas de memoria. Las pérdidas de memoria falsas pueden hacer que la aplicación se cierre lentamente, ya que la biblioteca MFC las estará notificando. En este caso, use AfxEnableMemoryLeakDump
para deshabilitar el volcado de pérdida de memoria.
Nota:
Si usa este método para desactivar el volcado de pérdida de memoria, no recibirá ningún informe de pérdidas de memoria válidas en la aplicación. Solo debe usar este método si está seguro de que el informe de pérdida de memoria contiene pérdidas de memoria falsas.
Requisitos
Encabezado: afx.h
AfxEnableMemoryTracking
El seguimiento de la memoria de diagnóstico suele estar habilitado en la versión de depuración de MFC.
BOOL AfxEnableMemoryTracking(BOOL bTrack);
Parámetros
bTrack
Al establecer este valor en TRUE, se activa el seguimiento de memoria; FALSE lo desactiva.
Valor devuelto
La configuración anterior de la marca de habilitación de seguimiento.
Comentarios
Use esta función para deshabilitar el seguimiento en secciones del código que sabe que están asignando bloques de forma correcta.
Para más información sobre AfxEnableMemoryTracking
, vea Técnicas de depuración de MFC.
Nota:
Esta función solo funciona en la versión de depuración de MFC.
Ejemplo
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;
}
Requisitos
Encabezado: afx.h
AfxIsMemoryBlock
Prueba una dirección de memoria para asegurarse de que representa un bloque de memoria actualmente activo asignado por la versión de diagnóstico de new
.
BOOL AfxIsMemoryBlock(
const void* p,
UINT nBytes,
LONG* plRequestNumber = NULL);
Parámetros
p
Apunta al bloque de memoria que se va a probar.
nBytes
Contiene la longitud del bloque de memoria en bytes.
plRequestNumber
Apunta a un entero long
que se rellenará con el número de secuencia de asignación del bloque de memoria o cero si no representa un bloque de memoria activo actualmente.
Valor devuelto
Distinto de cero si el bloque de memoria está asignado actualmente y la longitud es correcta; de lo contrario, 0.
Comentarios
También comprueba el tamaño especificado con respecto al tamaño asignado original. Si la función devuelve un valor distinto de cero, el número de secuencia de asignación se devuelve en plRequestNumber. Este número representa el orden en el que se asignó el bloque en relación con todas las demás asignaciones new
.
Ejemplo
CAge* pcage = new CAge(21); // CAge is derived from CObject.
ASSERT(AfxIsMemoryBlock(pcage, sizeof(CAge)));
Requisitos
Encabezado: afx.h
AfxIsValidAddress
Comprueba cualquier dirección de memoria para asegurarse de que se encuentra completamente dentro del espacio de memoria del programa.
BOOL AfxIsValidAddress(
const void* lp,
UINT nBytes,
BOOL bReadWrite = TRUE);
Parámetros
elepé
Apunta a la dirección de memoria que se va a probar.
nBytes
Contiene el número de bytes de memoria que se van a probar.
bReadWrite
Especifica si la memoria es para leer y escribir (TRUE) o solo leer (FALSE).
Valor devuelto
En las compilaciones de depuración, distinto de cero si el bloque de memoria especificado está contenido completamente dentro del espacio de memoria del programa; de lo contrario, 0.
En compilaciones que no son de depuración, distinto de cero si lp no es NULL; de lo contrario, 0.
Comentarios
La dirección no está restringida a los bloques asignados por new
.
Ejemplo
// 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));
Requisitos
Encabezado: afx.h
AfxIsValidString
Use esta función para determinar si un puntero a una cadena es válido.
BOOL AfxIsValidString(
LPCSTR lpsz,
int nLength = -1);
Parámetros
lpsz
Puntero que se va a probar.
nLength
Especifica la longitud de la cadena que se va a probar, en bytes. Un valor de -1 indica que la cadena finalizará en null.
Valor devuelto
En las compilaciones de depuración, es distinto de cero si el puntero especificado apunta a una cadena del tamaño especificado; de lo contrario, 0.
En las compilaciones que no son de depuración, es distinto de cero si lpsz no es NULL; de lo contrario, 0.
Ejemplo
// 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));
Requisitos
Encabezado: afx.h
AfxSetAllocHook
Establece un enlace que permite llamar a la función especificada antes de asignar cada bloque de memoria.
AFX_ALLOC_HOOK AfxSetAllocHook(AFX_ALLOC_HOOK pfnAllocHook);
Parámetros
pfnAllocHook
Especifica el nombre de la función que se va a llamar. Consulte los comentarios del prototipo de una función de asignación.
Valor devuelto
Distinto de cero si desea permitir la asignación; de lo contrario, 0.
Comentarios
El asignador de depuración de memoria de la biblioteca MFC (Microsoft Foundation Class) puede llamar a una función de enlace definida por el usuario para permitir al usuario supervisar una asignación de memoria y controlar si se permite la asignación. Las funciones de enlace de asignación se vuelven prototipos de la siguiente manera:
BOOL AFXAPI AllocHook( size_t nSize
, BOOLbObject
, LONG ); lRequestNumber
nSize
Tamaño de la asignación de memoria propuesta.
bObject
TRUE si la asignación es para un objeto derivado de CObject
; en caso contrario, FALSE.
lRequestNumber
Número de secuencia de la asignación de memoria.
Tenga en cuenta que la convención de llamada de AFXAPI implica que el destinatario debe quitar los parámetros de la pila.
Requisitos
Encabezado: afx.h
AfxDoForAllClasses
Llama a la función de iteración especificada para todas las clases derivadas de CObject
que se pueden serializar en el espacio de memoria de la aplicación.
void
AFXAPI AfxDoForAllClasses(
void (* pfn)(const CRuntimeClass* pClass, void* pContext),
void* pContext);
Parámetros
pfn
Apunta a una función de iteración a la que se llamará para cada clase. Los argumentos de función son un puntero a un objeto CRuntimeClass
y un puntero void a datos adicionales que el autor de la llamada proporciona a la función.
pContext
Apunta a datos opcionales que el autor de la llamada puede proporcionar a la función de iteración. Este puntero puede ser NULL.
Comentarios
Las clases derivadas de CObject
que se pueden serializar son clases derivadas mediante la macro DECLARE_SERIAL. El puntero que se pasa a AfxDoForAllClasses
en pContext se pasa a la función de iteración especificada cada vez que se la llama.
Nota:
Esta función solo funciona en la versión de depuración de MFC.
Ejemplo
#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
Requisitos
Encabezado: afx.h
AfxDoForAllObjects
Ejecuta la función de iteración especificada para todos los objetos derivados de CObject
que se han asignado con new
.
void AfxDoForAllObjects(
void (* pfn)(CObject* pObject, void* pContext),
void* pContext);
Parámetros
pfn
Apunta a una función de iteración que se va a ejecutar para cada objeto. Los argumentos de función son un puntero a CObject
y un puntero void a datos adicionales que el autor de la llamada proporciona a la función.
pContext
Apunta a datos opcionales que el autor de la llamada puede proporcionar a la función de iteración. Este puntero puede ser NULL.
Comentarios
Los objetos incrustados, globales o de pila no se enumeran. El puntero pasado a AfxDoForAllObjects
en pContext se pasa a la función de iteración especificada cada vez que se la llama.
Nota:
Esta función solo funciona en la versión de depuración de MFC.
Ejemplo
#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