#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;//初始化变量,初始化只能放这下面,不能放顶上
Dump文件的生成和使用
最新推荐文章于 2024-02-06 17:32:45 发布