2012-01-26 3 views
7

Я пытаюсь создать файл дампа для моего приложения всякий раз, когда он сбой. В настоящее время я использую procdump.exe с флагом -e, чтобы сделать это, поэтому, если у меня есть необработанное исключение в моем приложении, procdump создает для меня файл дампа.Создайте файл дампа для приложения, когда он сбой

Я думал, что все закончилось, но потом выяснилось, что сбой приложения и procdump не создает файл дампа. После некоторых исследований я обнаружил, что недопустимое использование ошибки: :: front вызывает ошибку времени выполнения. Я включил флаг _SECURE_SCL_THROWS, и после этого procdump.exe -e поймал сбой и создал файл дампа.

Теперь на мой вопрос: теперь procdump.exe -e всегда будет создавать файл дампа при сбое приложения? Как я могу гарантировать, что у меня нет других сценариев, где procdump -e не подходит для меня?

ответ

7

Я предполагаю, что вы находитесь в среде Windows (потому что вы используете procdump.exe). Кроме того, можно установить фильтр исключений для вашей программе, которая записывает mindump всякий раз, когда ваше приложение аварии:

  1. Регистрирует функцию обратного вызова с помощью SetUnhandledExceptionFilter, которая будет запущена на аварии. Возможная подпись будет:

    LONG WINAPI HandleException(struct _EXCEPTION_POINTERS* apExceptionInfo) 
    

    Зарегистрируйте где-то с помощью:

    SetUnhandledExceptionFilter(HandleException); 
    
  2. Определить указатель на функцию для вызова функции 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. Используйте функцию MiniDumpWriteDump писать дамп (требуется DbgHelp.dll 5.1 или новее) в ранее зарегистрированном методе обратного вызова (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

Почему вы используете 'GetProcAddr' для' MiniDumpWriteDump', когда можете просто включите DbgHelp.h из SDK DebuggingTools ?? –

+0

Поскольку IAT (таблица адресов импорта) может быть повреждена при возникновении сбоя. В таких обработчиках сбоев единственная надежная вещь - связать себя с библиотеками самостоятельно! –

+0

@ ПетърПетров Но тогда как вы собираетесь называть 'LoadLibrary'? Если IAT поврежден, значит, вы, вероятно, уже ввернуты. – 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; 
}