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