程序崩溃处理方法二(分析dmp文件,无法在现场调试,只能拷回运行出错时记录的文件)

一 使用场景:

  当可执行程序在现场跑崩溃时,线程不能调试,此时就得就要考虑让程序崩溃时产生dmp文件,然后拷回来调试,dmp里面记录出错时的记录。

二 如何产生dmp文件,

  以下为示范代码(VS2013),代码开始时调用SetUnhandledExceptionFilter(&MyUnhandledFilter);,出错时就会产生dmp文件,本实例中会产生errorData.dmp

#include "stdafx.h"
#include"windows.h"
#include <DbgHelp.h>
#include<iostream>
#include <direct.h>
#pragma comment(lib,"User32.lib")
#pragma comment(lib, "DbgHelp.Lib")

struct Object
{
    int id;
    char name[32];
};
void show(Object* p)
{
    printf("Object [%d, %s] 
", p->id, p->name);
}

LONG WINAPI MyUnhandledFilter(struct _EXCEPTION_POINTERS *lpExceptionInfo)
{
    LONG ret = EXCEPTION_EXECUTE_HANDLER;
    SYSTEMTIME st;
    CHAR szFileName[_MAX_PATH];
    WCHAR szFileName1[_MAX_PATH];
    ::GetLocalTime(&st);

    _getcwd(szFileName, _MAX_PATH);
    strcat(szFileName, "\errorData.dmp");
    //将char *转为WCHAR *
    MultiByteToWideChar(CP_ACP, 0, szFileName, strlen(szFileName) + 1, szFileName1, sizeof(szFileName1) / sizeof(szFileName1[0]));
    //创建dmp文件
    HANDLE hFile = ::CreateFile(szFileName1, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile != INVALID_HANDLE_VALUE)
    {
        MINIDUMP_EXCEPTION_INFORMATION ExInfo;
        ExInfo.ThreadId = ::GetCurrentThreadId();
        ExInfo.ExceptionPointers = lpExceptionInfo;
        ExInfo.ClientPointers = false;
        // 往dmp文件中写出错时的信息
        BOOL bOK = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL);
        ::CloseHandle(hFile);
    }
    else
    {
        std::cout << "创建文件失败!" << std::endl;
    }
    return ret;
}


int _tmain(int argc, _TCHAR* argv[])
{
    SetUnhandledExceptionFilter(&MyUnhandledFilter);

    Object* obj = NULL;
    show(obj); //<--空指针

    system("pause");
    return 0;
}
View Code

  上面的示范代码如果生成可执行程序放到现场就会出错(使用空指针),将现场生成的.exe      .pdb和.dmp拷回。

例如:

三:复现出错时的场景

  (1)将errorData.dmp文件用VS打开

  (2)点击右边的“使用仅限本机进行调试,点击完后,直接跳转到出错时的那一行。

111
原文地址:https://www.cnblogs.com/zwj-199306231519/p/13660925.html