捕获异常并生成minidump文件

注册如下三个函数并在异常处理函数中用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)

即可以捕获异步(结构化)异常

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值