程序崩溃时生成崩溃报告

关键词:SetUnhandledExceptionFilter MiniDumpWriteDump

1、声明:该流程只对本线程有效,如果是多线程,需要对每个线程都做调用处理。

2、代码流程:

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

MINIDUMPWRITEDUMP  g_pDumpFunc = NULL;        // 声明函数指针

// 参数lpExceptionInfo包含了异常信息,由系统提供
LONG WINAPI ExceptionFilterFunc (struct _EXCEPTION_POINTERS *lpExceptionInfo)
{
    LONG ret = EXCEPTION_CONTINUE_SEARCH;
    // 根据当前时间创建dmp空文件
    CString strFile;
    CTime timeNow = CTime::GetCurrentTime();
    strFile = timeNow.Format("%Y%m%d%H%M%S");
    strFile += ".dmp";
    ::CreateDirectory("dumps\\",NULL);
    strFile = "dumps\\" + strFile;
    HANDLE hFile = ::CreateFile(strFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL );
    if (hFile != INVALID_HANDLE_VALUE)
    {
        MINIDUMP_EXCEPTION_INFORMATION ExInfo;
        ExInfo.ThreadId = ::GetCurrentThreadId();
        ExInfo.ExceptionPointers = lpExceptionInfo;
        ExInfo.ClientPointers = NULL;
        // 将崩溃信息记录到dmp文件中
        BOOL bRet = g_pDumpFunc( GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL );
        if (bRet)
            ret = EXCEPTION_EXECUTE_HANDLER;
        else
        {
            AfxMessageBox("call MiniDumpWriteDump fail...");
        }
        ::CloseHandle(hFile);
    }

    return ret;
}

// thread function
UINT xxThread(LPVOID pParam)
{
    // load dgbhelp.dll
    HMODULE hDll = NULL;
    hDll = LoadLibrary("dbghelp.dll") ;
    if (hDll == NULL)
    {
        AfxMessageBox("load dbghelp.dll fail");
        return FALSE;
    }
    // load MiniDumpWriteDump function
    g_pDumpFunc = (MINIDUMPWRITEDUMP)::GetProcAddress(hDll, "MiniDumpWriteDump");
    if (g_pDumpFunc == NULL)
    {
        AfxMessageBox("load MiniDumpWriteDump function fail");
        return FALSE;
    }
    // 设置异常捕获函数
    ::SetUnhandledExceptionFilter(ExceptionFilterFunc);

    return TRUE;
}

3、采用这种方法,基本上可以在程序崩溃的时候收集到崩溃报告并生成dmp文件,如果没有dmp文件生成,那么可能发生了栈溢出、覆盖的情况,请检查代码是否存在栈溢出、覆盖的情况。

4、如果收集到的dmp文件是空的,这种情况我碰到过,根据我自己的经验,原因是内存耗尽了。

原文地址:https://www.cnblogs.com/yuohoo/p/2961707.html