Linux 解释gfortran错误回溯

Linux 解释gfortran错误回溯,linux,bash,debugging,fortran,gfortran,Linux,Bash,Debugging,Fortran,Gfortran,我正在运行一个别人编写的Fortran 77程序。我正在Linux(Ubuntu v.16.04)上使用gfortran编译器(v5.4.0)。我不是Fortran、gcc或bash脚本的经验丰富的用户,所以我在这里很挣扎 当我的程序完成运行时,我收到以下消息: 注意:以下浮点异常是信令:IEEE_非规范 我必须查一下——我知道我的一些浮点数需要存储为“非规范”,这是一种非常小的数字的低精度形式(而不是将它们刷新为零)。这些来自于程序中不稳定的空气动力学计算——我在做计算时看到了这一点。这些非规

我正在运行一个别人编写的Fortran 77程序。我正在Linux(Ubuntu v.16.04)上使用gfortran编译器(v5.4.0)。我不是Fortran、gcc或bash脚本的经验丰富的用户,所以我在这里很挣扎

当我的程序完成运行时,我收到以下消息:

注意:以下浮点异常是信令:IEEE_非规范

我必须查一下——我知道我的一些浮点数需要存储为“非规范”,这是一种非常小的数字的低精度形式(而不是将它们刷新为零)。这些来自于程序中不稳定的空气动力学计算——我在做计算时看到了这一点。这些非规范量不太可能显著影响我的结果,但为了尝试找出发生这种情况的原因,我尝试使用以下错误选项进行编译:

gfortran–g–fbacktrace–ffpe陷阱=无效、零、溢出、下溢、非规范–O3–mcmodel=中等–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:

*六,。在“main.f”的第235行,出现了一个问题。[这是对“code.f”的调用]

*五,。在“code.f”的第428行,出现了一个问题。[这是对“code.f”中“subroutine1”的调用]

*四,。在“子程序1”中“code.f”的第3569行,出现了一个问题。[这是对“code.f”中“subroutine2”的调用]

*三,。在“子程序2”中“code.f”的第3601行,出现了一个问题。[这是一个条件语句]

if(windpd_2m.ge.5.0)然后…

因此,非规范化错误必须发生在“then”操作中(我没有包含该代码,因为(a)它涉及一系列长而复杂的依赖项,(b)我可以解开数学错误,这是我正在努力解决的调试错误)


但对于上述误差2,1,0。。。我不知道如何解释这些数字/字母串。我也不知道“鉴别器3”是什么意思。我在谷歌上搜索过这些,但我找到的唯一资源是,假设他们的知识水平比我高。假设之前对Fortran、gcc或bash脚本的了解很少,有人能帮我解释这些错误代码吗?

前三个堆栈帧是由于在GFortran运行库(libgfortran)中实现了回溯。回溯不能象征性地解析动态库中的地址,因此只能得到地址。如果您想看到符号输出,可以在编译选项中添加“-static”


因此,我的第一个猜测是,错误在.f:3601处,由于5.0是一个常数,因此WindPd_2m应该是非规范的。

您的思路是正确的。您的程序崩溃是因为您告诉它在出现浮点异常时使用
-ffpe trap=…
崩溃。前三个堆栈帧最有可能是对处理实际错误处理的库或内部函数的调用。我不会太担心这些。好的,谢谢@chw21!听起来,深入源代码并找到denom的源代码是处理此问题的最佳方法。有一种可能性是,在计算中保留denom数是合理的,这取决于它们的位置。我将更深入地研究
-ffpe陷阱的控制问题
-如果我能让它生成一个警告,而不是使程序崩溃,那就更好了。*编辑:“denom”应该是“非规范”Hi@janneb,谢谢!我不知道动态库是什么,所以我会去看看。我现在就试试-static选项。对于代码为.f:3601的错误,您的结论是有意义的,但windpsd_2m直接来自天气时间序列,它不包含非规范值。因为这是一个条件,我认为错误在“then”语句中,我在我的帖子中总结为“…”,因为这个块相当大。我想知道回溯是否就是“鉴别器3”的意思。。。以某种方式表明“then”块的哪一部分在发信号。。。这有意义吗?好的,我已经完成了关于静态链接和动态链接的家庭作业-似乎很重要,很高兴我将其添加到我的知识库中。编译时合并“-static”会返回这3个帧的符号输出。但是,输出不会产生新信息,因为这些帧是对gsignal、gfortran backtrace处理程序和gfortran backtrace本身的调用。因此,错误必须在从code.f:3601开始的条件语句中的某个地方。是时候检查我的数学了!