關於“程序閃退,沒有生成DUMP文件”的一點總結

今早一回到公司,測試的同事就反映,昨晚程序運行一段時間後閃退了。。。。閃退???額,好吧,幸好我有加寫DUMP的代碼,示例如下:

LONG WINAPI UnhandledExceptionFunction(_EXCEPTION_POINTERS* pExceptionInfo)
{
    SYSTEMTIME st;
    GetLocalTime(&st);

    CString time_now = _T("");
    time_now.Format(_T("%04d_%02d_%02d_%02d_%02d_%03d.dmp"), st.wYear, st.wMonth, st.wDay,
        st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
    CString dump_file_path = GetRootPath();            //獲取程序所在的文件夾的路徑
    dump_file_path += _T("dump/");
    CreateDirectory(dump_file_path, NULL);
    dump_file_path += time_now;

    HANDLE hDumpFile = CreateFile(dump_file_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
    dumpInfo.ExceptionPointers = pExceptionInfo;
    dumpInfo.ThreadId = GetCurrentThreadId();
    dumpInfo.ClientPointers = TRUE;

    MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);
    CloseHandle(hDumpFile);

    ExitProcess(0);
    return 1;
}

只要在程序的Main函數中加上

    SetUnhandledExceptionFilter(UnhandledExceptionFunction);

就行了。但是一查看測試同事手上的軟件時。。。。DUMP呢???沒有生成!什麼鬼!於是我去找了找“程序閃退,沒有生成DUMP文件”之類的資料,於是找到了這篇博客:https://blog.csdn.net/liaozhilong88/article/details/80595757。先感謝這位博主的整理與分享。

原來SetUnhandledExceptionFilter是無法捕獲printf等CRT函數的異常的,於是我加上了下面的代碼後,開始了測試

void DisableSetUnhandledExceptionFilter()
{
    void* addr = (void*)GetProcAddress(LoadLibrary(_T("kernel32.dll")), "SetUnhandledExceptionFilter");

    if (addr != NULL)
    {
        unsigned char code[16];
        int size = 0;

        code[size++] = 0x33;
        code[size++] = 0xC0;
        code[size++] = 0xC2;
        code[size++] = 0x04;
        code[size++] = 0x00;

        DWORD dwOldFlag, dwTempFlag;
        VirtualProtect(addr, size, PAGE_READWRITE, &dwOldFlag);
        WriteProcessMemory(GetCurrentProcess(), addr, code, size, NULL);
        VirtualProtect(addr, size, dwOldFlag, &dwTempFlag);
    }
}

上面這個函數使用方法如下所示

    SetUnhandledExceptionFilter(UnhandledExceptionFunction);
    DisableSetUnhandledExceptionFilter();

我先註釋掉DisableSetUnhandledExceptionFilter();這句代碼,並在其後面加上pritf(NULL);這句代碼,如下所示

    SetUnhandledExceptionFilter(UnhandledExceptionFunction);
    //DisableSetUnhandledExceptionFilter();
    printf(NULL);

然後運行程序,發現DUMP的確沒有生成。於是我把DisableSetUnhandledExceptionFilter();的註釋去掉,如下所示

    SetUnhandledExceptionFilter(UnhandledExceptionFunction);
    DisableSetUnhandledExceptionFilter();
    printf(NULL);

再次運行程序,發現生成了DUMP,問題解決。

以上就是我對“程序閃退,沒有生成DUMP文件”的一點總結。至於程序究竟是不是因爲CRT的異常出現閃退,還得等測試的同事再次重現異常纔可以,希望這次能捕捉到DUMP吧

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章