/*
** Copyright (C) QPSOFT.COM All rights reserved.
*/
#ifndef INCLUDE_MINIDUMPER_H_
#define INCLUDE_MINIDUMPER_H_
#ifdef _MSC_VER
#include <string>
#include <windows.h>
#include <tchar.h>
#pragma comment(lib, "dbghelp.lib")
#include <dbghelp.h>
#pragma comment(lib, "user32.lib")
#include <shlwapi.h>
#pragma comment(lib, "shlwapi.lib")
namespace Dbg
{
typedef std::string StringA;
typedef std::wstring StringW;
#ifdef _UNICODE
typedef StringW String;
#else
typedef StringA String;
#endif // _UNICODE
typedef BOOL (WINAPI* PFNWRITEDUMP)(HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, PMINIDUMP_EXCEPTION_INFORMATION,
PMINIDUMP_USER_STREAM_INFORMATION, PMINIDUMP_CALLBACK_INFORMATION);
class MiniDumper
{
protected:
MiniDumper() { ::SetUnhandledExceptionFilter(&MiniDumper::TopLevelExceptionFilter); }
~MiniDumper() {};
private:
MiniDumper(const MiniDumper&);
const MiniDumper& operator=(const MiniDumper&);
public:
static MiniDumper* Get()
{
static MiniDumper dumper;
return &dumper;
}
void Init(const String& dumpFilePath = String(), const String& appVersion = _T("1.0.0.0"))
{
if (!dumpFilePath.empty() && ::PathIsDirectory(dumpFilePath.c_str()))
m_DumpFilePath = dumpFilePath;
else
{
TCHAR appPath[MAX_PATH];
::GetModuleFileName(NULL, appPath, MAX_PATH);
::PathRemoveFileSpec(appPath);
m_DumpFilePath = appPath;
}
m_AppVersion = appVersion;
}
String GetDumpFile() const
{
SYSTEMTIME st;
::GetLocalTime(&st);
TCHAR dt[11];
wsprintf(dt, _T("%02d%02d%02d%02d%02d"), st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
TCHAR appPath[MAX_PATH];
::GetModuleFileName(NULL, appPath, MAX_PATH);
::PathRemoveExtension(appPath);
String file(m_DumpFilePath);
file += _T("\\");
file += ::PathFindFileName(appPath);
file += _T("_") + m_AppVersion + _T("_");
file += dt;
file += _T(".dmp");
return file;
}
private:
static LONG WINAPI TopLevelExceptionFilter(struct _EXCEPTION_POINTERS* ep)
{
LONG ret = EXCEPTION_CONTINUE_SEARCH;
TCHAR dbgHelpDLL[MAX_PATH];
::GetModuleFileName(NULL, dbgHelpDLL, MAX_PATH);
::PathRemoveFileSpec(dbgHelpDLL);
::PathAppend(dbgHelpDLL, _T("dbghelp.dll"));
HMODULE module = ::LoadLibrary(dbgHelpDLL);
if (module == NULL)
{
::MessageBox(NULL, _T("提示"), _T("缺少dbghelp.dll"), MB_TOPMOST | MB_ICONSTOP);
return ret;
}
PFNWRITEDUMP MiniDumpWriteDump = (PFNWRITEDUMP)::GetProcAddress(module, "MiniDumpWriteDump");
if (MiniDumpWriteDump != NULL)
{
String dumpFile = MiniDumper::Get()->GetDumpFile();
HANDLE file = ::CreateFile(dumpFile.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if (file == INVALID_HANDLE_VALUE)
return ret;
_MINIDUMP_EXCEPTION_INFORMATION mdei;
mdei.ThreadId = ::GetCurrentThreadId();
mdei.ExceptionPointers = ep;
mdei.ClientPointers = NULL;
MINIDUMP_TYPE mdt = (MINIDUMP_TYPE)(MiniDumpWithPrivateReadWriteMemory |
MiniDumpWithDataSegs |
MiniDumpWithHandleData |
MiniDumpWithFullMemoryInfo |
MiniDumpWithThreadInfo /*|
MiniDumpWithUnloadedModules*/);
if (MiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(), file, mdt, &mdei, NULL, NULL))
{
::MessageBox(NULL, dumpFile.c_str(), _T("Crash Report!"), MB_TOPMOST | MB_ICONSTOP);
const String openDmp(_T("/select,") + dumpFile);
::ShellExecute(NULL, _T("open"), _T("explorer.exe"), openDmp.c_str(), NULL, SW_SHOWNORMAL);
ret = EXCEPTION_EXECUTE_HANDLER;
}
CloseHandle(file);
}
return ret;
}
private:
String m_DumpFilePath;
String m_AppVersion;
};
} // namespace qp
#endif // _MSC_VER
#endif // INCLUDE_MINIDUMPER_H_
使用Dbg::MiniDumper::Get()->Init(); 也可以指定路径和版本
本文由 Ryan 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为:
2018/01/12 14:24