MFC设置和使用dump在release模式下查找闪退位置《转》亲测有效!

本文是讲 用VS如何调试.dmp(比较高版本的VS,本文是vs2017):
人为制造一个崩溃,先直接看效果图:

下面是实现过程,本文是VS2017为例:
dump.h:

点击查看代码
#pragma once
// dump.h
#include <windows.h>
extern LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS lpExceptionInfo);

dump.cpp:

点击查看代码
// dump.cpp
#include <stdio.h>
#include <windows.h>
#include <dbghelp.h>
#include <stdlib.h>
#include "pch.h" //这行看你工程设置,可以去掉

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

#include <DbgHelp.h>

//Creatte DUMP File
int GenerateMiniDump(HANDLE hFile, PEXCEPTION_POINTERS pExceptionPointers, PWCHAR pwAppName)
{
	BOOL bOwnDumpFile = FALSE;
	HANDLE hDumpFile = hFile;
	MINIDUMP_EXCEPTION_INFORMATION ExpParam;

	typedef BOOL(WINAPI * MiniDumpWriteDumpT)(
		HANDLE,
		DWORD,
		HANDLE,
		MINIDUMP_TYPE,
		PMINIDUMP_EXCEPTION_INFORMATION,
		PMINIDUMP_USER_STREAM_INFORMATION,
		PMINIDUMP_CALLBACK_INFORMATION
		);


	MiniDumpWriteDumpT pfnMiniDumpWriteDump = NULL;
	HMODULE hDbgHelp = LoadLibrary(L"DbgHelp.dll");
	if (hDbgHelp)
		pfnMiniDumpWriteDump = (MiniDumpWriteDumpT)GetProcAddress(hDbgHelp, "MiniDumpWriteDump");

	if (pfnMiniDumpWriteDump)
	{
		if (hDumpFile == NULL || hDumpFile == INVALID_HANDLE_VALUE)
		{
			TCHAR szFileName[MAX_PATH] = { 0 };
			TCHAR dwBufferSize = MAX_PATH;
			SYSTEMTIME stLocalTime;
			GetLocalTime(&stLocalTime);
			CreateDirectory(szFileName, NULL);

			wsprintf(szFileName, L"%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp",
				L"v1.0",
				stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
				stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond,
				GetCurrentProcessId(), GetCurrentThreadId());
			hDumpFile = CreateFile(szFileName, GENERIC_READ | GENERIC_WRITE,
				FILE_SHARE_WRITE | FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
			bOwnDumpFile = TRUE;
			OutputDebugString(szFileName);
		}
		if (hDumpFile != INVALID_HANDLE_VALUE)
		{
			ExpParam.ThreadId = GetCurrentThreadId();
			ExpParam.ExceptionPointers = pExceptionPointers;
			ExpParam.ClientPointers = FALSE;
			pfnMiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
				hDumpFile, MiniDumpWithDataSegs, (pExceptionPointers ? &ExpParam : NULL), NULL, NULL);
			if (bOwnDumpFile)
				CloseHandle(hDumpFile);
		}
	}
	if (hDbgHelp != NULL)
		FreeLibrary(hDbgHelp);
	return EXCEPTION_EXECUTE_HANDLER;
}

LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS lpExceptionInfo)
{
	if (IsDebuggerPresent())
	{
		return EXCEPTION_CONTINUE_SEARCH;
	}
	return GenerateMiniDump(NULL, lpExceptionInfo, PWCHAR("test"));
}

//用到的地方加入这个头文件
#include "dump.h"

//程序初始化时,加入这个代码:
::SetUnhandledExceptionFilter(ExceptionFilter);

人为制造一个崩溃:
int *pTest = NULL; (*pTest) = 1;

Release版设置:


VS 工具(T) ->选项(O)…:

把这个.dmp文件,直接用VS打开:

定位到了出错的代码行:

发布时,主要是 4个要素:
1、.exe文件(或.dll)
2、对应的.pdb文件
3、崩溃后的.dmp文件
4、对应的结点代码(当时编译出这个exe/dll的代码,提前留个备份,比如 SVN / git 上的结点、代码打包rar/zip的备份、代码文件夹备份……)

本文主体内容至此已完结,下面有兴趣可以研究一下,那 4个要素 的对应过程:
首先,一个独立的.dmp,用vs打开,使用调试,会发生什么?

好,然后把这个 .exe放到.dmp同目录下,再调试:

好,然后再把这个.pdb放到.dmp同目录下,再调试:

找到这个.cpp,并把这个文件小改动一下保存:

在刚VS的打开.cpp对话框中,打开这个.cpp:
先选择否,把刚.cpp还原至发布时(即去掉刚加入的那个空格,再保存),再用VS重新打开这个.cpp:

这下明白了那 4要素 的作用了吧?

————————————————
版权声明:本文为CSDN博主「maoyeahcom」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/maoyeahcom/article/details/108583124

posted @ 2022-05-17 00:17  你的代码能改变世界吗  阅读(696)  评论(0编辑  收藏  举报