2011-04-12 19 views
12

Aby debugować moją aplikację (fortran 90), chcę włączyć wszystkie NaN do sygnalizacji NaN.Wymuś najpierw program do zatrzymania NaN

Przy ustawieniach domyślnych mój program działa bez żadnych sygnałów i po prostu wypisuje dane NaN w pliku. Chcę znaleźć punkt, w którym generowane jest NaN. Jeśli mogę ponownie skompilować program z sygnalizacją NaN, otrzymam sygnał SIGFPE w pierwszym punkcie, w którym rezyduje pierwsza niewłaściwa operacja pływająca.

Odpowiedz

21

Flaga, której szukasz, to -ffpe-trap=invalid; Zwykle dodajemy ,zero,overflow, aby sprawdzić powiązane wyjątki zmiennoprzecinkowe.

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 

Następnie kompilacji go i uruchomienie go w debugera daje:

$ 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 

Z Intel Fortran kompilator (ifort), korzystając z opcji -fpe0 zrobi to samo.

To trochę tricker z kodem C/C++; musimy faktycznie wstawić połączenie do feenableexcept(), które włącza wyjątki zmiennoprzecinkowe i jest zdefiniowane w 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; 
} 

ale efekt jest ten sam:

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

czy inaczej, masz dużo lepszy uchwyt na którym są błędy występujące.

+0

Witam, czy jest możliwe zastosowanie tej samej opcji do g ++? – osgx

+2

Z g ++ jest trudniej, ale możliwe jest ustawienie pułapek na błędach zmiennoprzecinkowych - http://trac.hackerwithin.org/wiki/Articles/GccFpe –