诱捕安静的NaN

Sim*_*ter 13 c++ debugging floating-point x86

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

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

Evg*_*uev 20

如果要在调试期间生成所有NaN,溢出和零点信号,则可能.

对于gcc:

#include <fenv.h>

#ifndef NDEBUG
feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
#endif
Run Code Online (Sandbox Code Playgroud)

对于Visual Studio(未测试):

#include <float.h>

#ifndef NDEBUG
_clearfp();
_controlfp(_controlfp(0, 0) & ~(_EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW),
           _MCW_EM);
#endif
Run Code Online (Sandbox Code Playgroud)

参考文献:Microsoft,gcc.


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

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


Luc*_*ore 7

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

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

if ( x != x )
    assert(!"NaN detected");
Run Code Online (Sandbox Code Playgroud)

  • 有没有理由你没有把条件放在`assert`本身? (2认同)