windows mini dump file

参考网络资料及源码整理:

头文件

#ifndef _H_WIN_DUMP_H_
#define _H_WIN_DUMP_H_
#include 
#include 
#pragma comment( lib, "DbgHelp" )
//
//DO NOT CARE THINGS
TCHAR DUMP_FILE_NAME[512] = {0};
#if defined _M_X64 || defined _M_IX86
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI 
MyDummySetUnhandledExceptionFilter(
								   LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
{
	return NULL;
}
#else
#error "This code works only for x86 and x64!"
#endif

BOOL PreventSetUnhandledExceptionFilter()
{
	HMODULE hKernel32 = LoadLibrary(_T("kernel32.dll"));
	if (hKernel32 == NULL) return FALSE;
	void *pOrgEntry = GetProcAddress(hKernel32, 
		"SetUnhandledExceptionFilter");
	if(pOrgEntry == NULL) return FALSE;

	DWORD dwOldProtect = 0;
	SIZE_T jmpSize = 5;
#ifdef _M_X64
	jmpSize = 13;
#endif
	BOOL bProt = VirtualProtect(pOrgEntry, jmpSize, 
		PAGE_EXECUTE_READWRITE, &dwOldProtect);
	BYTE newJump[20];
	void *pNewFunc = &MyDummySetUnhandledExceptionFilter;
#ifdef _M_IX86
	DWORD dwOrgEntryAddr = (DWORD) pOrgEntry;
	dwOrgEntryAddr += jmpSize; // add 5 for 5 op-codes for jmp rel32
	DWORD dwNewEntryAddr = (DWORD) pNewFunc;
	DWORD dwRelativeAddr = dwNewEntryAddr - dwOrgEntryAddr;
	// JMP rel32: Jump near, relative, displacement relative to next instruction.
	newJump[0] = 0xE9;  // JMP rel32
	memcpy(&newJump[1], &dwRelativeAddr, sizeof(pNewFunc));
#elif _M_X64
	// We must use R10 or R11, because these are "scratch" registers 
	// which need not to be preserved accross function calls
	// For more info see: Register Usage for x64 64-Bit
	// http://msdn.microsoft.com/en-us/library/ms794547.aspx
	// Thanks to Matthew Smith!!!
	newJump[0] = 0x49;  // MOV R11, ...
	newJump[1] = 0xBB;  // ...
	memcpy(&newJump[2], &pNewFunc, sizeof (pNewFunc));
	//pCur += sizeof (ULONG_PTR);
	newJump[10] = 0x41;  // JMP R11, ...
	newJump[11] = 0xFF;  // ...
	newJump[12] = 0xE3;  // ...
#endif
	SIZE_T bytesWritten;
	BOOL bRet = WriteProcessMemory(GetCurrentProcess(),
		pOrgEntry, newJump, jmpSize, &bytesWritten);

	if (bProt != FALSE)
	{
		DWORD dwBuf;
		VirtualProtect(pOrgEntry, jmpSize, dwOldProtect, &dwBuf);
	}
	return bRet;
}

LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS* ExceptionInfo)
{
	//创建dump文件
	HANDLE lhDumpFile = CreateFile((LPCTSTR)DUMP_FILE_NAME, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL ,NULL);

	MINIDUMP_EXCEPTION_INFORMATION loExceptionInfo;
	loExceptionInfo.ExceptionPointers = ExceptionInfo;
	loExceptionInfo.ThreadId = GetCurrentThreadId();
	loExceptionInfo.ClientPointers = TRUE;
	//捕获异常写入dump文件
	MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),lhDumpFile, MiniDumpNormal, &loExceptionInfo, NULL, NULL);

	CloseHandle(lhDumpFile);

	return EXCEPTION_EXECUTE_HANDLER;
}

//Interface
BOOL SetMyUnhandledExceptionFilter(TCHAR* dumpName)
{
	memset(DUMP_FILE_NAME,0,sizeof(DUMP_FILE_NAME));
	_tcscpy_s(DUMP_FILE_NAME,sizeof(DUMP_FILE_NAME),dumpName);
	//为未捕获且引起崩溃异常注册捕获
	SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
	//防止编译器再次注册捕获,编译器默认会注册SetUnhandledExceptionFilter
	return PreventSetUnhandledExceptionFilter();
}

#endif

测试例子:

// test123.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "winDump.h"

int _tmain(int argc, _TCHAR* argv[])
{
	SetMyUnhandledExceptionFilter(L"myTest.dmp");

	char* p=NULL;
	memcpy(p,"this is just dump test",5);
	return 0;
}


运行结果:

windows mini dump file_第1张图片


启动调试:

用编译器调试(VS):

1.将dmp拷贝至当时编译的电脑上(如果不在同一台电脑,调试时要指定对应版本的源码 )

2.将 test123.exe 和 test123.pdb 及 dmp文件放置同一个文件夹中

3.确保原本的编译代码没有改变过,及要有对应版本的代码,

4.F5启动调试,此时就可以在源码中看到崩溃点了。

用windbg调试:

没试过。


VS调试截图如下:

windows mini dump file_第2张图片



你可能感兴趣的:(c/c++,windump)