2017-10-10 82 views
5

Tôi đang chạy chương trình Fortran 77 do người khác viết. Tôi đang sử dụng trình biên dịch gfortran (v5.4.0) trên Linux (Ubuntu v.16.04). Tôi không phải là người dùng có kinh nghiệm về Fortran, gcc hay bash scripting, vì vậy tôi đang đấu tranh ở đây.Thông dịch lỗi traceback gfortran

Khi chương trình của tôi kết thúc hoạt động, tôi nhận được thông báo sau:

Note: The following floating-point exceptions are signalling: IEEE_DENORMAL

Tôi phải bất lực nhìn này lên - Tôi hiểu rằng một số các số dấu chấm động của tôi cần phải được lưu trữ "denormal", một hình thức có độ chính xác thấp cho các số rất nhỏ (thay vì xả chúng bằng không). Chúng đến từ các tính toán khí động học không ổn định trong chương trình - Tôi đã thấy điều này khi thực hiện các phép tính dài. Nó không chắc rằng những lượng denormal đang ảnh hưởng đáng kể kết quả của tôi, nhưng để thử và tìm ra nơi/tại sao điều này đã xảy ra, tôi đã cố gắng biên soạn với các tùy chọn báo lỗi sau:

gfortran –g –fbacktrace –ffpe-trap=invalid,zero,overflow,underflow,denormal –O3 –mcmodel=medium –o ../program.exe

Chương trình biên soạn, nhưng trong thời gian chạy nó đã bị rơi và trả về:

Program received signal SIGFPE: Floating-point exception - erroneous arithmetic operation. 

Backtrace for this error: 
#0 0x7F442F143E08 
#1 0x7F442F142F90 
#2 0x7F442EA8A4AF 
#3 0x4428CF in subroutine2_ at code.f:3601 (discriminator 3) 
#4 0x442C3F in subroutine1_ at code.f:3569 
#5 0x4489DA in code_ at code.f:428 
#6 0x42BdD1 in MAIN__ at main.f:235 
Floating point exception (core dumped) 

tôi có thể giải thích này như một hệ thống các cuộc gọi, làm việc ngược 6-3:

* 6. Tại dòng 235 của "main.f", đã xảy ra sự cố. [đây là cuộc gọi tới "code.f"]

* 5. Tại dòng 428 của "code.f", đã xảy ra sự cố. [đây là cuộc gọi tới "chương trình con1" trong "code.f"]

* 4. Tại dòng 3569 của "code.f", trong "chương trình con1", đã xảy ra sự cố. [đây là cuộc gọi tới "chương trình con2" trong "code.f"]

* 3. Tại dòng 3601 của "code.f", trong "subroutine2", đã xảy ra sự cố. [Đây là một tuyên bố có điều kiện]

if (windspd_2m.ge.5.0) then...

Vì vậy, các lỗi DENORMAL phải được xảy ra trong "sau đó" hoạt động (Tôi chưa bao gồm mã mà vì (a) nó liên quan đến một lâu, loạt phức tạp phụ thuộc và (b) Tôi có thể làm sáng tỏ các lỗi toán học, đó là lỗi gỡ lỗi mà tôi đang gặp phải).

Nhưng đối với các lỗi trên 2,1,0 ... Tôi không biết cách diễn giải các chuỗi số/chữ cái này. Tôi cũng không biết "kẻ phân biệt đối xử 3" nghĩa là gì. Tôi đã googled này, nhưng các nguồn tài nguyên duy nhất tôi đã tìm thấy giải thích cho họ giả định một mức độ cao hơn của kiến ​​thức hơn tôi có. Bất cứ ai có thể giúp tôi để giải thích các mã lỗi, giả sử rất ít kiến ​​thức sẵn có của Fortran, gcc, hoặc bash scripting?

+0

Bạn đang đi đúng hướng. Chương trình của bạn bị treo vì bạn đã báo cho nó gặp sự cố về các ngoại lệ dấu phẩy động với '-ffpe-trap = ...'. Ba khung ngăn xếp hàng đầu có nhiều khả năng nhất là các cuộc gọi đến các thư viện hoặc các hàm nội tại xử lý việc xử lý lỗi thực tế. Tôi sẽ không lo lắng quá nhiều về những điều đó. – chw21

+0

OK, cảm ơn @ chw21!Nghe có vẻ như đi vào mã nguồn và tìm nguồn gốc của denom là cách tốt nhất để giải quyết vấn đề này. Có một cơ hội hợp lý để bỏ số denom trong các phép tính, tùy thuộc vào vị trí của chúng. Tôi sẽ xem xét nhiều hơn về kiểm soát '-ffpe-trap' - nó sẽ tốt hơn nếu tôi có thể làm cho nó tạo ra một cảnh báo thay vì đâm chương trình. –

+0

* chỉnh sửa: "denom" phải là "bất thường" –

Trả lời

2

Ba khung ngăn xếp đầu tiên là do việc thực hiện backtracing trong thư viện thời gian chạy GFortran (libgfortran). Các backtrace không thể giải quyết địa chỉ trong thư viện động tượng trưng, ​​do đó bạn chỉ nhận được địa chỉ. Nếu bạn muốn xem đầu ra tượng trưng, ​​bạn có thể thêm "-static" vào các tùy chọn biên dịch của mình.

Do đó, dự đoán đầu tiên của tôi là lỗi ở mã.f: 3601 và vì 5.0 là hằng số nên theo sau đó windspd_2m phải không chính xác.

+0

Xin chào @janneb, cảm ơn! Tôi không biết thư viện động là gì, vì vậy tôi sẽ tìm hiểu. Và tôi sẽ thử tùy chọn -static ngay bây giờ. Đối với lỗi tại mã.f: 3601, kết luận của bạn có ý nghĩa, nhưng windpsd_2m được vẽ trực tiếp từ chuỗi thời tiết, không chứa các giá trị bất thường. Bởi vì đó là một điều kiện, tôi nghĩ rằng lỗi trong các câu lệnh "sau đó", mà tôi tóm tắt trong bài đăng của tôi là "...", vì khối đó khá lớn. Tôi tự hỏi nếu đó là những gì backtrace có nghĩa là "phân biệt đối xử 3" ... bằng cách nào đó chỉ ra một phần của khối "sau đó" đã được báo hiệu ... điều đó có ý nghĩa? –

+0

OK, tôi đã làm bài tập ở nhà của tôi trên liên kết tĩnh và động - có vẻ quan trọng, vui vì tôi đang thêm nó vào cơ sở tri thức của mình. Kết hợp "-static" tại quá trình biên dịch sẽ trả lại kết quả đầu ra cho 3 khung hình đó. Tuy nhiên, đầu ra không mang lại thông tin mới, bởi vì các khung này là các lệnh gọi tới gsignal, trình xử lý backtrace gfortran và chính backtrace gfortran. Vì vậy, lỗi phải ở đâu đó trong câu lệnh có điều kiện bắt đầu từ mã.f: 3601. Thời gian để kiểm tra toán học của tôi! –

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