Dump文件的生成和使用

#pragma once

#include <windows.h>
#include <DbgHelp.h>
#include <shlwapi.h>
#include <string>
#include <tchar.h>





class mimihDump
{
private://单列模式,构造私有
	mimihDump() {}
	static mimihDump* m_pInstance;//单列静态的变量

public:
	static mimihDump * GetInstance() {
		if (NULL == m_pInstance)//如果为空就new一个
			m_pInstance = new mimihDump;
		return m_pInstance;
	}

	typedef	BOOL(WINAPI *MINIDUMPWRITEDUMP)(// 定义函数指针
		HANDLE                            hProcess,
		DWORD                             ProcessId,
		HANDLE                            hFile,
		MINIDUMP_TYPE                     DumpType,
		PMINIDUMP_EXCEPTION_INFORMATION   ExceptionParam,
		PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
		PMINIDUMP_CALLBACK_INFORMATION    CallbackParam
		);

	inline void CreateMniDump(PEXCEPTION_POINTERS pEp, LPCTSTR strFileName)
	{// 从 "DbgHelp.dll" 库中获取 "MiniDumpWriteDump" 函数
		/*HINSTANCE*/HMODULE  hLib = NULL;
		hLib = ::LoadLibrary(TEXT("dbghelp.dll"));//加载"DbgHelp.dll" 库
		if (NULL == hLib)return;
		_MiniDumpWriteDump = (MINIDUMPWRITEDUMP)GetProcAddress(hLib, "MiniDumpWriteDump");//获取 "MiniDumpWriteDump" 函数
		if (NULL == _MiniDumpWriteDump) return;

		HANDLE hFile = CreateFile(strFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
			FILE_ATTRIBUTE_NORMAL, NULL);
		if (NULL != hFile && hFile != INVALID_HANDLE_VALUE)//
		{
			MINIDUMP_EXCEPTION_INFORMATION mdei;
			mdei.ThreadId = GetCurrentThreadId();
			mdei.ExceptionPointers = pEp;
			mdei.ClientPointers = FALSE;
			MINIDUMP_CALLBACK_INFORMATION mci;
			mci.CallbackRoutine = (MINIDUMP_CALLBACK_ROUTINE)mimihDump::MinidumpCallback;
			mci.CallbackParam = 0;
			MINIDUMP_TYPE mdt = (MINIDUMP_TYPE)(MiniDumpWithPrivateReadWriteMemory | MiniDumpWithDataSegs |
				MiniDumpWithHandleData | MiniDumpWithFullMemoryInfo |
				MiniDumpWithThreadInfo | MiniDumpWithUnloadedModules);
			//	_MiniDumpWriteDump(GetCurrentThread(),GetCurrentThreadId(),
			//	hFile, mdt,((NULL !=  pEp) ? (&mdei):NULL), NULL, &mci);
			_MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
				hFile, MiniDumpNormal, &mdei, NULL, &mci);// MiniDumpNormal

		}
		CloseHandle(hFile);
		FreeLibrary(hLib);
	}

	inline void init()//调用这个
	{
		std::wstring root_directory = TEXT("")/*根目录*/, dump_directory = TEXT("")/*dump目录*/;
		TCHAR szModuleFileName[_MAX_FNAME] = { 0 };
		TCHAR szFilePath[_MAX_FNAME] = { 0 };
		GetModuleFileName(NULL, szModuleFileName, _MAX_FNAME);
		_wsplitpath_s(szModuleFileName, NULL, 0, szFilePath, _MAX_FNAME, NULL, 0, NULL, 0);//只取文件路径
		root_directory = szFilePath;
		dump_directory = root_directory;//+ TEXT("\\dump\\");
		if (!PathFileExistsW(dump_directory.c_str()))
			CreateDirectoryW(dump_directory.c_str(), NULL);

		TCHAR szFileName[_MAX_FNAME] = { 0 };
		_wsplitpath_s(szModuleFileName, NULL, 0, NULL, 0, szFileName, _MAX_FNAME, NULL, 0);//从路径中取文件名
		_dump_file = dump_directory + szFileName + TEXT(".dmp");

		SetUnhandledExceptionFilter(mimihDump::GPTUnhandledExceptionFilter);
	}

	inline bool isDataSectionNeeded(const TCHAR* pModuleName)
	{
		if (NULL == pModuleName) return FALSE;
		TCHAR szFileName[_MAX_FNAME] = { 0 };
		_wsplitpath_s(pModuleName, NULL, 0, NULL, 0, szFileName, _MAX_FNAME, NULL, 0);//从路径中取文件名
		if (0 == _tcscmp(szFileName, TEXT("ntdll"))) return TRUE;
		return FALSE;
	}

	static	BOOL CALLBACK MinidumpCallback(PVOID pParam, PMINIDUMP_CALLBACK_INPUT pInput,
		PMINIDUMP_CALLBACK_OUTPUT pOutput)
	{
		if (NULL == pInput || NULL == pOutput) return false;
		switch (pInput->CallbackType)
		{
		case ModuleCallback:
			if (pOutput->ModuleWriteFlags& ModuleWriteCodeSegs)
				if (!mimihDump::GetInstance()->isDataSectionNeeded(pInput->Module.FullPath))
					pOutput->ModuleWriteFlags &= (~ModuleWriteDataSeg);
		case IncludeModuleCallback:
		case IncludeThreadCallback:
		case ThreadCallback:
		case ThreadExCallback:
			return TRUE;
		default:
			break;
		}
	}

	std::wstring getdumpfile() { return _dump_file; }
	static	LONG WINAPI GPTUnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo)
	{
		mimihDump::GetInstance()->CreateMniDump(pExceptionInfo,
			/*(LPCWSTR)	*/mimihDump::GetInstance()->getdumpfile().c_str());
		exit(pExceptionInfo->ExceptionRecord->ExceptionCode);
	}

	char* wcharToChar(const wchar_t* wch)//多字节与宽字节间的转换
	{
		char* pchar;
		int len = WideCharToMultiByte(CP_ACP, 0, wch, wcslen(wch), NULL, 0, NULL, NULL);
		pchar = new char[len + 1];
		WideCharToMultiByte(CP_ACP, 0, wch, wcslen(wch), pchar, len, NULL, NULL);
		pchar[len] = '\0';
		return pchar;
	}

protected:
private:
	std::wstring _dump_file;
	MINIDUMPWRITEDUMP _MiniDumpWriteDump;


};

mimihDump* mimihDump::m_pInstance = NULL;//初始化变量,初始化只能放这下面,不能放顶上

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值