Uso de la utilidad PageHeap para detectar errores de memoria en un proyecto de Visual C++

En este artículo se describe cómo usar la utilidad PageHeap para detectar errores de memoria en proyectos de Microsoft Visual C++. La información de este artículo solo se aplica al código de Visual C++ no administrado.

Versión original del producto: Visual C++
Número de KB original: 264471

Resumen

La utilidad PageHeap se puede habilitar para las aplicaciones para que todas las mallocasignaciones , newy heapAlloc se supervisen automáticamente en busca de errores de memoria.

PageHeap1 es un proyecto de Visual C++ con varios tipos de errores de memoria. Para habilitar PageHeap en esta aplicación de ejemplo, escriba el siguiente contenido desde la línea de comandos:

pageheap /enable pgh.exe 0x01

A continuación, escriba el siguiente contenido:

pageheap

Nota:

Nombre de la aplicación que supervisa PageHeap.

Para muchas aplicaciones, 0x01 es la única marca que necesita. Para obtener más información sobre su uso, ejecute PageHeap con la marca de signo de interrogación (/?) desde la línea de comandos.

Funcionamiento de PageHeap

PageHeap devuelve un puntero a la memoria asignada en límites de 8 bytes. El final del puntero devuelto va seguido de 0 a 7 bytes de protección (según el tamaño solicitado, se agregan de 0 bytes a 7 bytes para redondear el tamaño de la solicitud para que esté en un límite de 8 bytes), seguido de una página de memoria marcada PAGE_NOACCESS (para obtener más información, vea VirtualAlloc). Por ejemplo:

char * p;
p = new char[5];

PageHeap devuelve un puntero a los 5 bytes más tres bytes de protección para componer un total de 8 bytes, como..... XXX. Si el tamaño de asignación de memoria es un múltiplo de ocho, no hay bytes de protección agregados al puntero devuelto.

Si se sobrescribe el final de la asignación, cambian los bytes de protección y PageHeap provocan un error de infracción de acceso cuando se libera la memoria. Si la aplicación lee o escribe más allá de la asignación (incluidos los bytes de protección), incurre en un error de infracción de acceso instantáneo.

Uso del ejemplo PageHeap1

  1. Compile el proyecto pgh y ejecute el pgh.exe.

    Nota:

    Debe realizar una compilación de versión para que PageHeap funcione con new o malloc.

    Inicie el PageHeap1.exe. Hay un cuadro de diálogo emergente.

  2. En el cuadro de diálogo, puede ver una casilla TextBox, una casilla Bad Alloc/Free y tres pares de botones, nuevos & delete, PageAlloc & Heap Free y COM new & COM Delete. TextBox toma el tamaño de la memoria que desea haber asignado. Si está activada la casilla Bad Alloc/Free (Asignación incorrecta o gratuita), cada tipo de asignación (new, PageAlloc y COM new) asigna memoria y, a continuación, escribe más allá de la asignación. Si no se activa Bad Alloc, no se produce ninguna sobrescritura de memoria.

    Button new prueba el new operador, button PageAlloc prueba HeapAlloc. El nuevo COM no usa CoTaskMemAlloc , sino que llama a una biblioteca de vínculos dinámicos (DLL) COM que simplemente llama a new. Para probar com nuevo, debe registrar r1LeakMemMod.dll o compilar el proyecto r1LeakMemMod.

    Puede usar una biblioteca DLL en tiempo de ejecución para que PageHeap funcione. (Desde el Entorno de desarrollo integrado (IDE) de Visual C++, Proyectos>Configuración>C++>Categoría: Generación de> códigoUse la biblioteca en tiempo de ejecución).

  3. Después de activar la casilla Bad Alloc/Free ,si el tamaño de asignación de memoria es de 5 bytes, seleccione en el nuevo botón, se asignará memoria de 5 bytes y 0 se escribirá en el sexto byte. Escribir en el sexto byte es una sobrescritura de memoria no válida, pero se produce en un byte de protección, por lo que PageHeap no detecta este error hasta que se elimina la memoria. Al seleccionar el botón Eliminar, PageHeap detecta la sobrescritura y verá un cuadro de mensaje de error similar al siguiente ejemplo:

    Excepción Punto de interrupción Se ha alcanzado un punto de interrupción. (0x80000003) se produjo en la aplicación en la ubicación 0x77f9f9df.

    Si tiene Visual C++ especificado como depurador Just-In-Time (JIT), puede seleccionar el botón Cancelar y depurar en el código.

    Si cambia el tamaño de asignación a 8 (o cualquier múltiplo de 8), al seleccionar los botones nuevo, pageAlloc o COM Nuevo, se producirá un error de infracción de acceso instantáneo porque ha escrito en una dirección sin acceso. (es decir, no es necesario eliminar la memoria para detectar el error).

Nota:

  1. Limitaciones: PageHeap solo puede encontrar errores de memoria de la malloc familia (por lo tanto, operador newde C++ ) y heapAlloc. Muchas aplicaciones usan asignadores personalizados y PageHeap no puede interceptar estas asignaciones.
  2. Cuando haya terminado de probar una aplicación, ejecute pageheap /disable <appName> desde la línea de comandos para desactivar PageHeap para esa aplicación.
  3. Las aplicaciones habilitadas para PageHeap pueden consumir mucha más memoria que la misma aplicación sin PageHeap habilitado. Es posible que tenga que aumentar el archivo de intercambio para satisfacer la mayor demanda de memoria.

Puede descargar Pageheap1vcnet.exe aquí. Para obtener más información sobre cómo descargar archivos de soporte técnico de Microsoft, consulte Obtención de archivos de soporte técnico de Microsoft de servicios en línea.

Microsoft ha examinado este archivo en busca de virus. Microsoft usó el software de detección de virus más actual que estaba disponible en la fecha en que se publicó el archivo. El archivo se almacena en servidores mejorados de seguridad que ayudan a evitar cambios no autorizados en el archivo.