Win32常见异常

       在所有 Win32 操作系统提供的机制中,使用最广泛的未公开的机制恐怕就要数结构化异常处理(structured exception handling,SEH)了。一提到结构化异常处理,可能就会令人想起 _try、_finally 和 _except 之类的词儿。在任何一本不错的 Win32 书中都会有对 SEH 详细的介绍。甚至连 Win32 SDK 里都对使用 _try、_finally 和 _except 进行结构化异常处理作了完整的介绍。既然有这么多地放都提到了 SEH,那我为什么还要说它是未公开的呢?本质上讲,Win32 结构化异常处理是操作系统提供的一种服务。编译器的运行时库对这种服务操作系统实现进行了封装,而所有能找到的介绍 SEH 的文档讲的都是针对某一特定编译器的运行时库。关键字 _try、_finally 和 _except 并没有什么神秘的。微软的 OS 和编译器定义了这些关键字以及它们的行为。其它的 C++ 编译器厂商也只需要尊从它们定好的语义就行了。在编译器的 SEH 层减少了直接使用纯操作系统的 SEH 所带来的危害的同时,也将纯操作系统的 SEH 从大家的面前隐藏了起来。                                                               ——Matt Pietrek

        以下列出一些Win32常见的异常。 

Value

MacroMeaning
0x80000002EXCEPTION_DATATYPE_MISALIGNMENTThe thread tried to read or write data that is misaligned on hardware that does not provide alignment. For example, 16-bit values must be aligned on 2-byte boundaries; 32-bit values on 4-byte boundaries, and so on.
0x80000003EXCEPTION_BREAKPOINTA breakpoint was encountered.
0xc0000005EXCEPTION_ACCESS_VIOLATIONThe thread tried to read from or write to a virtual address for which it does not have the appropriate access.
0xc0000006EXCEPTION_IN_PAGE_ERRORThe thread tried to access a page that was not present, and the system was unable to load the page. For example, this exception might occur if a network connection is lost while running a program over the network.
0xc000001dEXCEPTION_ILLEGAL_INSTRUCTIONThe thread tried to execute an invalid instruction.
0xc0000025EXCEPTION_NONCONTINUABLE_EXCEPTIONThe thread tried to continue execution after a noncontinuable exception occurred.
0xc0000026EXCEPTION_INVALID_DISPOSITIONAn exception handler returned an invalid disposition to the exception dispatcher. Programmers using a high-level language such as C should never encounter this exception.
0xc000008cEXCEPTION_ARRAY_BOUNDS_EXCEEDEDThe thread tried to access an array element that is out of bounds and the underlying hardware supports bounds checking.
0xc000008dEXCEPTION_FLT_DENORMAL_OPERANDOne of the operands in a floating-point operation is denormal. A denormal value is one that is too small to represent as a standard floating-point value.
0xc000008eEXCEPTION_FLT_DIVIDE_BY_ZEROThe thread tried to divide a floating-point value by a floating-point divisor of zero.
0xc000008fEXCEPTION_FLT_INEXACT_RESULTThe result of a floating-point operation cannot be represented exactly as a decimal fraction.
0xc0000090EXCEPTION_FLT_INVALID_OPERATIONThis exception represents any floating-point exception not included in this list.
0xc0000091EXCEPTION_FLT_OVERFLOWThe exponent of a floating-point operation is greater than the magnitude allowed by the corresponding type.
0xc0000092EXCEPTION_FLT_STACK_CHECKThe stack overflowed or underflowed as the result of a floating-point operation.
0xc0000093EXCEPTION_FLT_UNDERFLOWThe exponent of a floating-point operation is less than the magnitude allowed by the corresponding type.
0xc0000094EXCEPTION_INT_DIVIDE_BY_ZEROThe thread tried to divide an integer value by an integer divisor of zero.
0xc0000095EXCEPTION_INT_OVERFLOWThe result of an integer operation caused a carry out of the most significant bit of the result.
0xc0000096EXCEPTION_PRIV_INSTRUCTIONThe thread tried to execute an instruction whose operation is not allowed in the current machine mode.
0xc00000fdEXCEPTION_STACK_OVERFLOWThe thread used up its stack.

 

      如果要像处理C++类型的异常一样的处理Win32异常,即可以catch到某一类型的异常。_set_se_translator提供了这种转化的功能。以下是一个代码示例:

  1. void trans_fuc(unsigned int, EXCEPTION_POINTERS*);
  2. class CWin32Exception
  3. {
  4. public:
  5.     CWin32Exception(unsigned int n, PEXCEPTION_POINTERS pException)
  6.         : m_nSE(n), m_pException(pException) {}
  7.     /// 获得结构化异常信息。
  8.     PEXCEPTION_POINTERS ExceptionInformation()
  9.     { return m_pException; }
  10.     /// 获得结构化异常代码。
  11.     DWORD ExceptionCode()
  12.     {
  13.         if(NULL != m_pException)
  14.             return m_nSE;
  15.         else
  16.             return 0;
  17.     }   
  18. private:
  19.     /// 结构化异常代码
  20.     unsigned int m_nSE;
  21.     /// 结构化异常信息
  22.     PEXCEPTION_POINTERS m_pException;
  23. };
  24. /// 将Win32结构化异常翻译为C++异常的转换函数。
  25. void trans_fuc(unsigned int u, EXCEPTION_POINTERS* pExp)
  26. {
  27.     throw CWin32Exception(u, pExp);
  28. }

    使用该代码的方式如下:

  1. // 设置异常处理转换函数
  2.     _set_se_translator(trans_fuc);
  3.     // 运行测试异常
  4.     try
  5.     {
  6.         /*int y = 3;
  7.         int x = 4;
  8.         x = x - x;
  9.         int z = y / x;*/
  10.         int *pTest = NULL;
  11.         *pTest = 8;     
  12.     }
  13.     catch( CWin32Exception& Win32Ex )
  14.     {       
  15.         PEXCEPTION_POINTERS pEx = NULL;
  16.         pEx = Win32Ex.ExceptionInformation();
  17.         if (pEx->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
  18.         {           
  19.                      //处理异常代码
  20.         }           
  21.     }

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值