Crash dump进程信息

梦想游戏人
目录:
C/C++

linux下 比较简单,这里不在说明,

windows下 相对复杂一点 SEH,用SetUnhandledExceptionFilter 来捕获 MiniDumpWriteDump 来写dmp文件,这种方法还不够完全,一些错误 一样无法捕获 比如 多次 delete ,可修改注册表  crash自动生成dmp 而不用代码去控制   结合代码控制 一起使用

#if _WIN32

#include <windows.h>
#include <dbghelp.h>
#pragma comment(lib, "dbghelp.lib")

void myInvalidParameterHandler(const wchar_t* expression,
	const wchar_t* function,
	const wchar_t* file,
	unsigned int line,
	uintptr_t pReserved)
{

	throw 1;
}

LONG CustomCrashHandledExceptionFilter(_EXCEPTION_POINTERS *ExceptionInfo)
{
	CHAR strDumpFile[MAX_PATH] = { 0 };
	SYSTEMTIME tm;
	HANDLE hFile = NULL;

	time_t rawtime;
	struct tm * t;
	time(&rawtime);
	t = localtime(&rawtime);

	sprintf(strDumpFile, "%d%s%d-%04d-%02d-%02d-%02d-%02d-%02d.dmp", sid, name.c_str(), g_Inner_id, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);

	hFile = CreateFileA(strDumpFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile != INVALID_HANDLE_VALUE)
	{
		MINIDUMP_EXCEPTION_INFORMATION ExInfo;
		ExInfo.ThreadId = GetCurrentThreadId();
		ExInfo.ExceptionPointers = ExceptionInfo;
		ExInfo.ClientPointers = NULL;
		BOOL bOK = MiniDumpWriteDump(
			GetCurrentProcess(),
			GetCurrentProcessId(),
			hFile,
			MiniDumpNormal,
			&ExInfo,
			NULL,
			NULL);

		CloseHandle(hFile);
	}
	return EXCEPTION_CONTINUE_SEARCH;
}
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI EmptySetUnhandledExceptionFilter(
	LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
{
	return NULL;
}

void myPurecallHandler(void)
{

	throw 1;
}

BOOL HookSetUnhandledExceptionFilter()
{
	HMODULE hKernel32 = LoadLibraryA(("kernel32.dll"));
	if (hKernel32 == NULL) return FALSE;
	void *pOrgEntry = GetProcAddress(hKernel32, "SetUnhandledExceptionFilter");
	if (pOrgEntry == NULL) return FALSE;
	unsigned char newJump[100];
	DWORD dwOrgEntryAddr = (DWORD)pOrgEntry;
	dwOrgEntryAddr += 5; // add 5 for 5 op-codes for jmp far
	void *pNewFunc = &EmptySetUnhandledExceptionFilter;
	DWORD dwNewEntryAddr = (DWORD)pNewFunc;
	DWORD dwRelativeAddr = dwNewEntryAddr - dwOrgEntryAddr;

	newJump[0] = 0xE9;  // JMP absolute
	memcpy(&newJump[1], &dwRelativeAddr, sizeof(pNewFunc));
	SIZE_T bytesWritten;
	BOOL bRet = WriteProcessMemory(GetCurrentProcess(),
		pOrgEntry, newJump, sizeof(pNewFunc) + 1, &bytesWritten);
	return bRet;
}

class CrashHandler
{
public:
	CrashHandler()
	{
	//	SetErrorMode(SEM_FAILCRITICALERRORS);
		SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)CustomCrashHandledExceptionFilter);
		_purecall_handler old_pure_handle;
		old_pure_handle = _set_purecall_handler(myPurecallHandler);
		_invalid_parameter_handler oldHandler;
		oldHandler = _set_invalid_parameter_handler(myInvalidParameterHandler);
		HookSetUnhandledExceptionFilter();
	}
};
#else
class CrashHandler
{
public:
	CrashHandler()
	{
		assert(false);
	}
};
#endif
Scroll Up