注册如下三个函数并在异常处理函数中用MiniDumpWriteDump函数生成minidump文件
1、SetUnhandledExceptionFilter
2、_set_purecall_handler
3、_set_invalid_parameter_handler
关于2,3两个需要用如下方法获得EXCEPTION_POINTERS指针
#include <dbghelp.h>
#include <shellapi.h>
#include <shlobj.h>
#include <strsafe.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void * _ReturnAddress(void);
#pragma intrinsic(_ReturnAddress)
#ifdef _X86_
void * _AddressOfReturnAddress(void);
#pragma intrinsic(_AddressOfReturnAddress)
#endif /* _X86_ */
}
void GetExceptionPointers(DWORD dwExceptionCode, EXCEPTION_POINTERS** ppExceptionPointers)
{
// The following code was taken from VC++ 8.0 CRT (invarg.c: line 104)
EXCEPTION_RECORD ExceptionRecord;
CONTEXT ContextRecord;
memset(&ContextRecord, 0, sizeof(CONTEXT));
#ifdef _X86_
__asm {
mov dword ptr [ContextRecord.Eax], eax
mov dword ptr [ContextRecord.Ecx], ecx
mov dword ptr [ContextRecord.Edx], edx
mov dword ptr [ContextRecord.Ebx], ebx
mov dword ptr [ContextRecord.Esi], esi
mov dword ptr [ContextRecord.Edi], edi
mov word ptr [ContextRecord.SegSs], ss
mov word ptr [ContextRecord.SegCs], cs
mov word ptr [ContextRecord.SegDs], ds
mov word ptr [ContextRecord.SegEs], es
mov word ptr [ContextRecord.SegFs], fs
mov word ptr [ContextRecord.SegGs], gs
pushfd
pop [ContextRecord.EFlags]
}
ContextRecord.ContextFlags = CONTEXT_CONTROL;
#pragma warning(push)
#pragma warning(disable:4311)
ContextRecord.Eip = (ULONG)_ReturnAddress();
ContextRecord.Esp = (ULONG)_AddressOfReturnAddress();
#pragma warning(pop)
ContextRecord.Ebp = *((ULONG *)_AddressOfReturnAddress()-1);
#elif defined (_IA64_) || defined (_AMD64_)
/* Need to fill up the Context in IA64 and AMD64. */
RtlCaptureContext(&ContextRecord);
#else /* defined (_IA64_) || defined (_AMD64_) */
ZeroMemory(&ContextRecord, sizeof(ContextRecord));
#endif /* defined (_IA64_) || defined (_AMD64_) */
ZeroMemory(&ExceptionRecord, sizeof(EXCEPTION_RECORD));
ExceptionRecord.ExceptionCode = dwExceptionCode;
ExceptionRecord.ExceptionAddress = _ReturnAddress();
///
EXCEPTION_RECORD* pExceptionRecord = new EXCEPTION_RECORD;
memcpy(pExceptionRecord, &ExceptionRecord, sizeof(EXCEPTION_RECORD));
CONTEXT* pContextRecord = new CONTEXT;
memcpy(pContextRecord, &ContextRecord, sizeof(CONTEXT));
*ppExceptionPointers = new EXCEPTION_POINTERS;
(*ppExceptionPointers)->ExceptionRecord = pExceptionRecord;
(*ppExceptionPointers)->ContextRecord = pContextRecord;
}
使用例子:
DWORD dwData = 0;
EXCEPTION_POINTERS* pExp = NULL;
GetExceptionPointers(dwData, &pExp );
另外关于GetExceptionInformation()的使用
__try
{
int p = 0;
int n= 1/p;
}
__except(CustomUnhandledExceptionFilter(GetExceptionInformation()))
{
}
附加信息:
_CrtSetReportMode(_CRT_ASSERT, 0);禁止assert判断生效
如果要c++异常支持seh需要设置如下
c/c++
Code Generation
Enable C++ Exceptions: Yes With SEH Exceptions(/EHa)
即可以捕获异步(结构化)异常