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

Macro Meaning
0x80000002 EXCEPTION_DATATYPE_MISALIGNMENT The 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.
0x80000003 EXCEPTION_BREAKPOINT A breakpoint was encountered.
0xc0000005 EXCEPTION_ACCESS_VIOLATION The thread tried to read from or write to a virtual address for which it does not have the appropriate access.
0xc0000006 EXCEPTION_IN_PAGE_ERROR The 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.
0xc000001d EXCEPTION_ILLEGAL_INSTRUCTION The thread tried to execute an invalid instruction.
0xc0000025 EXCEPTION_NONCONTINUABLE_EXCEPTION The thread tried to continue execution after a noncontinuable exception occurred.
0xc0000026 EXCEPTION_INVALID_DISPOSITION An exception handler returned an invalid disposition to the exception dispatcher. Programmers using a high-level language such as C should never encounter this exception.
0xc000008c EXCEPTION_ARRAY_BOUNDS_EXCEEDED The thread tried to access an array element that is out of bounds and the underlying hardware supports bounds checking.
0xc000008d EXCEPTION_FLT_DENORMAL_OPERAND One 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.
0xc000008e EXCEPTION_FLT_DIVIDE_BY_ZERO The thread tried to divide a floating-point value by a floating-point divisor of zero.
0xc000008f EXCEPTION_FLT_INEXACT_RESULT The result of a floating-point operation cannot be represented exactly as a decimal fraction.
0xc0000090 EXCEPTION_FLT_INVALID_OPERATION This exception represents any floating-point exception not included in this list.
0xc0000091 EXCEPTION_FLT_OVERFLOW The exponent of a floating-point operation is greater than the magnitude allowed by the corresponding type.
0xc0000092 EXCEPTION_FLT_STACK_CHECK The stack overflowed or underflowed as the result of a floating-point operation.
0xc0000093 EXCEPTION_FLT_UNDERFLOW The exponent of a floating-point operation is less than the magnitude allowed by the corresponding type.
0xc0000094 EXCEPTION_INT_DIVIDE_BY_ZERO The thread tried to divide an integer value by an integer divisor of zero.
0xc0000095 EXCEPTION_INT_OVERFLOW The result of an integer operation caused a carry out of the most significant bit of the result.
0xc0000096 EXCEPTION_PRIV_INSTRUCTION The thread tried to execute an instruction whose operation is not allowed in the current machine mode.
0xc00000fd EXCEPTION_STACK_OVERFLOW The thread used up its stack.

 

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

void trans_fuc(unsigned int, EXCEPTION_POINTERS*);
class CWin32Exception
{
public:
    CWin32Exception(unsigned int n, PEXCEPTION_POINTERS pException)
        : m_nSE(n), m_pException(pException) {}
    /// 获得结构化异常信息。
    PEXCEPTION_POINTERS ExceptionInformation()
    { return m_pException; }
    /// 获得结构化异常代码。
    DWORD ExceptionCode()
    {
        if(NULL != m_pException)
            return m_nSE;
        else
            return 0;
    }   
private:
    /// 结构化异常代码
    unsigned int m_nSE;
    /// 结构化异常信息
    PEXCEPTION_POINTERS m_pException;
};
/// 将Win32结构化异常翻译为C++异常的转换函数。
void trans_fuc(unsigned int u, EXCEPTION_POINTERS* pExp)
{
    throw CWin32Exception(u, pExp);
}
    使用该代码的方式如下:

// 设置异常处理转换函数
    _set_se_translator(trans_fuc);
    // 运行测试异常
    try
    {
        /*int y = 3;
        int x = 4;
        x = x - x;
        int z = y / x;*/
        int *pTest = NULL;
        *pTest = 8;     
    }
    catch( CWin32Exception& Win32Ex )
    {       
        PEXCEPTION_POINTERS pEx = NULL;
        pEx = Win32Ex.ExceptionInformation();
        if (pEx->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
        {           
                     //处理异常代码
        }           
    }


posted @ 2013-06-04 19:58  N3verL4nd  阅读(610)  评论(0编辑  收藏  举报