2011-04-12 21 views
12

Para depurar mi aplicación (fortran 90) Quiero convertir todos los NaN a la señalización de NaN.Force gfortran para detener el programa al principio NaN

Con la configuración predeterminada, mi programa funciona sin ninguna señal y solo emite datos de NaN en el archivo. Quiero encontrar el punto, donde se genera NaN. Si puedo recompilar el programa con la señalización de NaN, recibiré una señal SIGFPE en el primer punto donde resida la primera operación flotante incorrecta.

Respuesta

21

La bandera que está buscando es -ffpe-trap=invalid; Normalmente agrego ,zero,overflow para verificar excepciones relacionadas de coma flotante.

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 

A continuación, compilarlo y ejecutarlo en un depurador da:

$ 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 

Con el compilador fortran intel (ifort), usando la opción -fpe0 va a hacer lo mismo.

Es un pequeño truco con el código C/C++; tenemos que insertar una llamada al feenableexcept(), que habilita las excepciones de coma flotante, y se define en 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; 
} 

pero el efecto es el mismo:

$ 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; 

de cualquier manera, usted tiene una mejor idea de donde los errores se están produciendo.

+0

Hola, ¿es posible tener la misma opción aplicada a g ++? – osgx

+2

Es más difícil con g ++, pero es posible establecer capturas en errores de punto flotante - http://trac.hackerwithin.org/wiki/Articles/GccFpe –

Cuestiones relacionadas