Análisis del volcado de memoria

No todos los errores se pueden encontrar antes de la versión, lo que significa que no todos los errores que producen excepciones se pueden encontrar antes de la versión. Afortunadamente, Microsoft ha incluido en el SDK de plataforma una función para ayudar a los desarrolladores a recopilar información sobre las excepciones detectadas por los usuarios. La función MiniDumpWriteDump escribe la información de volcado de memoria necesaria en un archivo sin guardar todo el espacio del proceso. Este archivo de información de volcado de memoria se denomina minivolcado. En este artículo técnico se proporciona información sobre cómo escribir y usar un minivolcado.

Escribir un minivolcado

Las opciones básicas para escribir un minivolcado son las siguientes:

  • No haga nada. Windows genera automáticamente un minivolcado cada vez que un programa inicia una excepción no controlada. La generación automática de un minivolcado está disponible desde Windows XP. Si el usuario lo permite, el minivolcado se enviará a Microsoft y no al desarrollador, a través de Informe de errores de Windows (WER). Los desarrolladores pueden obtener acceso a estos minivolcados a través del Programa de aplicaciones de escritorio de Windows.

    El uso de WER requiere:

    • Desarrolladores para firmar sus aplicaciones mediante Authenticode
    • Las aplicaciones tienen un recurso VERSIONINFO válido en todos los archivos ejecutables y DLL

    Si implementa una rutina personalizada para excepciones no controladas, se le insta encarecidamente a usar la función ReportFault en el controlador de excepciones para enviar también un minivolcado automatizado a WER. La función ReportFault controla todos los problemas de conexión y envío del minivolcado a WER. No enviar minivolcados a WER infringe los requisitos de Juegos para Windows.

    Para obtener más información sobre cómo funciona WER, vea Cómo funciona Informe de errores de Windows. Para obtener una explicación de los detalles de registro, consulte Introducción a Informe de errores de Windows en la zona isv de MSDN.

  • Use un producto de Microsoft Visual Studio Team System. En el menú Depurar , haga clic en Guardar volcado como para guardar una copia de un volcado. El uso de un volcado guardado localmente solo es una opción para las pruebas y la depuración internas.

  • Agregue código al proyecto. Agregue la función MiniDumpWriteDump y el código de control de excepciones adecuado para guardar y enviar un minivolcado directamente al desarrollador. En este artículo se muestra cómo implementar esta opción. Sin embargo, tenga en cuenta que MiniDumpWriteDump no funciona actualmente con código administrado y solo está disponible en Windows XP, Windows Vista, Windows 7.

Seguridad para subprocesos

MiniDumpWriteDump forma parte de la biblioteca DBGHELP. Esta biblioteca no es segura para subprocesos, por lo que cualquier programa que use MiniDumpWriteDump debe sincronizar todos los subprocesos antes de intentar llamar a MiniDumpWriteDump.

Escritura de un minivolcado con código

La implementación real es sencilla. A continuación se muestra un ejemplo sencillo de cómo usar MiniDumpWriteDump.

#include <dbghelp.h>
#include <shellapi.h>
#include <shlobj.h>

int GenerateDump(EXCEPTION_POINTERS* pExceptionPointers)
{
    BOOL bMiniDumpSuccessful;
    WCHAR szPath[MAX_PATH]; 
    WCHAR szFileName[MAX_PATH]; 
    WCHAR* szAppName = L"AppName";
    WCHAR* szVersion = L"v1.0";
    DWORD dwBufferSize = MAX_PATH;
    HANDLE hDumpFile;
    SYSTEMTIME stLocalTime;
    MINIDUMP_EXCEPTION_INFORMATION ExpParam;

    GetLocalTime( &stLocalTime );
    GetTempPath( dwBufferSize, szPath );

    StringCchPrintf( szFileName, MAX_PATH, L"%s%s", szPath, szAppName );
    CreateDirectory( szFileName, NULL );

    StringCchPrintf( szFileName, MAX_PATH, L"%s%s\\%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp", 
               szPath, szAppName, szVersion, 
               stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay, 
               stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond, 
               GetCurrentProcessId(), GetCurrentThreadId());
    hDumpFile = CreateFile(szFileName, GENERIC_READ|GENERIC_WRITE, 
                FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);

    ExpParam.ThreadId = GetCurrentThreadId();
    ExpParam.ExceptionPointers = pExceptionPointers;
    ExpParam.ClientPointers = TRUE;

    bMiniDumpSuccessful = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), 
                    hDumpFile, MiniDumpWithDataSegs, &ExpParam, NULL, NULL);

    return EXCEPTION_EXECUTE_HANDLER;
}


void SomeFunction()
{
    __try
    {
        int *pBadPtr = NULL;
        *pBadPtr = 0;
    }
    __except(GenerateDump(GetExceptionInformation()))
    {
    }
}

En este ejemplo se muestra el uso básico de MiniDumpWriteDump y la información mínima necesaria para llamarla. El nombre del archivo de volcado de memoria es para el desarrollador; Sin embargo, para evitar colisiones de nombres de archivo, es aconsejable generar el nombre de archivo a partir del nombre y el número de versión de la aplicación, los identificadores de proceso y subproceso, y la fecha y hora. Esto también ayudará a mantener los minivolcados agrupados por aplicación y versión. Es el desarrollador el que decide cuánta información se usa para diferenciar los nombres de archivo de minivolcado.

Debe tenerse en cuenta que el nombre de ruta de acceso del ejemplo anterior se generó llamando a la función GetTempPath para recuperar la ruta de acceso del directorio designado para los archivos temporales. El uso de este directorio funciona incluso con cuentas de usuario con privilegios mínimos y también impide que el minivolcado ocupe espacio en el disco duro después de que ya no sea necesario.

Si archiva el producto durante el proceso de compilación diario, asegúrese también de incluir símbolos para la compilación para poder depurar una versión anterior del producto, si es necesario. También debe realizar pasos para mantener optimizaciones completas del compilador al generar símbolos. Para ello, abra las propiedades del proyecto en el entorno de desarrollo y, para la configuración de versión, haga lo siguiente:

  1. En el lado izquierdo de la página de propiedades del proyecto, haga clic en C/C++. De forma predeterminada, se muestra la configuración general . En el lado derecho de la página de propiedades del proyecto, establezca Formato de información de depuración en Base de datos de programa (/Zi).
  2. En el lado izquierdo de la página de propiedades, expanda Enlazador y, a continuación, haga clic en Depurar. En el lado derecho de la página de propiedades, establezca Generar información de depuraciónen Sí (/DEBUG).
  3. Haga clic en Optimización y establezca Referencias enDatos no referenciados (/OPT:REF).
  4. Establezca Habilitar plegado COMDAT para quitar COMDAT redundantes (/OPT:ICF).

MSDN tiene información más detallada sobre la estructura MINIDUMP_EXCEPTION_INFORMATION y la función MiniDumpWriteDump .

Uso de Dumpchk.exe

Dumpchk.exe es una utilidad de línea de comandos que se puede usar para comprobar que un archivo de volcado se creó correctamente. Si Dumpchk.exe genera un error, el archivo de volcado está dañado y no se puede analizar. Para obtener información sobre el uso de Dumpchk.exe, vea Cómo usar Dumpchk.exe para comprobar un archivo de volcado de memoria.

Dumpchk.exe se incluye en el CD del producto windows XP y se puede instalar en la unidad del sistema\Archivos de programa\Herramientas de soporte técnico\ ejecutando Setup.exe en la carpeta Support\Tools\ del CD del producto Windows XP. También puedes obtener la versión más reciente de Dumpchk.exe descargando e instalando las herramientas de depuración disponibles en Herramientas de depuración de Windows en Windows Hardware Developer Central.

Analizar un minivolcado

Abrir un minivolcado para el análisis es tan fácil como crear uno.

Para analizar un minivolcado

  1. Abra Visual Studio.
  2. En el menú Archivo , haga clic en Abrir proyecto.
  3. Establezca Archivos de tipo en Archivos de volcado, vaya al archivo de volcado, selecciónelo y haga clic en Abrir.
  4. Ejecute el depurador.

El depurador creará un proceso simulado. El proceso simulado se detendrá en la instrucción que provocó el bloqueo.

Usar el servidor de símbolos públicos de Microsoft

Para obtener la pila de bloqueos de nivel de controlador o sistema, puede que sea necesario configurar Visual Studio para que apunte al servidor de símbolos público de Microsoft.

Para establecer una ruta de acceso al servidor de símbolos de Microsoft

  1. En el menú Depurar , haga clic en Opciones.
  2. En el cuadro de diálogo Opciones , abra el nodo Depuración y haga clic en Símbolos.
  3. Asegúrese de buscar las ubicaciones anteriores solo cuando los símbolos se cargan manualmente no están seleccionados, a menos que desee cargar símbolos manualmente al depurar.
  4. Si usa símbolos en un servidor de símbolos remotos, puede mejorar el rendimiento especificando un directorio local en el que se pueden copiar símbolos. Para ello, escriba una ruta de acceso para Almacenar en caché símbolos del servidor de símbolos en este directorio. Para conectarse al servidor de símbolos públicos de Microsoft, debe habilitar esta configuración. Tenga en cuenta que si está depurando un programa en un equipo remoto, el directorio de caché hace referencia a un directorio del equipo remoto.
  5. Haga clic en OK.
  6. Dado que usa el servidor de símbolos públicos de Microsoft, aparece un cuadro de diálogo Contrato de licencia de usuario final. Haga clic en para aceptar el contrato y descargar símbolos en la memoria caché local.

Depuración de un minivolcado con WinDbg

También puede usar WinDbg, un depurador que forma parte de las Herramientas de depuración de Windows, para depurar un minivolcado. WinDbg permite depurar sin tener que usar Visual Studio. Para descargar herramientas de depuración de Windows, consulta Herramientas de depuración de Windows en Windows Hardware Developer Central.

Después de instalar herramientas de depuración de Windows, debe escribir la ruta de acceso del símbolo en WinDbg.

Para escribir una ruta de acceso de símbolo en WinDbg

  1. En el menú Archivo , haga clic en Ruta de acceso de símbolo.

  2. En la ventana Ruta de acceso de búsqueda de símbolos , escriba lo siguiente:

    "srv\*c:\\cache\*https://msdl.microsoft.com/download/symbols;"

Uso de herramientas de Copy-Protection con minivolcados

Los desarrolladores también deben tener en cuenta cómo su esquema de protección de copia podría afectar al minivolcado. La mayoría de los esquemas de protección de copia tienen sus propias herramientas de descramble y es el desarrollador el que aprende a usar esas herramientas con MiniDumpWriteDump.

Resumen

La función MiniDumpWriteDump puede ser una herramienta muy útil para recopilar y resolver errores después de que se haya publicado el producto. Escribir un controlador de excepciones personalizado que usa MiniDumpWriteDump permite al desarrollador personalizar la recopilación de información y mejorar el proceso de depuración. La función es lo suficientemente flexible como para usarse en cualquier proyecto basado en C++y debe considerarse parte del proceso de estabilidad de cualquier proyecto.