web-dev-qa-db-ja.com

プロセスがクラッシュしたときにクラッシュダンプを生成するための最良の方法は?

Windows環境(XPおよびWin 7):

  • プロセスがシステムでクラッシュしたときにクラッシュダンプを自動的に生成するための最良の方法は何ですか?
  • インストーラー(MSI)パッケージでこれを行うことはできますか?
11
CJ7

Windowsで任意の/特定のプロセスの自動ダンプを作成する最良の方法の1つは、レジストリに一連のエントリを構成することです。私はWindows764ビットで以下を試しました。

Notepad.exeを開き、以下のエントリを貼り付けて、「EnableDump.reg」として保存します。好きな名前を付けることができます。

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps]
"DumpFolder"=hex(2):44,00,3a,00,5c,00,64,00,75,00,6d,00,70,00,00,00
"DumpCount"=dword:00000010
"DumpType"=dword:00000002
"CustomDumpFlags"=dword:00000000

「EnableDump.reg」をダブルクリックして、「はい」を選択します。ダンプフォルダを「d:\ dump」として指定しました。好きなフォルダに変更できます。

クラッシュするアプリケーションを実行しようとすると、Windowsはエラーダイアログを表示します。 「プログラムを閉じる」オプションを選択します。その後、設定されたフォルダにダンプが表示されます。ダンプファイルの名前は.exe..dmpになります。

詳細については、以下のリンクを参照してください。

http://msdn.Microsoft.com/en-us/library/bb787181(VS.85).aspx

16
MNS

以下は別のものからの改良版です 回答

未処理の例外が発生したときにプロセスダンプを自動的に作成する独自のダンプ生成フレームワークを使用すると、クライアントがWinDbgをインストールする必要がなくなります。

アプリケーションの起動時に、SetUnhandledExceptionFilter(...) Win32 APIを使用してコールバックを登録します(つまり、アプリケーションレベルの例外ハンドラー)。これで、処理されない例外があるたびに、登録されたコールバック関数が呼び出されます。次に、_DbgHelp.dll_からMiniDumpWriteDump(...)APIを使用してプロセスダンプを作成できます。

C++サンプル(ユニコード):

ヘッダーファイル

_#ifndef CRASH_REPORTER_H
#define CRASH_REPORTER_H

//Exclude rarely used content from the Windows headers.
#ifndef WIN32_LEAN_AND_MEAN
#    define WIN32_LEAN_AND_MEAN
#    include <windows.h>
#    undef WIN32_LEAN_AND_MEAN
#else
#    include <windows.h>
#endif
#include <tchar.h>
#include <DbgHelp.h>

class CrashReporter {
public:
    inline CrashReporter() { Register(); }
    inline ~CrashReporter() { Unregister(); }

    inline static void Register() {
        if(m_lastExceptionFilter != NULL) {
            fprintf(stdout, "CrashReporter: is already registered\n");
            fflush(stdout);
        }
        SetErrorMode(SEM_FAILCRITICALERRORS);
        //ensures UnHandledExceptionFilter is called before App dies.
        m_lastExceptionFilter = SetUnhandledExceptionFilter(UnHandledExceptionFilter);
    }
    inline static void Unregister() {
        SetUnhandledExceptionFilter(m_lastExceptionFilter);
    }

private:
    static LPTOP_LEVEL_EXCEPTION_FILTER m_lastExceptionFilter;
    static LONG WINAPI UnHandledExceptionFilter(_EXCEPTION_POINTERS *);
};


#endif // CRASH_REPORTER_H
_

ソースファイル

_#include "crash-report.h"

#include <stdio.h>

LPTOP_LEVEL_EXCEPTION_FILTER CrashReporter::m_lastExceptionFilter = NULL;

typedef BOOL (WINAPI *MiniDumpWriteDumpFunc)(HANDLE hProcess, DWORD ProcessId
        , HANDLE hFile
        , MINIDUMP_TYPE DumpType
        , const MINIDUMP_EXCEPTION_INFORMATION *ExceptionInfo
        , const MINIDUMP_USER_STREAM_INFORMATION *UserStreamInfo
        , const MINIDUMP_CALLBACK_INFORMATION *Callback
    );

LONG WINAPI CrashReporter::UnHandledExceptionFilter(struct _EXCEPTION_POINTERS *exceptionPtr)
{
    //we load DbgHelp.dll dynamically, to support Windows 2000
    HMODULE hModule = ::LoadLibraryA("DbgHelp.dll");
    if (hModule) {
        MiniDumpWriteDumpFunc dumpFunc = reinterpret_cast<MiniDumpWriteDumpFunc>(
                    ::GetProcAddress(hModule, "MiniDumpWriteDump")
                );
        if (dumpFunc) {
            //fetch system time for dump-file name
            SYSTEMTIME  SystemTime;
            ::GetLocalTime(&SystemTime);
            //choose proper path for dump-file
            wchar_t dumpFilePath[MAX_PATH] = {0};
            _snwprintf_s(dumpFilePath, MAX_PATH, L"crash_%04d-%d-%02d_%d-%02d-%02d.dmp"
                    , SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay
                    , SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond
                );
            //create and open the dump-file
            HANDLE hFile = ::CreateFileW( dumpFilePath, GENERIC_WRITE
                    , FILE_SHARE_WRITE
                    , NULL
                    , CREATE_ALWAYS
                    , FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_HIDDEN
                    , NULL
                );

            if (hFile != INVALID_HANDLE_VALUE) {
                _MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
                exceptionInfo.ThreadId          = GetCurrentThreadId();
                exceptionInfo.ExceptionPointers = exceptionPtr;
                exceptionInfo.ClientPointers    = NULL;
                //at last write crash-dump to file
                bool ok = dumpFunc(::GetCurrentProcess(), ::GetCurrentProcessId()
                        , hFile, MiniDumpNormal
                        , &exceptionInfo, NULL, NULL
                    );
                //dump-data is written, and we can close the file
                CloseHandle(hFile);
                if (ok) {
                    //Return from UnhandledExceptionFilter and execute the associated exception handler.
                    //  This usually results in process termination.
                    return EXCEPTION_EXECUTE_HANDLER;
                }
            }
        }
    }
    //Proceed with normal execution of UnhandledExceptionFilter.
    //  That means obeying the SetErrorMode flags,
    //  or invoking the Application Error pop-up message box.
    return EXCEPTION_CONTINUE_SEARCH;
}
_

使用法

_#include "3rdParty/crash-report.h"

int main(int argc, char *argv[])
{
    CrashReporter crashReporter;
    (void)crashReporter; //prevents unused warnings

    // [application main loop should be here]

    return 0;
}
_
2
Top-Master

Windows XP:次の手順により、自動クラッシュダンプが有効になります。

1) Open a command Prompt, running as administrator
2) Run drwtsn32 -i. This will install Doctor Watson as the default debugger when something crashes
3) Click Ok
4) From the command Prompt, run drwtsn32
5) Set the Crash Dump path to your favorite directory, or leave the default.
6) Set the Crash Dump Type to mini. Note that under some circumstances, we may ask you for a full crash dump.
7) Make sure the Dump All Thread Contexts and Create Crash Dump File options are selected.
8) Click Ok
9) If a user.dmp file already exists in the Crash Dump path, delete it.

Windows 7:場所は次のとおりです。

C:\Users[Current User when app crashed]\AppData\Local\Microsoft\Windows\WER\ReportArchive
2