2011-02-17 9 views
11

empecé aprendido windbg y yo encontramos este buen puesto How to use WinDbg to analyze the crash dump for VC++ application?¿Cómo escribir un código de muestra que se bloqueará y producirá un archivo de volcado?

Ahora quiero seguir las instrucciones y hacerlo paso a paso. Aquí está el problema: necesito escribir un código de muestra que pueda bloquearse inmediatamente y crear algunos archivos de volcado que puedan ser utilizados por windbg.

¿Cómo escribir dicho código?

void Example4() 
{ 
    int* i = NULL; 
    *i = 80; 
} 

El código anterior se bloqueará inmediatamente; sin embargo, no sé dónde encontrar el archivo de volcado?

Gracias

+13

podría tomar prestado parte de mi código ;-) – Jimmy

+0

Eche un vistazo a esto también: http://www.debuginfo.com/articles/effminidumps.html Lo encontré muy útil. Contiene un código de muestra también. – Naveen

Respuesta

23
#include <Windows.h> 
#include <Dbghelp.h> 

void make_minidump(EXCEPTION_POINTERS* e) 
{ 
    auto hDbgHelp = LoadLibraryA("dbghelp"); 
    if(hDbgHelp == nullptr) 
     return; 
    auto pMiniDumpWriteDump = (decltype(&MiniDumpWriteDump))GetProcAddress(hDbgHelp, "MiniDumpWriteDump"); 
    if(pMiniDumpWriteDump == nullptr) 
     return; 

    char name[MAX_PATH]; 
    { 
     auto nameEnd = name + GetModuleFileNameA(GetModuleHandleA(0), name, MAX_PATH); 
     SYSTEMTIME t; 
     GetSystemTime(&t); 
     wsprintfA(nameEnd - strlen(".exe"), 
      "_%4d%02d%02d_%02d%02d%02d.dmp", 
      t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond); 
    } 

    auto hFile = CreateFileA(name, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); 
    if(hFile == INVALID_HANDLE_VALUE) 
     return; 

    MINIDUMP_EXCEPTION_INFORMATION exceptionInfo; 
    exceptionInfo.ThreadId = GetCurrentThreadId(); 
    exceptionInfo.ExceptionPointers = e; 
    exceptionInfo.ClientPointers = FALSE; 

    auto dumped = pMiniDumpWriteDump(
     GetCurrentProcess(), 
     GetCurrentProcessId(), 
     hFile, 
     MINIDUMP_TYPE(MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory), 
     e ? &exceptionInfo : nullptr, 
     nullptr, 
     nullptr); 

    CloseHandle(hFile); 

    return; 
} 

LONG CALLBACK unhandled_handler(EXCEPTION_POINTERS* e) 
{ 
    make_minidump(e); 
    return EXCEPTION_CONTINUE_SEARCH; 
} 

int main() 
{ 
    SetUnhandledExceptionFilter(unhandled_handler); 

    return *(int*)0; 
} 
-3

Prueba esto:

int main() 
{ 
    int v[5]; 

    printf("%d", v[10]); 
    return 0; 
} 

o acceder a una posición de memoria aleatoria.

+5

esto podría no bloquearse: la memoria de la pila en v [10] probablemente esté realmente asignada y printf simplemente imprimirá la basura. –

4

Esto producirá una excepción de referencia de puntero nulo: *((int*) 0) = 0;

Esto producirá una división entera por cero: int a = 0; int b = 5/a;

EDIT: Post-Mortem Debugging Your Application with Minidumps and Visual Studio .NET contiene una gran cantidad de código de ejemplo y la teoría sobre el uso de minivolcados.

+0

gracias por el código. ¿También puedes decirme dónde encontrar el archivo de volcado? – q0987

+0

@ q0987 El archivo estará donde sea que lo escriba con MiniDumpWriteDump(). Si tiene UAC activado, es posible que no pueda escribirlo directamente en C: \ embargo. En este caso, use una carpeta debajo de su usuario o inicie la aplicación como Administrador. –

1

Si desea ver un volcado de emergencia, debe crear uno. Ver Heisenbug: WinApi program crashes on some computers. Si bien es posible que pueda obtener el volcado de fallo destinado a ser enviado para WER sin pasar por WinQual, es un poco complicado (básicamente, puede copiarlo de la ubicación temporal antes de enviarlo, los detalles exactos dependen de su sistema operativo) , Recomendaría crear tu propio crashdump usando las funciones proporcionadas por Win API MiniDump. Todo el código necesario para esto se puede encontrar en The CodeProject page mentioned in the linked answer.

1

La generación automática de minivolcados se realiza mediante el depurador post mortem, por lo que debe comenzar allí. Lo más importante, sin embargo, es hecho por un depurador. Entonces, si solo quiere generar un minivolcado, puede usar su depurador típico (probablemente visual studio o windbg). Incluso el administrador de tareas puede crear archivos de volcado.

La configuración del registro que especifica el depurador post-mortem es HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug

mirada a la cadena Debugger, y usted estará en su camino para encontrar sus minivolcados.

1

El archivo de volcado se puede crear ya sea programáticamente o mediante la herramienta de depuración del error del programa. En el primer caso, puede utilizar la función MiniDumpWriteDump y en el segundo se puede utilizar Dr. Watson (para XP: echar un vistazo a este description y esto muy descriptivo video; para Vista, echar un vistazo here)

0

he utilizado el código a continuación cuando se prueba WinDbg hace algún tiempo.

  • El código de abajo trabajos y generará un accidente volcado
  • Hay dos funciones de manera que se puede ver una traza de la pila con una cadena evidente de funciones.
  • Para encontrar los volcados de error, busque * .dmp o * .mdmp en C: \ Users
  • Probablemente sea mejor dejar que el SO genere el volcado para usted. Esta es probablemente la forma en que se generarán la mayoría de los volcados de falla reales que ve.
  • El código funciona asignando primero 1 KiB de memoria, y luego escribiéndolo junto con el siguiente 1 KiB con un valor hexadecimal reconocible. Esto generalmente golpea una página de memoria marcada por el sistema operativo como no grabable, lo que desencadenará el bloqueo.

#include "stdafx.h" 
#include "stdio.h" 
#include "malloc.h" 

void Function2(int * ptr2) 
{ 
    for(int i=0; i < (2 * 1024); i++) 
    { 
     *ptr2++ = 0xCAFECAFE; 
    } 
} 

void Function1() 
{ 
    int * ptr1 = (int *)malloc(1024 * sizeof(int)); 

    Function2(ptr1); 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    printf("Press enter to allocate and corrupt.\r\n"); 
    getc(stdin); 

    printf("Allocating and corrupting...\r\n"); 
    Function1(); 

    printf("Done. Press enter to exit process.\r\n"); 
    getc(stdin); 

    return 0; 
} 
0

Para crear un volcado de bloqueo, me no escribir un manejador de excepción no controlada según lo propuesto por @Abyx por las siguientes razones:

a) en caso de algún desbordamiento de búfer o desbordamiento de pila, el código que maneja la excepción no controlada puede estar dañado. En el caso de una excepción OutOfMemoryException, ¿cómo puede cargar otra biblioteca como DbgHelp.dll?

b) el código que ha escrito puede tener errores. ¿Comprueba ese código el espacio libre en el disco antes de que escriba el volcado? ¿Cómo se prueba el código para escribir un volcado? ¿Tienes una prueba de unidad para eso? ¿Cómo comprueba la unidad de prueba si el volcado es correcto?

c) ¿por qué escribir código en absoluto si Windows puede hacerlo por usted?

MSDN tiene un artículo en Collecting user mode dumps. Básicamente, hay algunas configuraciones de Registro que puedes hacer. La ventaja es que Windows creará el volcado de emergencia por el sistema operativo, no por algún código dañado dentro de su propia aplicación.

+0

Punto válido pero citando el artículo de MSDN 'Habilitar la función requiere privilegios de administrador', lo que podría no ser posible para las implementaciones de software – PhilLab

0

En la mayoría de los casos, encontrará todas las aplicaciones descargadas en C: \ windows \ minidumps.

Para generar un archivo de volcado se puede utilizar una solución sencilla:

  1. windbg abierto
  2. Archivo-> Abrir ejecutable
  3. Ejecuta la aplicación que se colgará
  4. Un punto de interrupción se activará
  5. Ahora puede utilizar .dump en windbg para crear un archivo dmp

o

  1. Ejecutar la aplicación y esperar a chocar
  2. windbg abierto y conectar con el proceso (Archivo-> Unir al proceso)
  3. plazo .dump

De esta manera usted será capaz para analizar ese bloqueo en cualquier momento :)

Cuestiones relacionadas