栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

VS2013生成及调试dump文件

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

VS2013生成及调试dump文件

在程序崩溃时,需要对异常的情况进行捕获,并捕获到的堆栈信息保持下来。Windows操作系统提供了一个API函数可以在程序crash之前有机会处理这些异常并生成dump文件。通过VS2013编辑器调试dump文件能快速定位到程序崩溃处的代码。

一、Windows API函数介绍

LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilter ( _In_LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
) ;

参数:lpTopLevelExceptionFilter ,函数指针。当异常发生时,且程序不处于调试模式(在vs或者别的调试器里运行)则首先调用该函数。

返回值:返回以前设置的回调函数。

注意:在调用者进程中的所有线程已经将来创建的线程的异常处理链顶函数都会被修改为当前设定的回调函数。

二、demo代码

#include "stdafx.h"
#include 

#include 
using namespace std;

#pragma comment(lib, "Dbghelp.lib")
#include 

namespace DumpFile
{
	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;

		// 写入Dump文件内容   
		MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);

		CloseHandle(hDumpFile);
	}


	LPTOP_LEVEL_EXCEPTION_FILTER WINAPI MyDummySetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
	{
		return NULL;
	}

	BOOL PreventSetUnhandledExceptionFilter()
	{
		HMODULE hKernel32 = LoadLibrary(L"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(&newJump[1], &dwRelativeAddr, sizeof(pNewFunc));
		SIZE_T bytesWritten;
		BOOL bRet = WriteProcessMemory(GetCurrentProcess(), pOrgEntry, newJump, sizeof(pNewFunc) + 1, &bytesWritten);
		return bRet;
	}

	LONG WINAPI UnhandledExceptionFilterEx(struct _EXCEPTION_POINTERS *pException)
	{
		TCHAR szFileName[MAX_PATH] = { 0 };
		SYSTEMTIME stLocalTime;
		GetLocalTime(&stLocalTime);
		wsprintf(szFileName, L"%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp",
			stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
			stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond,
			GetCurrentProcessId(), GetCurrentThreadId());

		CreateDumpFile(szFileName, pException);
		MessageBox(NULL, L"      运行中出现错误!   ", L"123456", MB_OK);

		FatalExit(-1);
		return EXCEPTION_CONTINUE_SEARCH;
	}

	void RunCrashHandler()
	{
		SetUnhandledExceptionFilter(UnhandledExceptionFilterEx);
		PreventSetUnhandledExceptionFilter();
	}
};

#define ExceptionDumpFile() DumpFile::RunCrashHandler();

int _tmain(int argc, _TCHAR* argv[])
{
	ExceptionDumpFile();
	char* a = nullptr;
	*a = 1;
	return 0;
}

三、工程属性配置

1、打开工程->属性->链接器->调试->生成调试信息,修改成【是】(如下图)。

 2、打开工程->属性->C/C++->常规->调试信息格式,修改成【程序数据库】(如下图)。注意:如果在这里不修改成【程序数据库】,在调试dump文件时无法定位到源文件代码中的。

 四、VS2013调试dump文件

1、用VS2013打开dump文件,选择【设置符号路径】->【调试】->【符号】,把pdb、exe、dll文件路径添加到下图位置中。

 2、添加源代码文件

1、选择【视图】->【解决方案资源管理器】,把解决方案生成出来。如下图:

2、选择【解决方案】->右键->【属性】->【调试源文件】,添加源文件所在目录添加到下图所示位置中。

源码工程路径:https://download.csdn.net/download/jgliuhui1988/85330167

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/868968.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号