首先强制gfortran停止计划 [英] Force gfortran to stop program at first NaN

查看:169
本文介绍了首先强制gfortran停止计划的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了调试我的应用程序(fortran 90),我想把所有的NaN都变成NaN信号。

使用默认设置,我的程序在没有任何信号的情况下工作,只是将NaN数据输出到文件中。我想找到生成NaN的点。如果我可以使用信号NaN重新编译程序,那么在第一个错误的浮动操作驻留的第一个点,我将得到一个 SIGFPE 信号。

解决方案

您正在寻找的标志是 -ffpe-trap = invalid ;我通常添加,零,溢出来检查相关的浮点异常。

 程序nantest 
real :: a,b,c

a = 1.
b = 2.

c = a / b
print *,c,a,b

a = 0.
b = 0.

c = a / b
print *,c,a,b

a = 2.
b = 1.

c = a / b
print *,c,a,b
结束程序nantest

然后编译它并在调试器中运行它:

  $ gfortran -o nantest nantest.f90 -ffpe-trap = invalid,零,溢出-g -static 
$ gdb nantest
[...]
(gdb)运行
启动程序:/ scratch / ljdursi / Testing / fortran / nantest
0.50000000 1.0000000 2.0000000

编程接收到的信号SIGFPE,算术例外。在nantest.f90的nantest()中
0x0000000000400384:13
13 c = a / b
当前语言:auto;目前fortran

使用intel fortran编译器(ifort),使用选项 - fpe0 会做同样的事情。



这对C / C ++代码来说有点小技巧。我们必须实际插入对 feenableexcept()的调用,该调用将启用浮点异常,并在 fenv.h中定义;

  #include  
#include< fenv.h>

int main(int argc,char ** argv){
float a,b,c;
feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);

a = 1。
b = 2。

c = a / b;
printf(%f%f%f \ n,a,b,c);

a = 0。
b = 0。

c = a / b;
printf(%f%f%f \ n,a,b,c);

a = 2。
b = 1。

c = a / b;
printf(%f%f%f \ n,a,b,c);

返回0;
}

但效果是一样的:

  $ gcc -o nantest nantest.c -lm -g 
$ gdb ./nantest
[...]
( gdb)运行
启动程序:/ scratch / s / scinet / ljdursi / Testing / exception / nantest
1.000000 2.000000 0.500000

编程接收到的信号SIGFPE,算术例外。在nantest.c:17
17 c = a / b; main(argc = 1,argv = 0x7fffffffe4b8)中
0x00000000004005d0;

无论哪种方式,您都可以更好地掌握发生错误的位置。


To debug my application (fortran 90) I want to turn all NaNs to signalling NaN.

With default settings my program works without any signals and just outputs NaN data in file. I want find the point, where NaN is generated. If I can recompile program with signalling NaN, I will get an SIGFPE signal at first point where first wrong floating operation reside.

解决方案

The flag you're looking for is -ffpe-trap=invalid; I usually add ,zero,overflow to check for related floating point exceptions.

program nantest
    real :: a, b, c

    a = 1.
    b = 2.

    c = a/b
    print *, c,a,b

    a = 0.
    b = 0.

    c = a/b
    print *, c,a,b

    a = 2.
    b = 1.

    c = a/b
    print *,c,a,b
end program nantest

Then compiling it and running it in a debugger gives:

$ gfortran -o nantest nantest.f90 -ffpe-trap=invalid,zero,overflow -g -static
$ gdb nantest
[...]
(gdb) run
Starting program: /scratch/ljdursi/Testing/fortran/nantest 
  0.50000000       1.0000000       2.0000000    

Program received signal SIGFPE, Arithmetic exception.
0x0000000000400384 in nantest () at nantest.f90:13
13          c = a/b
Current language:  auto; currently fortran

With the intel fortran compiler (ifort), using the option -fpe0 will do the same thing.

It's a little tricker with C/C++ code; we have to actually insert a call to feenableexcept(), which enables floating point exceptions, and is defined in fenv.h;

#include <stdio.h>
#include <fenv.h>

int main(int argc, char **argv) {  
    float a, b, c;
    feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);

    a = 1.;
    b = 2.;

    c = a/b;
    printf("%f %f %f\n", a, b, c);

    a = 0.;
    b = 0.;

    c = a/b;
    printf("%f %f %f\n", a, b, c);

    a = 2.;
    b = 1.;

    c = a/b;
    printf("%f %f %f\n", a, b, c);

    return 0;
}

but the effect is the same:

$ gcc -o nantest nantest.c -lm -g
$ gdb ./nantest
[...]
(gdb) run
Starting program: /scratch/s/scinet/ljdursi/Testing/exception/nantest  
1.000000 2.000000 0.500000

Program received signal SIGFPE, Arithmetic exception.  
0x00000000004005d0 in main (argc=1, argv=0x7fffffffe4b8) at nantest.c:17  
17        c = a/b;  

either way, you have a much better handle on where the errors are occuring.

这篇关于首先强制gfortran停止计划的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆