簡體   English   中英

Fortran 中 -O2 的分段錯誤

[英]Segmentation fault with -O2 in Fortran

在開發大型 Fortran 軟件時,我時常遇到此錯誤,特別是在使用 -O2 進行編譯以獲得更好的性能時。

在某些情況下,錯誤是真實的並且可以糾正,但在其他情況下,我沒有發現任何錯誤,並假設它是由 -O2 對代碼進行改組引起的。 由於我的老式調試技術是在靠近錯誤發生點的位置添加寫入語句,因此我發現錯誤通常會在我這樣做時消失。

可能是因為 -O2 優化對此類語句進行了一些謹慎的改組。

最近我在一個循環中遇到了這個錯誤,這個循環不是很復雜,時間也不是很關鍵,在循環中添加一個 write 語句可以防止這個錯誤。 當我刪除 write 語句時,錯誤又回來了。 為了避免在運行程序時創建大量無意義的 output,我發現寫入內部字符就足夠了,因此對於用戶來說沒有任何改變。

在沒有 -O2 的情況下編譯代碼時沒有錯誤,但是循環在使用許多局部變量的模塊內部,我不知道如何在沒有 -O2 的情況下單獨編譯模塊中的一個子例程。

我在 Linux 和 Windows 上使用 GNU Fortran 7.2.0(這個最近的錯誤只發生在 Linux 上,但以前我在 Windows 上遇到過類似的問題)。 我無權訪問任何其他編譯器,但我的代碼是免費的,並且已使用其他編譯器編譯,沒有報告任何問題。

所以我的問題是,是否可以為模塊內的一小部分代碼關閉 -O2,或者是否有比添加 write 語句更好的替代方法來防止 -O2 在特定子例程內的代碼周圍打亂。

我通過 web 搜索來到這里,如果它對任何人有幫助,我想分享我的解決方案。 許多評論者提到了未初始化變量的可能性。 我的代碼中沒有這樣的警告,但我通過在子例程中分配存儲產生了明顯相同的效果,編譯器可能沒有意識到新分配的 memory 將在下一行中使用。

我這樣做是因為不小心在模塊中包含了一個可分配的數組,然后將它作為參數傳遞給首先進行分配的子例程(使用模塊中的名稱),然后立即開始使用我的名稱為數組元素賦值作為參數傳入。 當我從 -O1 移動到 -O2 時,它停止工作。 -fcheck=bounds 沒有檢測到問題,實際上導致代碼在沒有段錯誤的情況下運行。

我在不檢查邊界的情況下使用 -O2 -g -traceback 找到了有問題的行。 當我開始始終使用我作為參數傳遞的名稱來引用數組時,問題就消失了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM