dump生成与分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010855021/article/details/75000487

来源:

软件发生异常,没有调试环境,怎么快速定位问题?遇到这类问题,最有的信息就是生成dump文件,然后通过dump文件查看callstack等信息定位。

 

Dump文件生成原理:

dbghelp使用SetUnhandledExceptionFilter设置回调函数生成dump文件,后分析异常地方。

本文实现方式:分装类在MFC程序中调用并分析

1、类的实现

//CreateDump.h
#pragma once
#include <string>
using namespace std;
class CCreateDump
{
public:
    CCreateDump();
    ~CCreateDump(void);
    static CCreateDump* Instance();
    static long __stdcall UnhandleExceptionFilter(_EXCEPTION_POINTERS* ExceptionInfo);
    //声明Dump文件,异常时会自动生成。会自动加入.dmp文件名后缀
    void DeclarDumpFile(std::string dmpFileName = "");
private:
    static std::string    strDumpFile; 
    static CCreateDump*    __instance;
};

//CreateDump.cpp
#include "stdafx.h"
#include "CreateDump.h"
#include <DbgHelp.h>
#pragma comment(lib,  "dbghelp.lib")

CCreateDump* CCreateDump::__instance = NULL;
std::string CCreateDump::strDumpFile = "";

CCreateDump::CCreateDump()
{
}

CCreateDump::~CCreateDump(void)
{
    
}

long  CCreateDump::UnhandleExceptionFilter(_EXCEPTION_POINTERS* ExceptionInfo)
{

    HANDLE hFile   =   CreateFileA(strDumpFile.c_str(),   GENERIC_WRITE,   FILE_SHARE_WRITE,   NULL,   CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,   NULL   );
    if(hFile!=INVALID_HANDLE_VALUE)
    {
        MINIDUMP_EXCEPTION_INFORMATION   ExInfo; 
        ExInfo.ThreadId   =   ::GetCurrentThreadId();
        ExInfo.ExceptionPointers   =   ExceptionInfo;
        ExInfo.ClientPointers   =   FALSE;
        //   write   the   dump
        BOOL   bOK   =   MiniDumpWriteDump(GetCurrentProcess(),   GetCurrentProcessId(),   hFile,   MiniDumpNormal,  &ExInfo,   NULL,   NULL   );
        CloseHandle(hFile);
        if (!bOK)
        {
            DWORD dw = GetLastError();
            //写dump文件出错处理,异常交给windows处理
            return EXCEPTION_CONTINUE_SEARCH;
        }
        else
        {    //在异常处结束
            return EXCEPTION_EXECUTE_HANDLER;
        }
    }
    else
    {
        return EXCEPTION_CONTINUE_SEARCH;
    }
}

void CCreateDump::DeclarDumpFile(std::string dmpFileName)
{
    SYSTEMTIME syt;
    GetLocalTime(&syt);
    char c[MAX_PATH];
    sprintf_s(c,MAX_PATH,"[%04d-%02d-%02d %02d:%02d:%02d]",syt.wYear,syt.wMonth,syt.wDay,syt.wHour,syt.wMinute,syt.wSecond);
    strDumpFile = std::string(c);
    if (!dmpFileName.empty())
    {
        strDumpFile += dmpFileName;
    }
    strDumpFile += std::string(".dmp");
    SetUnhandledExceptionFilter(UnhandleExceptionFilter);
}

CCreateDump* CCreateDump::Instance()
{
    if (__instance == NULL)
    {
        __instance = new CCreateDump;
    }
    return __instance;
}


2、调用和产生方式

在程序初始化时候调用:

CCreateDump::Instance()->DeclarDumpFile("dumpfile");

3写出异常代码

int a = 9;

int b = 0;

int c = 0;

c = a / b;

运行程序,并执行此处代码(运行目录下生成dump文件)

4、把dmp文件和exe, pdb文件放在同一目录下,然后用编译器(vc)打开dmp文件,然后开始调试就会中断到刚才异常的地方。

 
  

猜你喜欢

转载自blog.csdn.net/u010855021/article/details/75000487