您的位置:首页 > 其它

dump

2016-06-18 20:25 295 查看
#ifndef  DUMP_HEAD_FILE
#define  DUMP_HEAD_FILE
#pragma once

#include <windows.h>
#include <imagehlp.h>
#include <stdlib.h>
#include <tchar.h>
#include <stdio.h>
#include <assert.h>

#pragma comment(lib, "dbghelp.lib")
#pragma warning(disable:4996)
#define CountArray(Array) (sizeof(Array)/sizeof(Array[0]))

//运行异常处理
void RunCrashHandler(void);

//注销异常处理
void RemoveCrashHandler(void);

#endif


#include "stdafx.h"
#include "dump.h"

PVOID VectorHandle = NULL;

inline BOOL IsDataSectionNeeded(const TCHAR* pModuleName)
{
if (pModuleName == 0)return FALSE;
TCHAR szFileName[_MAX_FNAME] = { 0 };
_tsplitpath(pModuleName, NULL, NULL, szFileName, NULL);
if (_tcsicmp(szFileName, TEXT("ntdll")) == 0)
return TRUE;
assert(FALSE);
return FALSE;
}

inline BOOL CALLBACK MiniDumpCallback(PVOID pParam, const PMINIDUMP_CALLBACK_INPUT pInput, PMINIDUMP_CALLBACK_OUTPUT pOutput)
{
assert(pInput);
assert(pOutput);
if (pInput == 0 || pOutput == 0)return FALSE;

switch (pInput->CallbackType)
{
case ModuleCallback:
if (pOutput->ModuleWriteFlags & ModuleWriteDataSeg)
if (!IsDataSectionNeeded((TCHAR*)pInput->Module.FullPath))
pOutput->ModuleWriteFlags &= (~ModuleWriteDataSeg);
case IncludeModuleCallback:
case IncludeThreadCallback:
case ThreadCallback:
case ThreadExCallback:
return TRUE;
default:;
}
return FALSE;
}

//创建Dump文件
inline void CreateMiniDump(EXCEPTION_POINTERS* pep, LPCTSTR strFileName)
{
HANDLE hFile = CreateFile(strFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
assert(hFile);
if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))
{
MINIDUMP_EXCEPTION_INFORMATION mdei;
mdei.ThreadId = GetCurrentThreadId();
mdei.ExceptionPointers = pep;
mdei.ClientPointers = FALSE;
MINIDUMP_CALLBACK_INFORMATION mci;
mci.CallbackRoutine = (MINIDUMP_CALLBACK_ROUTINE)MiniDumpCallback;
mci.CallbackParam = 0;
MINIDUMP_TYPE mdt = (MINIDUMP_TYPE)0x0000ffff;
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &mdei, NULL, &mci);
CloseHandle(hFile);
}
return;
}

//vect异常处理回调函数
LONG CALLBACK VectoredHandler(PEXCEPTION_POINTERS ExceptionInfo)
{

TCHAR szText[128] = { 0 };
#ifdef _DEBUG
switch (ExceptionInfo->ExceptionRecord->ExceptionCode)
{
case EXCEPTION_ACCESS_VIOLATION:
{
_sntprintf(szText, CountArray(szText), TEXT(" 线程试图读取或写入到虚拟地址对于其不具有适当的访问------%0x\n"), ExceptionInfo->ExceptionRecord->ExceptionAddress);
MessageBox(NULL, szText, TEXT("提示"), MB_OK);
OutputDebugString(szText);
}
break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
{
_sntprintf(szText, CountArray(szText), TEXT(" 线程试图访问数组元素,是出界和底层硬件支持的边界检查。-----%0x\n"), ExceptionInfo->ExceptionRecord->ExceptionAddress);
MessageBox(NULL, szText, TEXT("提示"), MB_OK);
OutputDebugString(szText);
}
break;
case EXCEPTION_BREAKPOINT:
{
_sntprintf(szText, CountArray(szText), TEXT(" 断点遇到。-----%0x\n"), ExceptionInfo->ExceptionRecord->ExceptionAddress);
MessageBox(NULL, szText, TEXT("提示"), MB_OK);
OutputDebugString(szText);
}
break;
case EXCEPTION_DATATYPE_MISALIGNMENT:
{
_sntprintf(szText, CountArray(szText), TEXT(" 线程试图读取或写入该未对准的硬件上不提供对准数据。例如,16位的值必须在2字节边界对齐; 32位值4字节的边界上,等等。-----%0x\n"), ExceptionInfo->ExceptionRecord->ExceptionAddress);
MessageBox(NULL, szText, TEXT("提示"), MB_OK);
OutputDebugString(szText);
}
break;
case EXCEPTION_FLT_DENORMAL_OPERAND:
{
_sntprintf(szText, CountArray(szText), TEXT(" 一个在浮点运算的操作数是反常值。规格化值是太小,无法表示为标准浮点值。-----%0x\n"), ExceptionInfo->ExceptionRecord->ExceptionAddress);
MessageBox(NULL, szText, TEXT("提示"), MB_OK);
OutputDebugString(szText);
}
break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
{
_sntprintf(szText, CountArray(szText), TEXT(" 线程试图通过零浮点除数划分一个浮点值。-----%0x\n"), ExceptionInfo->ExceptionRecord->ExceptionAddress);
MessageBox(NULL, szText, TEXT("提示"), MB_OK);
OutputDebugString(szText);
}
break;
case EXCEPTION_FLT_INEXACT_RESULT:
{
_sntprintf(szText, CountArray(szText), TEXT(" 浮点运算的结果不能被精确表示作为一个小数。-----%0x\n"), ExceptionInfo->ExceptionRecord->ExceptionAddress);
MessageBox(NULL, szText, TEXT("提示"), MB_OK);
OutputDebugString(szText);
}
break;
case EXCEPTION_FLT_INVALID_OPERATION:
{
_sntprintf(szText, CountArray(szText), TEXT(" 此异常表示不包括在此列表中的任何浮点异常。-----%0x\n"), ExceptionInfo->ExceptionRecord->ExceptionAddress);
MessageBox(NULL, szText, TEXT("提示"), MB_OK);
OutputDebugString(szText);
}
break;
case EXCEPTION_FLT_OVERFLOW:
{
_sntprintf(szText, CountArray(szText), TEXT(" 浮点运算的指数大于由相应的类型所允许的幅度。-----%0x\n"), ExceptionInfo->ExceptionRecord->ExceptionAddress);
MessageBox(NULL, szText, TEXT("提示"), MB_OK);
OutputDebugString(szText);
}
break;
case EXCEPTION_FLT_STACK_CHECK:
{
_sntprintf(szText, CountArray(szText), TEXT(" 堆栈溢出或下溢作为浮点运算的结果。-----%0x\n"), ExceptionInfo->ExceptionRecord->ExceptionAddress);
MessageBox(NULL, szText, TEXT("提示"), MB_OK);
OutputDebugString(szText);
}
break;
case EXCEPTION_FLT_UNDERFLOW:
{
_sntprintf(szText, CountArray(szText), TEXT(" 浮点运算的指数小于由相应类型所允许的幅度。-----%0x\n"), ExceptionInfo->ExceptionRecord->ExceptionAddress);
MessageBox(NULL, szText, TEXT("提示"), MB_OK);
OutputDebugString(szText);
}
break;
case EXCEPTION_ILLEGAL_INSTRUCTION:
{
_sntprintf(szText, CountArray(szText), TEXT(" 线程试图执行一个无效的指令。-----%0x\n"), ExceptionInfo->ExceptionRecord->ExceptionAddress);
MessageBox(NULL, szText, TEXT("提示"), MB_OK);
OutputDebugString(szText);
}
break;
case EXCEPTION_IN_PAGE_ERROR:
{
_sntprintf(szText, CountArray(szText), TEXT(" 线程试图访问一个网页,不存在,并且该系统无法加载的页面。例如,如果在运行程序通过网络失去网络连接,可能会出现这种异常。-----%0x\n"), ExceptionInfo->ExceptionRecord->ExceptionAddress);
MessageBox(NULL, szText, TEXT("提示"), MB_OK);
OutputDebugString(szText);
}
break;
case EXCEPTION_INT_DIVIDE_BY_ZERO:
{
_sntprintf(szText, CountArray(szText), TEXT(" 线程试图通过的零的整数除数划分的整数值。-----%0x\n"), ExceptionInfo->ExceptionRecord->ExceptionAddress);
MessageBox(NULL, szText, TEXT("提示"), MB_OK);
OutputDebugString(szText);
}
break;
case EXCEPTION_INT_OVERFLOW:
{
_sntprintf(szText, CountArray(szText), TEXT(" 的整数运算的结果所引起的进位出来的结果的最显著位。-----%0x\n"), ExceptionInfo->ExceptionRecord->ExceptionAddress);
MessageBox(NULL, szText, TEXT("提示"), MB_OK);
OutputDebugString(szText);
}
break;
case EXCEPTION_INVALID_DISPOSITION:
{
_sntprintf(szText, CountArray(szText), TEXT(" 异常处理程序返回了一个无效配置的异常分派。使用高级语言编程如C应该永远不会遇到此异常。-----%0x\n"), ExceptionInfo->ExceptionRecord->ExceptionAddress);
MessageBox(NULL, szText, TEXT("提示"), MB_OK);
OutputDebugString(szText);
}
break;
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
{
_sntprintf(szText, CountArray(szText), TEXT(" 线程试图继续发生不可持续异常后执行。-----%0x\n"), ExceptionInfo->ExceptionRecord->ExceptionAddress);
MessageBox(NULL, szText, TEXT("提示"), MB_OK);
OutputDebugString(szText);
}
break;
case EXCEPTION_PRIV_INSTRUCTION:
{
_sntprintf(szText, CountArray(szText), TEXT(" 线程试图执行一条指令,其操作在当前机器模式是不允许的。-----%0x\n"), ExceptionInfo->ExceptionRecord->ExceptionAddress);
MessageBox(NULL, szText, TEXT("提示"), MB_OK);
OutputDebugString(szText);
}
break;
case EXCEPTION_SINGLE_STEP:
{
_sntprintf(szText, CountArray(szText), TEXT(" 一丝丝陷阱或其他单指令的机制标志着一个指令已被执行。-----%0x\n"), ExceptionInfo->ExceptionRecord->ExceptionAddress);
MessageBox(NULL, szText, TEXT("提示"), MB_OK);
OutputDebugString(szText);
}
break;
case EXCEPTION_STACK_OVERFLOW:
{
_sntprintf(szText, CountArray(szText), TEXT(" 线程用完它的堆栈。-----%0x\n"), ExceptionInfo->ExceptionRecord->ExceptionAddress);
MessageBox(NULL, szText, TEXT("提示"), MB_OK);
OutputDebugString(szText);
}
break;
default:
break;
}
#endif
return EXCEPTION_CONTINUE_SEARCH;
}

//异常处理回调函数
LONG WINAPI UnhandledExceptionFilterEx(struct _EXCEPTION_POINTERS *pException)
{
//定义变量
TCHAR szModuFile[MAX_PATH] = { 0 };
TCHAR szDumpFileName[MAX_PATH] = { 0 };

//获取模块路径
GetModuleFileName(NULL, szModuFile, MAX_PATH);

//获取时间
SYSTEMTIME time;
GetLocalTime(&time);
_sntprintf_s(szDumpFileName, CountArray(szDumpFileName), TEXT("%s%d%d%d%d%d.dmp"), szModuFile, time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute);

//创建dump文件
CreateMiniDump(pException, szDumpFileName);

return EXCEPTION_CONTINUE_SEARCH;
}

//运行异常处理
void RunCrashHandler(void)
{
//设置异常处理回调函数
SetUnhandledExceptionFilter(UnhandledExceptionFilterEx);
if (VectorHandle==NULL)
{
//注册vect异常处理程序
VectorHandle = AddVectoredExceptionHandler(0, VectoredHandler);
assert(VectorHandle != NULL);
}
return;
}

//注销异常处理
void RemoveCrashHandler(void)
{

if(VectorHandle)
{
RemoveVectoredExceptionHandler(VectorHandle);
}

return ;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: