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提供了这种转化的功能。以下是一个代码示例:

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)
        {           
                     //处理异常代码
        }           
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值