2012-01-26 14 views
7

Estoy intentando crear un archivo de volcado para mi aplicación cada vez que se cuelga. Actualmente estoy usando procdump.exe con el indicador -e para hacerlo, así que si tengo una excepción no controlada en mi aplicación, procdump crea un archivo de volcado para mí.Crear un archivo de volcado para una aplicación cada vez que se cuelga

Pensé que había terminado, pero luego descubrí que mi aplicación falla y procdump no crea un archivo de volcado. Después de algunas investigaciones, descubrí que el uso no válido de vector :: front causa un error de tiempo de ejecución. Encendí el indicador _SECURE_SCL_THROWS y después de eso procdump.exe -e atrapó el bloqueo y creó un archivo de volcado.

Ahora a mi pregunta: ¿Ahora es procdump.exe -e siempre creará un archivo de volcado cuando se bloquea mi aplicación? ¿Cómo puedo garantizar que no tengo otros escenarios donde procdump -e no es bueno para mí?

Respuesta

7

Supongo que se encuentra en un entorno de Windows (porque utiliza procdump.exe). También podría establecer un filtro de excepción para su Programm que escribe un mindump cada vez que el bloqueo de la aplicación:

  1. Registrar una función de devolución de llamada usando SetUnhandledExceptionFilter que se invoca en un accidente. Una posible firma sería:

    LONG WINAPI HandleException(struct _EXCEPTION_POINTERS* apExceptionInfo) 
    

    Registrarse en algún lugar usando:

    SetUnhandledExceptionFilter(HandleException); 
    
  2. definir un puntero de función para llamar a la función MiniDumpWriteDump:

    typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType,CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,CONSTPMINIDUMP_USER_STREAM_INFORMATIOUserStreamParam,CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam); 
    
  3. Utilice la función MiniDumpWriteDump escribir el vuelco (requiere DbgHelp.dll 5.1 o posterior) en el método de devolución de llamada registrado anteriormente (HandleException):

    HMODULE mhLib = ::LoadLibrary(_T("dbghelp.dll")); 
    MINIDUMPWRITEDUMP pDump = (MINIDUMPWRITEDUMP)::GetProcAddress(mhLib, "MiniDumpWriteDump"); 
    
    HANDLE hFile = ::CreateFile(_T("dump_name"), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 
            FILE_ATTRIBUTE_NORMAL, NULL); 
    
    
    _MINIDUMP_EXCEPTION_INFORMATION ExInfo; 
    ExInfo.ThreadId = ::GetCurrentThreadId(); 
    ExInfo.ExceptionPointers = apExceptionInfo; 
    ExInfo.ClientPointers = FALSE; 
    
    pDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL); 
    ::CloseHandle(hFile); 
    
+0

¿Por qué está utilizando 'GetProcAddr' para' MiniDumpWriteDump' cuando puede solo incluya DbgHelp.h desde DebuggingTools SDK ?? –

+0

Porque IAT (Tabla de direcciones de importación) puede estar ya dañado cuando se produce el bloqueo. En tales controladores de bloqueo, ¡lo único que se puede hacer es vincularse con las bibliotecas usted mismo! –

+0

@ ПетърПетров Pero entonces, ¿cómo vas a llamar a 'LoadLibrary'? Si el IAT está dañado, entonces probablemente ya estás jodido. – LHLaurini

2

/* * WinDump.cpp/

#ifdef WIN32 

#include <windows.h> 
#include <Dbghelp.h> 
#include <tchar.h> 


typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType,CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam); 

void create_minidump(struct _EXCEPTION_POINTERS* apExceptionInfo) 
{ 
    HMODULE mhLib = ::LoadLibrary(_T("dbghelp.dll")); 
    MINIDUMPWRITEDUMP pDump = (MINIDUMPWRITEDUMP)::GetProcAddress(mhLib, "MiniDumpWriteDump"); 

    HANDLE hFile = ::CreateFile(_T("core.dmp"), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 
     FILE_ATTRIBUTE_NORMAL, NULL); 

    _MINIDUMP_EXCEPTION_INFORMATION ExInfo; 
    ExInfo.ThreadId = ::GetCurrentThreadId(); 
    ExInfo.ExceptionPointers = apExceptionInfo; 
    ExInfo.ClientPointers = FALSE; 

    pDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL); 
    ::CloseHandle(hFile); 
} 

LONG WINAPI unhandled_handler(struct _EXCEPTION_POINTERS* apExceptionInfo) 
{ 
    create_minidump(apExceptionInfo); 
    return EXCEPTION_CONTINUE_SEARCH; 
} 

#endif // WIN32 

/* * WinDump.h/

#ifdef WIN32 

LONG WINAPI unhandled_handler(struct _EXCEPTION_POINTERS* apExceptionInfo); 

#endif // WIN32 

/* * main.cpp/

#include "WinDump.h" 

int main(int argc, char **argv) 
{ 

    // Create a dump file whenever the gateway crashes only on windows 
    SetUnhandledExceptionFilter(unhandled_handler); 
    return 0; 
} 
Cuestiones relacionadas