Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29276 Discussions

How to break the debugger on Nan code

Antoon
Beginner
2,434 Views
Hi,

While running my Fortran program in Debug mode it produces lot of Nan codes under Intel Fortran 11.0 compiler and MS Visual Studio 2008.

In Properties Window the Floating point property (under Fortran props) for Floating Point Exception Handling is set on "Produce NaN, signed infinities, and denormal results".

By adding some mysterious lines (txs to collegues):

new_fpe_flags = fpe_m_trap_ovf + fpe_m_trap_div0 + fpe_m_trap_inv
old_fpe_flags = for_set_fpe (new_fpe_flags)


a breakpoint is generated on a formula where division by zero occurs, and that's where theNaN codes come from.

In my simple mind I expected each debugger to break at least on "division by zero" , array out of bounds and that stuff but not here.

Is there any Fortran property that automatically "under the surface" adds these mysterious lines of code for me rather than adding these manually, and removing them again in release config. That's exactly what's nice for a debugger if it adds a lot of intermediate debugging code controlled by properties, rather than old-fashioned way of inserting/removing Fortran code manually.

Some help would be nice.

Antoon

0 Kudos
4 Replies
IanH
Honored Contributor III
2,434 Views
Have a look at the other options for the "Floating Point Exception Handling" property that you mention. The one you've selected explicitly says to ignore things like division by zero. Try the "/fpe:0" variant instead.

0 Kudos
Antoon
Beginner
2,434 Views
FinallyI ranmy simulation for all options of property "Floating Point Exception Handling", i.e.


1) Underflow gives 0.0; Abort on other IEEE exceptions (/fpe:0)

2) Underflow gives 0.0; Other exceptions produce NaN, signed infinity (/fpe:1)

3) Produce NaN, signed infinities, and denormal results

and for all 3 options there is no breakpoint generated on the division by zero statement, and all three runs produce NaN code.

IMHO there must be an easier way then let the debugger stop on division by zero thenby adding those mysterious lines of code.

Question still open: what Fortran property controls breaking on division by zero ?

Antoon

0 Kudos
Steven_L_Intel1
Employee
2,434 Views
There is a Fortran standard way to do this. For example:

[plain]program test_zerodivide
use, intrinsic :: ieee_exceptions
implicit none

real x,y
integer i

call ieee_set_halting_mode (IEEE_DIVIDE_BY_ZERO, .TRUE.)

do i=-3,3
x = 2.0 / real(i)
print *, x
end do

end program test_zerodivide[/plain]
[plain]C:Projects>zd.exe
 -0.6666667
  -1.000000
  -2.000000
forrtl: error (73): floating divide by zero
Image              PC                Routine            Line        Source

zd.exe             000000013FCF10F8  MAIN__                     12  zd.f90
zd.exe             000000013FD4216C  Unknown               Unknown  Unknown
zd.exe             000000013FD29D5B  Unknown               Unknown  Unknown
kernel32.dll       00000000772D652D  Unknown               Unknown  Unknown
ntdll.dll          000000007740C521  Unknown               Unknown  Unknown
[/plain]
0 Kudos
IanH
Honored Contributor III
2,434 Views
The following program from my extensive library of questionably useful utilities:
[fortran]PROGRAM DivideTwoBySomething
  IMPLICIT NONE
  REAL(KIND(1.0D0)) :: a
  CHARACTER(10) :: arg
  INTEGER :: stat
  !****
  IF (COMMAND_ARGUMENT_COUNT() < 1) STOP 'Supply an argument!'
  CALL GET_COMMAND_ARGUMENT(1,arg,STATUS=stat)
  IF (stat /= 0) STOP 'Don''t supply such a long argument!'
  READ (arg, *, IOSTAT=stat) a
  IF (stat > 0) STOP 'Supply a REAL argument!'
  a = 2.0 / a
  PRINT *, 'Two divided by the argument is:', a
END PROGRAM DivideTwoBySomething
[/fortran]

in a release-ish configuration could be compiled and run:

[plain]>ifort /O2 /warn:all /stand:f03 DivideTwoBySomething.f90
Intel Visual Fortran Compiler XE for applications running on IA-32, Version 12.0.4.196 Build 20110427
Copyright (C) 1985-2011 Intel Corporation.  All rights reserved.

Microsoft  Incremental Linker Version 8.00.50727.762
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:DivideTwoBySomething.exe
-subsystem:console
DivideTwoBySomething.obj

>DivideTwoBySomething.exe 0.0
 Two divided by the argument is: Infinity
[/plain]
or in a debug-like configuration:

[plain]>ifort /Od /check:all /warn:all /stand:f03 /debug /traceback /fpe:0 DivideTwoBySomething.f90
Intel Visual Fortran Compiler XE for applications running on IA-32, Version 12.0.4.196 Build 20110427
Copyright (C) 1985-2011 Intel Corporation.  All rights reserved.

Microsoft  Incremental Linker Version 8.00.50727.762
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:DivideTwoBySomething.exe
-debug
-pdb:DivideTwoBySomething.pdb
-subsystem:console
-incremental:no
DivideTwoBySomething.obj

>DivideTwoBySomething.exe 0.0
forrtl: error (73): floating divide by zero
Image              PC        Routine            Line        Source
DivideTwoBySometh  004011F1  _MAIN__                    12  DivideTwoBySomething.f90
DivideTwoBySometh  0047E9A3  Unknown               Unknown  Unknown
DivideTwoBySometh  00454F05  Unknown               Unknown  Unknown
kernel32.dll       7C817077  Unknown               Unknown  Unknown[/plain]

or perhaps that debug build could be "debugged" in Visual Studio:

[plain]>devenv /debugexe DivideTwoBySomething.exe 0.0[/plain]
giving:



which is pretty specific either way about the problematic code. If you have an example to the contrary then it would be interesting to understand the details.

Note that you need to have the main program built with this option turned on (safest option is to make sure that every source file in the program is compiled with the same options - though I think there's a relatively new option that lets you play games with specific source files) and if your code (or some third party library, or code from some other language) then goes and fiddles with the floating point exception flags then obviously you will see different behaviour.

Other options I use to help debugging, mostly in an attempt to get an exception raised as soon as it occurs, include turning off floating point speculation, enabling reliable exceptions and using a floating point model of source. Some of these were selected from reading the documentation, but there's a bit of a case of ignorantly random selection behind them too... others will know better.
0 Kudos
Reply