VC++ Dump文件生成&分析

*爱你&永不变心* 提交于 2019-12-24 14:42:37

请看示例(图1):

很明显,在代码行108行有一个对空指针p的赋值操作,在IDE环境下运行,结果如下(图2):

提示p是nullptr。一位曾经工作于中科院的学者告诉我,程序运行过程中出现错误提示,90%都是错误指针(空指针、野指针)引起的,鉴于多年工作经验的总结,对于这一点我深信无疑。IDE环境下运行,我们很容易发现和解决类似这种错误,但是如果我们脱离IDE运行,一般都会提示0xC0000005错误提示对话框,这个时候要解决这种问题就有些茫然了,手足无措,不知如何下手了。要解决类似这种问题,我们需要借助应用程序异常调试信息记录文件CrashDump文件,那么我们如何来生成这样的文件呢?请看修改后的代码:

void ExpTest5() { char *p = NULL; p[0] = 0; }
void ExpTest4() { ExpTest5(); }
void ExpTest3() { ExpTest4(); }
void ExpTest2() { ExpTest3(); }
void ExpTest1() { ExpTest2(); }

#include <dbgHelp.h>
#pragma comment(lib, "dbghelp.lib")
void WINAPI WriteCrashDumpFile(_EXCEPTION_POINTERS * pExInfo, _MINIDUMP_TYPE WriteFlag)
{
	//analyze -v 自动分析
	//.ecxr  转到源码
	if (pExInfo == NULL)
		RaiseException(EXCEPTION_BREAKPOINT, 0, 0, NULL);

	char lpszModuleFilePath[MAX_PATH];
	GetModuleFileName(NULL, lpszModuleFilePath, MAX_PATH);
	(_tcsrchr(lpszModuleFilePath, '.'))[0] = 0;
	strcat_s(lpszModuleFilePath, ".dump");

	MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
	dumpInfo.ThreadId = ::GetCurrentThreadId();
	dumpInfo.ExceptionPointers = pExInfo;
	dumpInfo.ClientPointers = TRUE;
	HANDLE hCrashFile = ::CreateFile(lpszModuleFilePath, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hCrashFile != INVALID_HANDLE_VALUE)
	{
		BOOL bWrite = ::MiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(), hCrashFile, WriteFlag, &dumpInfo, NULL, NULL);
		if (bWrite)
			::FlushFileBuffers(hCrashFile);
	}

	CloseHandle(hCrashFile);
	hCrashFile = NULL;
}

LONG WINAPI HandledExpFilter(_EXCEPTION_POINTERS *lpExceptionInfo)
{
	WriteCrashDumpFile(lpExceptionInfo, MiniDumpWithFullMemory);
	return EXCEPTION_EXECUTE_HANDLER;
}

void TestExceptionWalking()
{
	__try
	{
		ExpTest1();
	}
	__except (HandledExpFilter(GetExceptionInformation()))
	{
	}
}

int _tmain()
{
	TestExceptionWalking();
	system("pause");
	return 0;
}

这样在我们的exe相同工作目录下就会生成一个后缀名为dump的文件,我们用IDE打开这个dump文件(图3):

选择“使用 仅限本机 进行调试”,这个时候会跳转到错误代码行位置(图4):

 

 图4显示的错误描述和图2显示的错误描述一致,这样我们就可以通过dump文件很方便解决这种类似错误问题。

注意:要实现在IDE定位到错误代码位置,除了要借助这个dump问题,其中还有一个很重要的文件pdb文件(程序数据库文件)。Debug环境下,编译会自动产生pdb文件,但是Release模式下,就需要我们手动来打开这个选项了,如图5:

这样一个通过IDE环境下应用程序异常处理方案就介绍完了。说到异常处理机制,肯定要讲解下轻量级调试软件WinDbg,下一遍将简单介绍WinDbg如何来处理类似问题。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!