我无法理解为什么一个简单的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?
答案 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的转换。