Windows下 dmp文件的產生


一、windows下的崩潰捕獲
windows程序當遇到異常,沒有try-catch或者try-catch也無法捕獲到的異常時,程序就會自動退出。windows系統默認是不產生程序dmp文件的。
dump文件是C++程序發生異常時,保存當時程序運行狀態的文件,是調試異常程序重要的方法。

1. 產生dmp的三種方式:

方法一: 使用windows系統api,在要捕獲dmp文件的程序代碼中添加即可

復制代碼
#include "windows.h"
#include "DbgHelp.h"

//ANSI轉化成UNICODE
LPWSTR ANSITOUNICODE(const char* pBuf)
{
    int lenA = lstrlenA(pBuf);
    int lenW=0;
    LPWSTR lpszFile;
    lenW = MultiByteToWideChar(CP_ACP,0,pBuf,lenA,0,0);    
    if(lenW > 0)
    {
        lpszFile = SysAllocStringLen(0,lenW);    //申請一個指定字符長度的 BSTR 指針,並初始化為一個字符串
        MultiByteToWideChar(CP_ACP,0,pBuf,lenA,lpszFile,lenW);    //
    }
    return lpszFile;
} 
typedef    BOOL (WINAPI * MINIDUMP_WRITE_DUMP)(
    IN HANDLE            hProcess,
    IN DWORD            ProcessId,
    IN HANDLE            hFile,
    IN MINIDUMP_TYPE    DumpType,
    IN CONST PMINIDUMP_EXCEPTION_INFORMATION    ExceptionParam, OPTIONAL
    IN PMINIDUMP_USER_STREAM_INFORMATION        UserStreamParam, OPTIONAL
    IN PMINIDUMP_CALLBACK_INFORMATION            CallbackParam OPTIONAL
    );
void CreateDumpFile(LPCWSTR lpstrDumpFilePathName, EXCEPTION_POINTERS *pException)
{
    // 創建Dump文件    
    HANDLE hDumpFile = CreateFile(lpstrDumpFilePathName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    // Dump信息
    MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
    dumpInfo.ExceptionPointers = pException;
    dumpInfo.ThreadId = GetCurrentThreadId();
    dumpInfo.ClientPointers = TRUE;
    MINIDUMP_WRITE_DUMP    MiniDumpWriteDump_;
    HMODULE hDbgHelp = LoadLibrary(ANSITOUNICODE("DBGHELP.DLL"));
    MiniDumpWriteDump_ = (MINIDUMP_WRITE_DUMP)GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
    MiniDumpWriteDump_(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);
    CloseHandle(hDumpFile);
}
// 處理Unhandled Exception的回調函數
LONG ApplicationCrashHandler(EXCEPTION_POINTERS *pException)
{    
    QDir temp;
    QString errorPath;
    bool exist = temp.exists(QCoreApplication::applicationDirPath()+"/Log");
    if(!exist)        
    {
        bool ok = temp.mkdir(QCoreApplication::applicationDirPath()+"/Log");
        if(!ok)    //失敗 放在執行路徑下
            errorPath = QCoreApplication::applicationDirPath()+QString("/%1崩潰日志.dmp").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh.mm.ss"));
    }
    errorPath = QCoreApplication::applicationDirPath()+QString("/Log/%1崩潰日志.dmp").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh.mm.ss"));
    // 這里彈出一個錯誤對話框並退出程序
    CreateDumpFile(ANSITOUNICODE(errorPath.toStdString().c_str()), pException);  
    FatalAppExit(-1, ANSITOUNICODE("*** 未知 錯誤! ***"));
    return EXCEPTION_EXECUTE_HANDLER;
}
int main(int argc, char *argv[])
{
    SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationCrashHandler);   
    QApplication a(argc, argv);
    TestWidget w;
    w.showMaximized();
    return a.exec();
}
復制代碼

 

將上述代碼 可以移植到任何windows程序中使用即可。


方法二: 修改注冊表

1. 打開dmp文件生成:
使用管理員權限,執行一下腳本內容,運行后: 任何程序崩潰都會在C:\CrashDump 產生dmp文件(full dmp)。

復制代碼
@echo 啟用Dump
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps"
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpFolder /t REG_EXPAND_SZ /d "C:\CrashDump" /f
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpType /t REG_DWORD /d 2 /f
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpCount /t REG_DWORD /d 10 /f
@echo Dump已經啟用
復制代碼

 

 

 

 


2. 關閉dmp的生成:
管理員權限執行以下腳本修改注冊表信息:

@echo 關閉Dump
reg delete "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /f
@echo Dump已經關閉

 

3. 注冊表中Windows Error Reporting\LocalDumps (WER)下字段說明:

復制代碼
在他下面創建一個項,名字為你要檢測的程序名。 
此項中需要4個值配置
值:DumpFolder, 類型:REG_EXPAND_SZ - 就是存儲dump的位置
值:DumpCount, 類型:REG_DWORD - 最大保留的dump個數,默認為10.
值:DumpType, 類型:REG_DWORD - Dump類型,0:Custom dump, 1: Mini dump, 2: Full dump. 默認值為1
值:CustomDumpFlags, 類型:REG_DWORD - 沒怎么用。
啟動Windows Error Reporting Server服務
服務啟動后如果相應程序出現了崩潰的情況,WER就會自動將Crash Dump保存到指定的目錄
注意:
(1)Windows Error Reporting Server服務每當觸發一次dump,就會變成非啟動狀態,因此在設置此服務時,應當設置啟動類型為自動。
(2)在配置WER時,需要注意的是Count大小的設置,如果dmp文件個數超過Count的個數,會進行滾動覆蓋,即新的dmp會覆蓋舊的dmp。
復制代碼

 

方法三:手動創建轉儲文件

  當windows應用程序出現無響應時,可以打開任務管理器,找到無響應的進程,右鍵選擇創建轉儲文件即可,即生成崩潰對應的dmp文件,該文件一般位於 C:\Users\happy\AppData\Local\Temp目錄。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM