2012-01-26 58 views
7

我試圖在崩潰時爲我的應用程序創建一個轉儲文件。 我目前使用procdump.exe與-e標誌爲了做到這一點,所以如果我在我的應用程序中有未處理的異常procdump爲我創建一個轉儲文件。每次崩潰時爲應用程序創建一個轉儲文件

我以爲我完成了,但後來我發現我的應用程序崩潰,並且procdump不會創建轉儲文件。經過一番調查後,我發現vector :: front的無效使用會導致運行時錯誤。我打開了_SECURE_SCL_THROWS標誌,之後procdump.exe -e確實發現了崩潰並創建了一個轉儲文件。

現在我的問題:現在procdump.exe -e將始終創建一個轉儲文件,當我的應用程序崩潰?我如何保證我沒有其他procdump -e對我不利的情況?

回答

7

我假設你在一個Windows環境(因爲你使用procdump.exe)。您也可以爲您的PROGRAMM一個異常過濾器一個寫入mindump,只要您的應用程序崩潰:

  1. 註冊使用SetUnhandledExceptionFilter,這將在崩潰被調用的回調函數。一個可能的簽名是:

    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函數寫

    LONG WINAPI HandleException(struct _EXCEPTION_POINTERS* apExceptionInfo) 
    

    使用的地方註冊就在以前註冊的回調方法(HandleException)中轉儲(需要DbgHelp.dll 5.1或更高版本):

    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

爲什麼你可以在'MiniDumpWriteDump'中使用'GetProcAddr'只需包含DebuggingTools SDK中的DbgHelp.h? –

+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; 
} 
相關問題