诱捕安静的NaN

时间:2012-03-08 14:16:20

标签: c++ debugging x86 floating-point

我有一个应用程序,其中一些组件偶尔在大数据流中插入qNaN,然后​​使整个处理无效(包含单个qNaN的向量上的FFT导致全qNaN输出)。现在我想抓住行动中的那个组成部分,找出它为什么这样做。

为此,我需要在调试期间以某种方式使所有NaN信令。有没有办法这样做,x64 CPU执行32位代码?

2 个答案:

答案 0 :(得分:20)

如果你想在调试期间发出所有NaN,溢出和零点信号,那么就有可能。

对于gcc:

#include <fenv.h>

#ifndef NDEBUG
feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
#endif

对于Visual Studio(未经测试):

#include <float.h>

#ifndef NDEBUG
_clearfp();
_controlfp(_controlfp(0, 0) & ~(_EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW),
           _MCW_EM);
#endif

参考文献:Microsoftgcc


这些函数允许捕获由浮点运算(溢出,零点,无效运算)或sNaN产生的NaN,用作某些浮点运算的输入。它们不允许捕获qNaN,用作浮点运算的输入。对于这样的qNaN,找到它们的唯一方法是单独检查每个值(参见Luchian Grigore的答案)。

因此,如果插入qNaN的组件在同一个程序中,您想要捕获它,或者如果此组件位于单独的程序中,但是您有源代码,则只需使用{{1}启用FP异常} / feenableexcept()。否则,使用_controlfp()(C ++ 11)或isnan()检查传入数据流中的每个值。

答案 1 :(得分:7)

我怀疑是否有办法在整个内存中放置一个数据断点来捕获所有 NaNs

我会查找插入vector并在NaN测试的代码:

if ( x != x )
    assert(!"NaN detected");