2012-01-26 8 views
7

クラッシュするたびにアプリケーションのダンプファイルを作成しようとしています。 私は現在procdump.exeと-eフラグを使用していますので、アプリケーションで処理されない例外があると、procdumpが私のためにダンプファイルを作成します。クラッシュ時にアプリケーションのダンプファイルを作成する

私は完了したと思ったが、私のアプリケーションがクラッシュし、procdumpがダンプファイルを作成しないことがわかった。いくつかの調査の後、私はvector :: frontの無効な使用が実行時エラーを引き起こすことを発見しました。 _SECURE_SCL_THROWSフラグをオンにした後、procdump.exe -eはクラッシュをキャッチしてダンプファイルを作成しました。

私の質問に今すぐ:procdump.exe -eは、アプリケーションがクラッシュしたときに常にダンプファイルを作成しますか? procdump -eが私にとってうまくいかないシナリオが他にないことをどうすれば保証できますか?

答えて

7

私は、(procdump.exeを使用しているため)あなたがWindows環境にいると仮定します。

  1. クラッシュで呼び出すことができますSetUnhandledExceptionFilterを使用してコールバック関数を登録します。また、は、アプリケーションのクラッシュがいつでもmindumpを書き込み、あなたのプログラムの開発のための例外フィルタを設定することができます。可能なシグネチャは次のようになります。

    LONG WINAPI HandleException(struct _EXCEPTION_POINTERS* apExceptionInfo) 
    

    を使用してどこかにそれを登録します。

    SetUnhandledExceptionFilter(HandleException); 
    
  2. 機能MiniDumpWriteDump呼び出すための関数ポインタを定義します書くこと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. を以前に登録されたコールバックメソッド(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; 
} 
関連する問題