1.生成dmp文件方法
#include <DbgHelp.h>
#pragma comment(lib, "dbghelp.lib")
#define DMP_FILE_PATH "D:\\MyDmp"
LONG WINAPI MyUnhandledExceptFilterCallBack(struct _EXCEPTION_POINTERS * lpExceptionInfo)
{
char strDumpFile[1024]={0x00};
SYSTEMTIME currenttime;
::GetLocalTime(¤ttime);
sprintf(strDumpFile,"%s\\%02d-%02d-%02d.%03d.dmp",DMP_FILE_PATH,
currenttime.wHour,
currenttime.wMinute,
currenttime.wSecond,currenttime.wMilliseconds);
HANDLE hDumpFile = CreateFile(strDumpFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL ,NULL);//
if(hDumpFile!=NULL){
MINIDUMP_EXCEPTION_INFORMATION loExceptionInfo;
loExceptionInfo.ExceptionPointers = lpExceptionInfo;
loExceptionInfo.ThreadId = GetCurrentThreadId();
loExceptionInfo.ClientPointers = TRUE;
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),hDumpFile, MiniDumpNormal, &loExceptionInfo, NULL, NULL);
CloseHandle(hDumpFile);
}
return EXCEPTION_EXECUTE_HANDLER;//表示我已经处理了异常,可以优雅地结束了
}
BOOL PreventUnhandledExceptFilter()
{
HMODULE hKernel32 = LoadLibrary("kernel32.dll");
if (NULL == hKernel32)
return FALSE;
void *pExceptFun = GetProcAddress(hKernel32, "SetUnhandledExceptionFilter");
if(pExceptFun== NULL)
return FALSE;
unsigned char newJump[ 100 ] = {0};
DWORD dwOrgEntryAddr = (DWORD) pExceptFun;
dwOrgEntryAddr += 5; // add 5 for 5 op-codes for jmp far
void *pNewFunc = &MyUnhandledExceptFilterCallBack;
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(),
pExceptFun, newJump, sizeof(pNewFunc) + 1, &bytesWritten);
return bRet;
}
static void SetExceptHook() //程序初始化的时候调用该函数即可
{
SetUnhandledExceptionFilter(MyUnhandledExceptFilterCallBack); //安装生成DMP文件的钩子
PreventUnhandledExceptFilter(); //屏蔽其它钩子,可不用
}
2.使用windbg分析dmp文件
-
file->Symbol File Path
设置pdb文件路径,若是有本地编译生成的可不设置,会自动搜索;(必须有生成的pdb文件否则无法分析) -
打开指定dmp文件
-
输入指令!analyze -v 即可分析,等待分析需要一段时间。