http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54736



             Bug #: 54736

           Summary: GFORTRAN_CONVERT_UNIT causes malloc error on several

                    platforms

    Classification: Unclassified

           Product: gcc

           Version: 4.7.1

            Status: UNCONFIRMED

          Severity: major

          Priority: P3

         Component: libfortran

        AssignedTo: unassig...@gcc.gnu.org

        ReportedBy: sha...@utk.edu





I have a code that has multiple large data files that are written in big 

endian format.  To deal with this on many platforms, a script was written 

that, among various other things, sets a few units to read as big endian 

by using GFORTRAN_CONVERT_UNIT='native;big_endian:60-70,80-89'.  However, 

when the Fortran program is called from the script I get:



scale: malloc.c:2368: 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_to

p)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.



This reliably happens on any Linux platform I've tested it on *except* 

Fedora/RHEL.



I've been able to reliably reproduce the problem on several 32-bit 

machines (Arch Linux (GCC 4.7.1), OpenSUSE 12.2, Ubuntu 12.10 Beta 1) by 

creating and running these two programs:



Write program:



[shane@shane-laptop ~/temp/testgfortran]$ 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



Read Program:



[shane@shane-laptop ~/temp/testgfortran]$ cat test_read.f90

program test_write

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_write



And testing:



[shane@shane-laptop ~/temp/testgfortran]$ ./test_write

[shane@shane-laptop ~/temp/testgfortran]$ ./test_read

    16777216

At line 10 of file test_read.f90 (unit = 88, file = 'fort.88')

Fortran runtime error: End of file

[shane@shane-laptop ~/temp/testgfortran]$ 

GFORTRAN_CONVERT_UNIT='native;big_endian:88' ./test_read

test_read: malloc.c:2368: 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@shane-laptop ~/temp/testgfortran]$ 

GFORTRAN_CONVERT_UNIT='big_endian' ./test_read

           1

           2

           3

           4

           5

           6

           7

           8

           9

          10





Obviously the first invocation of test_read fails because the endianess 

is wrong, but the second one should work.  Running gdb yields:



Program received signal SIGABRT, Aborted.

0xb7fdd424 in __kernel_vsyscall ()



However, the above test program does work on all of the 64-bit machines 

I've tested.



I found that by commenting out the lines 582-583 in libgfortran/runtime/

environ.c I can get it to work.



I don't really know why it's accessing an element in the elist structure 

that hasn't been allocated yet.  This loop doesn't seem to do anything to 

me.  Since I don't know the reprocussions of just commenting out stuff 

willy nilly I'll leave the implementation details to someone with more 

knowledge, but this seems like a good place to start.

Reply via email to