我有一个相当单一的代码,它从未格式化的大端二进制文件中读取大量数据。通常,代码是在bash脚本中运行的,bash脚本设置环境变量gfortran_convert_unit='native;big_endian:60-70,80-89',然后使用其中一个单元号打开这些big endian数据文件。这对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程序,一个用来编写一个简单的big-endian数据文件,另一个用来读取它:
编写程序:
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位上,使用GCC4.7.1,但在Ubuntu32位上也失败了):
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>
显然,第一次尝试失败是因为它试图用很少的endian读取来读取一个大的endian文件,但是第二次尝试应该可以工作。事实上,它在许多系统上都起作用。设置gfortran_convert_unit=“big_endian”而不是尝试选择单位编号也适用于所有系统。
我不认为这是一个32位与64位的问题,因为单片代码是在64位服务器上,环境变量应该工作,不管…我现在在32位上运行这些,因为这是我的笔记本电脑上的东西。
有什么想法吗?
最佳答案
这个问题是由于libgfortran库中的一个错误造成的。自GCC 4.7.3起已修复(见https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54736)。
关于linux - GFORTRAN_CONVERT_UNIT环境变量在某些平台上不起作用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12632457/