Windows下收集崩溃信息C++代码MiniDump

xingyun86 2021-7-5 886

Windows下收集崩溃信息C++代码

// MiniDump.h : include file for standard system include files,
// or project specific include files
//
#pragma once
#include <tchar.h>
#include <stdio.h>
#include <winsock2.h>
#include <dbghelp.h>
class MiniDump {
    typedef BOOL(WINAPI* PFN_MiniDumpWriteDump)(HANDLE hProcess,
        DWORD dwPid,
        HANDLE hFile,
        MINIDUMP_TYPE DumpType,
        CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
        CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
        CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
	CRITICAL_SECTION m_CriticalSection = { 0 };
public:
    MiniDump() {
		// The SetUnhandledExceptionFilter function enables an application to 
		// supersede the top-level exception handler of each thread and process.
		// After calling this function, if an exception occurs in a process 
		// that is not being debugged, and the exception makes it to the 
		// unhandled exception filter, that filter will call the exception 
		// filter function specified by the lpTopLevelExceptionFilter parameter.
		SetUnhandledExceptionFilter(UnhandledExceptionHandler);
		// Since DBGHELP.dll is not inherently thread-safe, making calls into it 
		// from more than one thread simultaneously may yield undefined behavior. 
		// This means that if your application has multiple threads, or is 
		// called by multiple threads in a non-synchronized manner, you need to  
		// make sure that all calls into DBGHELP.dll are isolated via a global
		// critical section.
		InitializeCriticalSection(&m_CriticalSection);
	}
    virtual ~MiniDump() {
        DeleteCriticalSection(&m_CriticalSection);
    }
private:
    static LONG WINAPI UnhandledExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo) {
		MiniDump * thiz = MiniDump::Init();
		if (thiz == NULL)
		{
			return EXCEPTION_CONTINUE_SEARCH;
		}
		return thiz->WriteMiniDump(pExceptionInfo);
	}
	LONG WriteMiniDump(PEXCEPTION_POINTERS pExceptionInfo) {
		LONG lRetValue = EXCEPTION_CONTINUE_SEARCH;
		// You have to find the right dbghelp.dll. 
		// Look next to the EXE first since the one in System32 might be old (Win2k)
		HANDLE hMiniDumpFile = NULL;
		HMODULE hModuleDbgHelp = NULL;
		TCHAR szModuleFilePath[MAX_PATH] = { 0 };
		TCHAR szMiniDumpFilePath[MAX_PATH] = { 0 };
		PFN_MiniDumpWriteDump MiniDumpWriteDump = NULL;
		MINIDUMP_EXCEPTION_INFORMATION ExceptionInfo = { 0 };
		GetModuleFileName(NULL, szModuleFilePath, _MAX_PATH);
		// If we haven't found it yet - try one more time.
		hModuleDbgHelp = LoadLibrary(TEXT("DBGHELP"));
		if (hModuleDbgHelp != NULL)
		{
			// Get the address of the MiniDumpWriteDump function, which writes 
			// user-mode mini-dump information to a specified file.
			MiniDumpWriteDump = (PFN_MiniDumpWriteDump)GetProcAddress(hModuleDbgHelp, "MiniDumpWriteDump");
		}
		if (MiniDumpWriteDump != NULL)
		{
			ExceptionInfo.ThreadId = GetCurrentThreadId();
			ExceptionInfo.ExceptionPointers = pExceptionInfo;
			ExceptionInfo.ClientPointers = NULL;
			wsprintf(szMiniDumpFilePath, TEXT("%s.dmp"), szModuleFilePath);
			// Create the mini-dump file...
			hMiniDumpFile = CreateFile(szMiniDumpFilePath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
			if (hMiniDumpFile != INVALID_HANDLE_VALUE)
			{
				// DBGHELP.dll is not thread-safe, so we need to restrict access...
				EnterCriticalSection(&m_CriticalSection);
				// Write out the mini-dump data to the file...
				if (MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hMiniDumpFile, MiniDumpNormal, &ExceptionInfo, NULL, NULL) == TRUE)
				{
					lRetValue = EXCEPTION_EXECUTE_HANDLER;
				}
				LeaveCriticalSection(&m_CriticalSection);
				CloseHandle(hMiniDumpFile);
				hMiniDumpFile = NULL;
			}
		}
		return lRetValue;
	}
public:
	static MiniDump* Init() {
		static MiniDump MiniDumpInstance;
		return &MiniDumpInstance;
	}
};


×
打赏作者
最新回复 (0)
只看楼主
全部楼主
返回