1

我有一个相当单一的代码,它从未格式化的大端二进制文件中读取大量数据。通常,代码从设置环境变量 GFORTRAN_CONVERT_UNIT='native;big_endian:60-70,80-89' 的 bash 脚本中运行,然后使用其中一个单元号打开这些大端数据文件。这适用于 Fedora 和 RHEL。但是,当我在 Debian(以及包括 Ubuntu 和 Linux Mint 在内的衍生产品)、OpenSUSE 和 Arch Linux 上运行该程序时,在 Fortran 代码执行任何操作之前,我会收到以下 malloc 错误:

malloc.c:2451: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.
Aborted

为了进一步演示这个问题,我编写了两个 Fortran 程序,一个用于编写简单的大端数据文件,一个用于读取它:

编写程序:

shane@linux-0r5g:~/temp> cat test_write.f90
program test_write
implicit none

integer, parameter :: NUM = 10
integer :: i

open (unit=88,form='unformatted',convert='big_endian')
do i = 1,NUM
  write (88) i
end do

close (88)

end program test_write

阅读程序:

shane@linux-0r5g:~/temp> cat test_read.f90
program test_read
implicit none

integer, parameter :: NUM = 10
integer :: readInt
integer :: i

open (unit=88,form='unformatted')
do i = 1,NUM
  read (88) readInt
  write (*,*) readInt
end do

close (88)

end program test_read

运行程序(这是在 OpenSUSE 12.2 32 位上使用 GCC 4.7.1,但在 Ubuntu 32 位上也失败):

shane@linux-0r5g:~/temp> ./test_write 
shane@linux-0r5g:~/temp> ./test_read
    16777216
At line 10 of file test_read.f90 (unit = 88, file = 'fort.88')
Fortran runtime error: End of file
shane@linux-0r5g:~/temp> GFORTRAN_CONVERT_UNIT='native;big_endian:88' ./test_read
test_read: malloc.c:2451: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.
Aborted
shane@linux-0r5g:~/temp> 

显然,第一次尝试失败,因为它试图读取带有小端读取的大端文件,但第二次尝试应该有效。事实上,它确实适用于许多系统。设置 GFORTRAN_CONVERT_UNIT='big_endian' 而不是尝试挑选单元编号也适用于所有系统。

我不认为这是 32 位与 64 位的问题,因为单体代码位于 64 位服务器上,并且环境变量无论如何都应该工作......我现在在 32 位上运行这些,因为这就是我的笔记本电脑上有。

有任何想法吗?

4

1 回答 1

1

此问题是由于 libgfortran 库中的错误造成的。自 gcc 4.7.3 以来它已被修复(参见https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54736)。

于 2015-02-09T22:08:47.147 回答