2017-08-02 134 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