2017-10-10 157 views
5

私は誰かが書いたFortran 77プログラムを実行しています。私はLinux上でgfortranコンパイラ(v5.4.0)を使用しています(Ubuntu v.16.04)。 Fortran、gcc、bashスクリプトの経験豊富なユーザーではないので、私はここで苦労しています。私のプログラムの実行が終了するとgfortranエラートレースバックの解釈

、私は次のメッセージが出ます:

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

を私はこれを見ていた - 私は私の浮動小数点数のいくつかは「非正規化」を格納する必要があることを理解し、 (ゼロにフラッシュするのではなく)非常に小さい数の場合は低精度のフォームです。これらはプログラム中の不安定な空力的計算から来ています。計算の際にはこれを見てきました。それは、これらの非正規の量が大幅に私の結果に影響を与えているとは考えにくいですが、試してみて/なぜこれがどこに起こっていた見つけるために、私は次のエラーのオプションでコンパイルしてみました:

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

コンパイルされたプログラムが、実行時にそれがクラッシュして返さ:

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) 

私は6~3から逆方向に働いて、呼び出しの階層としてこれらを解釈することができます

* 6。 "main.f"の235行目に問題がありました。 [これは "code.f"への呼び出しです]

* 5 "code.f"の428行目に問題がありました。 [これは "code.f"の "subroutine1"への呼び出しです]

* 4 "code.f"の行3569の "subroutine1"に問題がありました。 [これは "code.f"の "subroutine2"への呼び出しです]

* 3 "code.f"の行3601の "subroutine2"に問題がありました。 [これは条件文]

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

だからデノーマル・エラー(a)は、それが依存関係の長い、複雑なシリーズが関与するので、私はそのコードを含めていない(「それから」の操作で発生しなければなりません、(b)私は数学のエラーを解くことができます、それは私が苦労しているデバッグエラーです)。

しかし、上記のエラー2,1,0 ...私は数値/文字のこれらの文字列をどのように解釈するのか分かりません。私はまた、「弁別者3」が何を意味するのかも知らない。私はこれらを探検しましたが、私が見つけた唯一のリソースは、私が持っているよりも高いレベルの知識を前提に説明しています。 Fortran、gcc、またはbashスクリプティングに関する既存の知識がほとんどないと仮定して、誰も私にこれらのエラーコードを解釈させる手助けはできますか?

+0

あなたは正しい方向にあります。 '-ffpe-trap = ...'で浮動小数点例外をクラッシュさせるように指示したため、プログラムがクラッシュします。上位3つのスタックフレームは、実際のエラー処理を扱うライブラリまたは組み込み関数への呼び出しの可能性が最も高いです。私はそれらについてあまり心配しないでしょう。 – chw21

+0

OK、thanks @ chw21!それはソースコードに入るように聞こえ、デンソーのソースを見つけることがこれに対処する最善の方法です。彼らがどこにいるかに応じて、計算にデノム番号を残すことは妥当である可能性があります。私は '-ffpe-trap'の制御についてもっと見ていきます。プログラムをクラッシュさせる代わりに警告を生成させることができれば良いでしょう。 –

+0

*編集: "denom"は "denormal"にする必要があります –

答えて

2

最初の3つのスタックフレームは、GFortranランタイムライブラリ(libgfortran)でのバックトレースの実装によるものです。バックトレースはダイナミックライブラリのアドレスをシンボリックに解決できないため、アドレスだけを取得します。シンボリック出力を見たい場合は、コンパイルオプションに "-static"を追加することができます。

私の最初の推測では、エラーはcode.f:3601にあり、5.0は定数なので、windspd_2mは非正規化すべきです。

+0

こんにちは@janneb、ありがとう!ダイナミックライブラリが何であるかわからないので、私は見つけ出すつもりです。私は今、静的なオプションを試してみます。 code.f:3601のエラーについては結論が合っていますが、windpsd_2mは天気の時系列から直接引き出されます。これには非正規化値は含まれていません。それは条件なので、エラーは "then"ステートメントにあると思います。ブロックではかなり大きいので、投稿に「...」とまとめています。逆追跡が「弁別者3」によって意味されたものであるかどうかは疑問に思っていました...どうやら "then"ブロックのどの部分が信号を出していたのかを示しています...それは意味がありますか? –

+0

OK、私は静的対ダイナミックリンクで宿題をしました - 重要だと思う、私は自分の知識ベースに追加してうれしいです。コンパイル時に "-static"を組み込むと、3つのフレームのシンボリック出力が返されます。ただし、出力はgsignal、gfortranバックトレースハンドラ、gfortranバックトレース自体の呼び出しであるため、新しい情報は得られません。 エラーは、code.f:3601から始まる条件文のどこかにある必要があります。私の数学をチェックする時間! –