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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章