windows环境C++抓取dump信息

Minidump文件生成

  1、Minidump概念

    minidump(小存储器转储)可以理解为一个dump文件,里面记录了能够帮助调试crash的最小有用信息。实际上,如果你在系统属性 -> 高级 -> 启动和故障恢复 -> 设置 -> 写入调试信息中选择“小内存转储(64 KB)”的话,当系统意外停止时都会在C:\Windows\Minidump\路径下生成一个.dmp后缀的文件,这个文件就是minidump文件,只不过这个是内核态的minidump。

   我们要生成的是用户态的minidump,文件中包含了程序运行的模块信息、线程信息、堆栈调用信息等。而且为了符合其mini的特性,dump文件是压缩过的。

2、生成minidump文件

       通过drwtsn32、NTSD、CDB等调试工具生成Dump文件, drwtsn32存在的缺点虽然NTSD、CDB可以完全解决,但并不是所有的操作系统中都安装了NTSD、CDB等调试工具。根据MiniDumpWriteDump接口,完全可以程序自动生成Dump文件。

3、  自动生成Minidump文件

当程序遇到未处理异常(主要指非指针造成)导致程序崩溃死,如果在异常发生之前调用了SetUnhandledExceptionFilter()函数,异常交给函数处理。因而,在程序开始处增加SetUnhandledExceptionFilter()函数,并在函数中利用适当的方法生成Dump文件,即可实现需要的功能。

1、开启生成Dump文件

void RunCrashHandler()
{
    // 设置产生奔溃dump文件功能 // WINAPI
    SetUnhandledExceptionFilter(UnhandledExceptionFilterEx); // 添加回调
    PreventSetUnhandledExceptionFilter();
}

SetUnhandledExceptionFilter() 这个函数的返回值有三种情况:

EXCEPTION_EXECUTE_HANDLER equ 1 表示我已经处理了异常,可以优雅地结束了  
EXCEPTION_CONTINUE_SEARCH equ 0 表示我不处理,于是windows调用默认的处理程序显示一个错误框,并结束  
EXCEPTION_CONTINUE_EXECUTION equ -1 表示错误已经被修复,请从异常发生处继续执行 

 2、指定dump文件名称等

void UnhandledExceptionFilterExImpl(struct _EXCEPTION_POINTERS *pException)
{
    // 日志按日期存储
    SYSTEMTIME tmCurrent;
    GetLocalTime(&tmCurrent);

    TCHAR szDumpFilePath[MAX_PATH] = { 0 };
    GetModuleFileName(0, szDumpFilePath, MAX_PATH);
    PTSTR pszTemp = _tcsrchr(szDumpFilePath, _T('\\'));
    if (pszTemp) {
        StringCchCopy(szLogFilePath, SIZE_ARRAY(szDumpFilePath), pszTemp + 1);
        pszTemp[1] = 0;
    } else {
        StringCchCopy(szLogFilePath,  SIZE_ARRAY(szLogFilePath), _T("Exception"));
    }
    TCHAR szDMPFileName[MAX_PATH];
    StringCchPrintf(szDMPFileName, MAX_PATH, _T("%s-%02d-%02d-%02d.dmp"),  szDumpFilePath, tmCurrent.wHour, tmCurrent.wMinute, tmCurrent.wSecond);
    CreateDumpFile(szDMPFileName, pException);
}

 3、生成dump文件

void CreateDumpFile(LPCTSTR lpstrDumpFilePathName, EXCEPTION_POINTERS *pException)  
{  
    // 创建Dump文件  
    HANDLE hDumpFile = CreateFile(lpstrDumpFilePathName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);  

    if (INVALID_HANDLE_VALUE != hDumpFile)
    {
        // Dump信息  
        MINIDUMP_EXCEPTION_INFORMATION ExInfo;
        if (pException)
        {
            ExInfo.ThreadId = ::GetCurrentThreadId();
            ExInfo.ExceptionPointers = pException;
            ExInfo.ClientPointers = TRUE;
        }

        // 写入Dump文件内容  // DbgHelp库函数
        MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpWithFullMemory, pException ? &ExInfo : NULL, NULL, NULL);
        CloseHandle(hDumpFile);  
    }
} 
BOOL PreventSetUnhandledExceptionFilter()
{
    HMODULE hKernel32 = LoadLibrary(_T("kernel32.dll"));
    if (hKernel32 ==   NULL)
        return FALSE;

    void *pOrgEntry = GetProcAddress(hKernel32, "SetUnhandledExceptionFilter");
    if(pOrgEntry == NULL)
        return FALSE;

    unsigned char newJump[ 100 ];
    DWORD dwOrgEntryAddr = (DWORD) pOrgEntry;
    dwOrgEntryAddr += 5; // add 5 for 5 op-codes for jmp far

    void *pNewFunc = &MyDummySetUnhandledExceptionFilter;
    DWORD dwNewEntryAddr = (DWORD) pNewFunc;
    DWORD dwRelativeAddr = dwNewEntryAddr -  dwOrgEntryAddr;

    newJump[ 0 ] = 0xE9;  // JMP absolute
    memcpy_s(&newJump[ 1 ], sizeof(newJump) - 1, &dwRelativeAddr, sizeof(pNewFunc));
    SIZE_T bytesWritten;
    BOOL bRet = WriteProcessMemory(GetCurrentProcess(),    pOrgEntry, newJump, sizeof(pNewFunc) + 1, &bytesWritten);

    ::FreeLibrary(hKernel32);
    return bRet;
}

win7自动生成dump-----------------------------------------------------------------------------------------------------------------------------------------------------------------

win7下需打开regedit--> 找到:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting]

在它下面加一项LocalDumps,并做如下项配置:

Value描述Type默认值
DumpFolder文件保存路径REG_EXPAND_SZ%LOCALAPPDATA%CrashDumps
DumpCountdump文件的最大数目REG_DWORD10
DumpType指定生成的dump类型:
0:Custom dump
1:Mini dump
2:Full dump
REG_DWORD1
CustomDumpFlags仅在DumpType为0时使用
为MINIDUMP_TYPE的组合
REG_DWORD
MiniDumpWithDataSegs|
MiniDumpWithUnloadedModules|
MiniDumpWithProcessThreadData

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:\MyDump" /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 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值