2011-04-12 29 views
12

Để gỡ lỗi ứng dụng của tôi (fortran 90) Tôi muốn biến tất cả các NaN thành tín hiệu NaN.Buộc gfortran dừng chương trình tại NaN

Với cài đặt mặc định, chương trình của tôi hoạt động mà không có bất kỳ tín hiệu nào và chỉ xuất dữ liệu NaN vào tệp. Tôi muốn tìm điểm, nơi NaN được tạo ra. Nếu tôi có thể biên dịch lại chương trình với tín hiệu NaN, tôi sẽ nhận được tín hiệu SIGFPE tại điểm đầu tiên nơi hoạt động nổi sai đầu tiên cư trú.

Trả lời

21

Cờ bạn đang tìm kiếm là -ffpe-trap=invalid; Tôi thường thêm ,zero,overflow để kiểm tra ngoại lệ cho dấu phẩy động có liên quan.

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 

Sau đó biên dịch nó và chạy nó trong một trình gỡ lỗi cho:

$ 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 

Với trình biên dịch Fortran intel (ifort), sử dụng tùy chọn -fpe0 sẽ làm điều tương tự.

Đó là một mẹo nhỏ với mã C/C++; chúng tôi phải thực sự chèn một cuộc gọi đến feenableexcept(), cho phép ngoại lệ dấu phẩy động và được xác định trong 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; 
} 

nhưng hiệu quả là như nhau:

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

một trong hai cách, bạn có một xử lý tốt hơn về nơi mà các lỗi đang xảy ra.

+0

Xin chào, bạn có thể có cùng một tùy chọn được áp dụng cho g ++ không? – osgx

+2

Khó hơn với g ++, nhưng có thể đặt bẫy trên các lỗi dấu phẩy động - http://trac.hackerwithin.org/wiki/Articles/GccFpe –

Các vấn đề liên quan