为啥启用浮点异常后出现多个陷阱错误

Posted

技术标签:

【中文标题】为啥启用浮点异常后出现多个陷阱错误【英文标题】:Why after enabling floating point exceptions I got multiple traps error为什么启用浮点异常后出现多个陷阱错误 【发布时间】:2015-11-27 14:37:52 【问题描述】:

使用MSVC2015专业版环境Windows 10,使用/EHa编译

我在做什么:启用浮点异常,以便在发生一些不好的事情时能够捕获异常,仅用于调试

代码:

namespace debug_details

void (*defaultStructuredExceptionFunc)(unsigned int, PEXCEPTION_POINTERS) = nullptr;

void my_trans_func(unsigned int exceptionCode, PEXCEPTION_POINTERS pExpInfo)

    switch (exceptionCode)
    
    case EXCEPTION_FLT_DENORMAL_OPERAND:
    case EXCEPTION_FLT_DIVIDE_BY_ZERO:
    case EXCEPTION_FLT_INEXACT_RESULT:
    case EXCEPTION_FLT_INVALID_OPERATION:
    case EXCEPTION_FLT_OVERFLOW:
    case EXCEPTION_FLT_STACK_CHECK:
    case EXCEPTION_FLT_UNDERFLOW:
    
        _clearfp();
        std::stringstream ss;
        ss << "floating-point structured exception: 0x" << std::hex << exceptionCode;
        throw std::runtime_error(ss.str());
    
    default:
        if (defaultStructuredExceptionFunc != nullptr)
        
            defaultStructuredExceptionFunc(exceptionCode, pExpInfo);
        
    ;
;

void EnableFloatingPointExceptions()

    unsigned int fe_value = ~(/*_EM_INVALID | _EM_DENORMAL |*/ _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW /* | _EM_INEXACT*/);
    unsigned int mask = _MCW_EM;
    unsigned int currentWord = 0;
    _clearfp();
    errno_t result = _controlfp_s(&currentWord, fe_value, mask); // https://msdn.microsoft.com/en-us/library/c9676k6h.aspx
    DVASSERT(result == 0);
    debug_details::defaultStructuredExceptionFunc = _set_se_translator(&debug_details::my_trans_func); // https://msdn.microsoft.com/en-us/library/5z4bw5h5.aspx

    float32 div = 0.f;
    float32 f = 15.f / div;
    float32 f2 = 30.f * div;


 // end namespace debug_details

我希望 EXCEPTION_FLT_DIVIDE_BY_ZERO,但有

请帮助了解发生了什么?提前致谢!

【问题讨论】:

【参考方案1】:

我在 MSDN 上找到了答案,x86 平台的问题,在 x64 上,我们可以从线程上下文寄存器中获取正确的异常代码,请参阅参考 - // https://social.msdn.microsoft.com/Forums/en-US/48f63378-19be-413f-88a5-0f24aa72d3c8/the-exceptions-statusfloatmultipletraps-and-statusfloatmultiplefaults-is-needed-in-more

【讨论】:

【参考方案2】:

关于 FP 异常有几点需要了解:

controlfp 的标志 mask(即禁用)您设置的异常,而不是启用它们。因此,要仅启用除以 0,您需要在参数中的 EM_ZERODIVIDE 中设置 中的所有内容 SSE 代码中的异常不受 controlfp 影响,您需要使用 _mm_setctr(因此,如果您在编译器设置中启用了 SSE/AVX,您的大部分代码可能会使用 SSE,甚至是标量) 如果在被屏蔽时发生异常,稍后启用它会中断(除非某些代码清除了状态字)

【讨论】:

以上是关于为啥启用浮点异常后出现多个陷阱错误的主要内容,如果未能解决你的问题,请参考以下文章

Python的作用域陷阱

Intel异常的分类:错误,陷阱,终止

C ++浮点陷阱[重复]

中止陷阱:strncat() 出现 6 个错误

python异常是不是会生成软件陷阱/中断?

为啥在 ERR 陷阱中退出 0 时 bash 会抑制标准输出?