gfortran WRITE错误选项导致段错误

时间:2015-11-27 18:21:19

标签: segmentation-fault fortran gfortran

我无法理解为什么一个简单的fortran程序会在Ubuntu 14.04 Trusty下导致分段错误,但在Ubuntu 12.04 Precise中工作正常。我想通过两次使用WRITE命令的ERR选项来隔离它:

      PROGRAM WRITESEGF2
      WRITE (*,'(I8)',ERR=40) 3.14
   40 CONTINUE
      WRITE (*,'(I8)',ERR=80) 3.14
   80 CONTINUE
      END 

我这样编译:

gfortran -O0 -g -fcheck=all -o writesegfault2 writesegfault2.f

这是Trusty中的输出:

(trusty64)$ ./writesegfault2 
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:
#0  0x7F1B871EA777
#1  0x7F1B871EAD7E
#2  0x7F1B86E42D3F
#3  0x7F1B86EA41B4
#4  0x7F1B872A1D1E
#5  0x7F1B872AC43C
#6  0x7F1B872AE558
#7  0x40088E in writesegf2 at writesegfault2.f:4
Segmentation fault (core dumped)

GDB说:

(trusty64)$ gdb ./writesegfault2

Program received signal SIGSEGV, Segmentation fault.
__memcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:153
153 ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S: No such file or directory.

在精确中根本没有输出,如预期的那样:

(precise64)$ ./writesegfault2
(precise64)$ 

带有ERR标签的单个WRITE似乎工作正常,即使在Trusty:

      PROGRAM WRITEOK
      WRITE (*,'(I8)',ERR=40) 3.14
   40 CONTINUE
      WRITE (*,'(I8)') 3
      WRITE (*,'(E8.3)') 3.14
      END

(trusty64)$ ./writeok 
       3
.314E+01

这是另一种变体:

      PROGRAM WRITESEGF
      WRITE (*,'(I8)',ERR=40) 3.14
   40 CONTINUE
      WRITE (*,'(I8)') 3.14
      END

另一个分段错误似乎是由带有ERR标签的WRITE引起的,后面是简单的转换(应该是错误):

(trusty64)$ ./writesegfault 

Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:
#0  0x7FF7F2BCB777
#1  0x7FF7F2BCBD7E
#2  0x7FF7F2823D3F
#3  0x7FF7F28851B4
#4  0x7FF7F2C82D1E
#5  0x7FF7F2C8D43C
#6  0x7FF7F2C8F558
#7  0x40088E in MAIN__ at writesegfault.f:4
Segmentation fault (core dumped)

不使用标签,应该是错误:

  PROGRAM WRITEERR
  WRITE (*,'(I8)') 3.14
  END

在运行时,在Trusty和Precise中:

(trusty64)$ ./writeerror 
At line 2 of file writeerror.f (unit = 6, file = 'stdout')
Fortran runtime error: Expected INTEGER for item 1 in formatted transfer, got REAL
(I8)
 ^

我用不同版本的gfortran重现了所有这些:精确的4.6.3和Trusty的4.8.4,我也切换了它们(在Precise中向后移动4.8并在Trusty中安装4.6),改变架构(32和64位) ),移动二进制文件。问题是一样的,所以我认为这是一个libgfortran或glib问题......

问题1):为什么那些分段错误,为什么只在Trusty?这可能是glibc的回归吗?

问题2):在最后一种情况下,gfortran中是否有一个标志实际允许REAL转换为INTEGER?

1 个答案:

答案 0 :(得分:1)

看起来它确实是一个影响某些Ubuntu版本的错误,在GCC bugzilla中打开一张票后,他们重现了问题并追踪了修复:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68594

这个问题正在影响gfortran 4.8,部分是gfortran 4.9,应该在gfortran 5.0中修复。

我没有找到任何方法允许使用gfortran选项在WRITE()中进行REAL到INTEGER的转换。