2017-08-02 128 views
1

當我使用gfortran -g -fbacktrace -ffpe陷阱=無效,溢出編譯我的代碼,溢File.f90我得到以下錯誤:解釋回溯錯誤信息

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

Backtrace for this error: 

#0 0x7f3da0768ed7 in ??? 
#1 0x7f3da076810d in ??? 
#2 0x7f3d9fe9b7ef in ??? 
#3 0x7f3da0230a3e in ??? 

我的問題是:如何能我解釋這些數字,並在「回溯這個錯誤:」之下。我如何使用此錯誤消息來幫助我找到錯誤?它們與某些有問題的代碼行有關嗎?如果是這樣,怎麼樣?

截至目前我知道我有一個錯誤的算術運算錯誤,但我不知道在哪裏和這個回溯錯誤消息根本沒有幫助。如果我僅使用gfortran File.f90進行編譯,則編譯期間或運行期間根本沒有錯誤消息。

+0

我不知道FORTRAN,但是當我在其他語言中碰上離奇的消息是這樣的地方是不明確的地方錯誤正在發生,我將遍佈各地的'print'語句並查看最後一次打印的內容。這通常是在沒有有用位置的情況下縮小範圍的最佳方法。如果可用,調試器也是一個很好的選擇。 – Carcigenicate

+0

@Carcigenicate我已經做到了。謝謝! –

+0

調試時,我通常禁用優化('-O0'),這樣可以更容易地查看出錯的地方。 – chw21

回答

2

這可能取決於您正在使用哪個目標。 GFortran回溯功能取決於libbacktrace,它可能不適用於所有目標。在Ubuntu 16.04 x86_64的對碼

program bt 
    use iso_fortran_env 
    implicit none 
    real(real64) :: a, b = -1 
    a = sqrt(b) 
    print *, a 
end program bt

gfortran -g -ffpe-trap=invalid bt.f90 

編譯時,我得到

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

Backtrace for this error: 
#0 0x7F08C38E8E08 
#1 0x7F08C38E7F90 
#2 0x7F08C35384AF 
#3 0x4007F9 in MAIN__ at bt.f90:5 
zsh: floating point exception ./a.out 

其中堆棧幀#3你可以看到,在第5行發生錯誤bt.f90。

現在,什麼是堆棧幀#0-#2的東西?那麼,它們是GFortran運行時庫libgfortran中的回溯功能。由於某種原因libbacktrace無法解析動態庫中的符號。如果我靜態鏈接它:

gfortran -g -static -ffpe-trap=invalid bt.f90 

我得到

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

Backtrace for this error: 
#0 0x40139E in _gfortrani_backtrace 
#1 0x400D00 in _gfortrani_backtrace_handler 
#2 0x439B2F in gsignal 
#3 0x400C01 in MAIN__ at bt.f90:5 
zsh: floating point exception ./a.out 
+0

謝謝你的答案和簡單的代碼來解釋一切。我有兩個問題/澄清。這看起來很明顯,但我只想澄清一下,你提供的示例代碼的問題是你定義了一個真實的,但是然後使用a = sqrt(-1),所以a不是真實的。因此,我們正在得到這個錯誤的算術運算。正確?其次:如果我使用'trap = invalid'編譯,我根本沒有得到任何錯誤信息,然後運行代碼,一切都很好。但如果我使用'陷阱=無效',下溢;我收到錯誤消息。如何從「陷阱」中去除下溢會改變一切? –

+0

@JeffFaraci b是一個真實的,所以sqrt(b)也是真實的。從整數文字初始化b不會將b轉換爲整數,而是在將其分配給實變量時將整數值轉換爲實數。我只用了fpe-trap = invalid,因爲在我的示例中,這足以捕獲負數的sqrt();由於我沒有看到你的代碼,我不知道哪個異常導致陷阱。 – janneb