Интерфейс:

// SeException.h - interface of the CSeException class

// Copyright (c) 2004-2008 by Elijah Zarezky,
// All rights reserved.
// Portions copyright (c) 2000 by Martin Ziacek.

#if !defined(__SeException_h)
#define __SeException_h

#if defined(_MSC_VER) && (_MSC_VER > 1000)
#pragma once
#endif   // _MSC_VER

class CSeException: public CException
{
   DECLARE_DYNAMIC(CSeException)

// construction/destruction
public:
   CSeException(UINT uCode, _EXCEPTION_POINTERS* pXcptPtrs);
   virtual ~CSeException(void);

// copying/assignment
public:
   CSeException(const CSeException& src);
   CSeException& operator =(const CSeException& src);

// operations
public:
   void Delete(void);
   virtual BOOL GetErrorMessage(LPTSTR pszDest, UINT uMaxLen, UINT* puHelpCtx = NULL);
   virtual int ReportError(UINT fuType = MB_OK, UINT uHelpID = 0);

// SEH translator
public:
   static void Translator(UINT uCode, _EXCEPTION_POINTERS* pXcptPtrs);

// accessibility
public:
   UINT GetCode(void);
   LPCTSTR GetDescription(void);
   void* GetAddress(void);

// attributes
protected:
   UINT m_uCode;
   _EXCEPTION_POINTERS m_xcptPtrs;

// implementation helpers
private:
   BOOL FormatErrorMessage(CString& strDest);

// diagnostic services
#if defined(_DEBUG)
public:
   virtual void AssertValid(void) const;
   virtual void Dump(CDumpContext& dumpCtx) const;
#endif
};

#endif   // __SeException_h

Реализация:

// SeException.cpp - implementation of the CSeException class

// Copyright (c) 2004-2008 by Elijah Zarezky,
// All rights reserved.
// Portions copyright (c) 2000 by Martin Ziacek.

#include "SeException.h"

#if defined(__INTEL_COMPILER)
// remark #279: controlling expression is constant
#pragma warning(disable: 279)
// remark #981: operands are evaluated in unspecified order
#pragma warning(disable: 981)
#endif   // __INTEL_COMPILER

#if defined(_DEBUG)
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#define new DEBUG_NEW
#endif   // _DEBUG

// object model
IMPLEMENT_DYNAMIC(CSeException, CException)

CSeException::CSeException(UINT uCode, _EXCEPTION_POINTERS* pXcptPtrs):
m_uCode(uCode),
m_xcptPtrs(*pXcptPtrs)
{
}

CSeException::~CSeException(void)
{
}

CSeException::CSeException(const CSeException& src):
m_uCode(src.m_uCode),
m_xcptPtrs(src.m_xcptPtrs)
{
}

CSeException& CSeException::operator =(const CSeException& src)
{
   m_uCode = src.m_uCode;
   m_xcptPtrs = src.m_xcptPtrs;
   return (*this);
}

void CSeException::Delete(void)
{
#if defined(_DEBUG)
   m_bReadyForDelete = TRUE;
#endif   // _DEBUG
   delete this;
}

BOOL CSeException::GetErrorMessage(LPTSTR pszDest, UINT uMaxLen, UINT* puHelpCtx)
{
   CString strTemp;

   ASSERT(pszDest != NULL);
   ASSERT(AfxIsValidString(pszDest, uMaxLen));
   if (puHelpCtx != NULL)
   {
      *puHelpCtx = 0;
   }
   FormatErrorMessage(strTemp);
   if (!strTemp.IsEmpty())
   {
      ::lstrcpyn(pszDest, strTemp, uMaxLen);
      return (TRUE);
   }
   else
   {
      return (FALSE);
   }
}

int CSeException::ReportError(UINT fuType, UINT uHelpID)
{
   CString strError;

   FormatErrorMessage(strError);
   return (AfxMessageBox(strError, fuType, uHelpID));
}

void CSeException::Translator(UINT uCode, _EXCEPTION_POINTERS* pXcptPtrs)
{
   CSeException* pXcpt = new CSeException(uCode, pXcptPtrs);
   throw pXcpt;
}

UINT CSeException::GetCode(void)
{
   return (m_uCode);
}

LPCTSTR CSeException::GetDescription(void)
{
   switch (m_uCode)
   {
   case EXCEPTION_ACCESS_VIOLATION:
      return (_T("Access violation"));
   case EXCEPTION_DATATYPE_MISALIGNMENT:
      return (_T("EXCEPTION_DATATYPE_MISALIGNMENT"));
   case EXCEPTION_BREAKPOINT:
      return (_T("EXCEPTION_BREAKPOINT"));
   case EXCEPTION_SINGLE_STEP:
      return (_T("EXCEPTION_SINGLE_STEP"));
   case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
      return (_T("EXCEPTION_ARRAY_BOUNDS_EXCEEDED"));
   case EXCEPTION_FLT_DENORMAL_OPERAND:
      return (_T("EXCEPTION_FLT_DENORMAL_OPERAND"));
   case EXCEPTION_FLT_DIVIDE_BY_ZERO:
      return (_T("Floating point divide by zero"));
   case EXCEPTION_FLT_INEXACT_RESULT:
      return (_T("Floating point inexact result"));
   case EXCEPTION_FLT_INVALID_OPERATION:
      return (_T("EXCEPTION_FLT_INVALID_OPERATION"));
   case EXCEPTION_FLT_OVERFLOW:
      return (_T("Floating point overflow"));
   case EXCEPTION_FLT_STACK_CHECK:
      return (_T("EXCEPTION_FLT_STACK_CHECK"));
   case EXCEPTION_FLT_UNDERFLOW:
      return (_T("Floating point underflow"));
   case EXCEPTION_INT_DIVIDE_BY_ZERO:
      return (_T("Integer divide by zero"));
   case EXCEPTION_INT_OVERFLOW:
      return (_T("Integer overflow"));
   case EXCEPTION_PRIV_INSTRUCTION:
      return (_T("EXCEPTION_PRIV_INSTRUCTION"));
   case EXCEPTION_IN_PAGE_ERROR:
      return (_T("EXCEPTION_IN_PAGE_ERROR"));
   case EXCEPTION_ILLEGAL_INSTRUCTION:
      return (_T("EXCEPTION_ILLEGAL_INSTRUCTION"));
   case EXCEPTION_NONCONTINUABLE_EXCEPTION:
      return (_T("EXCEPTION_NONCONTINUABLE_EXCEPTION"));
   case EXCEPTION_STACK_OVERFLOW:
      return (_T("Stack overflow"));
   case EXCEPTION_INVALID_DISPOSITION:
      return (_T("EXCEPTION_INVALID_DISPOSITION"));
   case EXCEPTION_GUARD_PAGE:
      return (_T("EXCEPTION_GUARD_PAGE"));
   case EXCEPTION_INVALID_HANDLE:
      return (_T("EXCEPTION_INVALID_HANDLE"));
   default:
      return (_T(">>> unrecognized <<<"));
   }
}

void* CSeException::GetAddress(void)
{
   return (m_xcptPtrs.ExceptionRecord->ExceptionAddress);
}

BOOL CSeException::FormatErrorMessage(CString& strDest)
{
   static TCHAR szFormat[] = _T("Exception 0x%08lX at address 0x%08lX:\n%s.");

   strDest.Empty();
   if (m_uCode == EXCEPTION_ACCESS_VIOLATION)
   {
      // special case
      CString strDescr(GetDescription());
      ULONG_PTR* xcptInfo = m_xcptPtrs.ExceptionRecord->ExceptionInformation;
      LPCTSTR pszMemOp = xcptInfo[0] != 0 ? _T("write") : _T("read");
      CString strDetails;
      strDetails.Format(_T("\x20(unable to %s at address 0x%08lX)"), pszMemOp, xcptInfo[1]);
      strDescr += strDetails;
      strDest.Format(szFormat, m_uCode, GetAddress(), static_cast<LPCTSTR>(strDescr));
   }
   else
   {
      // common case
      strDest.Format(szFormat, m_uCode, GetAddress(), GetDescription());
   }
   return (!strDest.IsEmpty());
}

#if defined(_DEBUG)

void CSeException::AssertValid(void) const
{
   // first perform inherited validity check...
   CException::AssertValid();

   // ...and then verify own state as well
}

void CSeException::Dump(CDumpContext& dumpCtx) const
{
   try
   {
      // first invoke inherited dumper...
      CException::Dump(dumpCtx);

      // ...and then dump own unique members
      dumpCtx << "m_uCode = " << m_uCode;
   }
   catch (CFileException* pXcpt)
   {
      pXcpt->ReportError();
      pXcpt->Delete();
   }
}

#endif   // _DEBUG

Пример использования:

// install SEH translator
int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
   _set_se_translator(&CSeException::Translator);

   ...
}

...

void foo(void)
{
   try
   {
      int* pnDummy = NULL;
      int nCrash = *pnDummy;
   }
   catch (CSeException* pXcpt)
   {
      pXcpt->ReportError();
      pXcpt->Delete();
   }
}
обновлено
21.07.2007
 
Проверка PR и ТИЦ