• 程序崩溃时生成崩溃报告


    关键词: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文件是空的,这种情况我碰到过,根据我自己的经验,原因是内存耗尽了。

  • 相关阅读:
    毕业设计进度5(2月5日)
    毕业设计进度4(2月4日)
    Intellij IDEA 安装Scala插件 + 创建Scala项目
    中国HBase技术社区第一届Meetup资料大合集
    【大会PPT+直播回顾】HBaseCon亚洲2018峰会
    Java 中的锁原理、锁优化、CAS、AQS 详解!
    Reactor 反应堆设计模式
    IO模型
    浅析Reactor设计模式
    将IDEA工程代码提交到Github
  • 原文地址:https://www.cnblogs.com/yuohoo/p/2961707.html
Copyright © 2020-2023  润新知