15

I have an application where some component occasionally inserts a qNaN in a large data stream, which then invalidates the entire processing (FFT on a vector containing a single qNaN results in an all-qNaN output). Now I'd like to catch that component in the act and find out why it's doing that.

For this, I'd need to somehow make all NaNs signalling during debug. Is there a way to do so, with a x64 CPU executing 32 bit code?

Simon Richter
  • 28,572
  • 1
  • 42
  • 64
  • 1
    Not exactly a duplicate, but lots of details http://stackoverflow.com/questions/570669/checking-if-a-double-or-float-is-nan-in-c – user7116 Mar 08 '12 at 14:28
  • Another question with good details http://stackoverflow.com/questions/2247447/usefulness-of-signaling-nan – user7116 Mar 08 '12 at 15:19
  • Related: [Can I make gcc tell me when a calculation results in NaN or inf at runtime?](http://stackoverflow.com/questions/2941611/can-i-make-gcc-tell-me-when-a-calculation-results-in-nan-or-inf-at-runtime/20973509) – legends2k May 02 '14 at 09:40
  • 1
    possible duplicate of [How to trace a NaN in C++](http://stackoverflow.com/questions/3615724/how-to-trace-a-nan-in-c) – legends2k May 02 '14 at 09:45

2 Answers2

23

If you want to make all NaNs, overflows, and zerodivides signaling during debug, it is possible.

For gcc:

#include <fenv.h>

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

For Visual Studio (not tested):

#include <float.h>

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

References: Microsoft, gcc.


These functions allow to catch either NaNs, produced by floating point operations (overflows, zerodivides, invalid operations), or sNaNs, used as input to some floating point operation. They do not allow to catch qNaNs, used as input to floating point operation. For such qNaNs, the only way to find them is to check each value individually (see Luchian Grigore's answer).

So if the component, that inserts a qNaN is in the same program, were you want to catch it, or if this component is in separate program, but you have its source codes, just enable FP exceptions with feenableexcept()/_controlfp(). Otherwise, check every value in the incoming data stream with isnan() (C++11) or with x != x.

Evgeny Kluev
  • 24,287
  • 7
  • 55
  • 98
7

I doubt there's a way to put a data breakpoint all over the memory to catch all NaNs.

I'd look for the code that inserts into the vector and test for NaN there:

if ( x != x )
    assert(!"NaN detected");
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625