Menu

#83 array.f90 gfortran 4.8.5

v1.0 (example)
closed
None
5
2018-05-06
2018-04-20
seismick
No

This bug only seems to occur with gfortran 4.8.5, used in enterprise
linux.
The subroutine mfile_update is used by TRIN to specify multiple files.
The last parameter in the process screen is a table headed
STATUS PATHNAMES
Now if you enter a wrong filename, it will show up as status RE.
If you edit the filename, and hit Apply button, then cfe crashed with
a malloc error, such as
free(): invalid next size (fast):
or
double free or corruption (!prev):

Fortunately, there is a backtrace sign-posting the bug.
The problem lies in subroutine array_realloc_char_1d (in src/array.f90).
The input to this subroutine is string array parray1. A temporary array
called temp is created and copied into parray1. However, temp is longer
than parray1 and memory is contaminated. Older versions of gfortran
didn't seem to suffer from this defect.
To fix the problem, one must obtain the length of parray1 early in the
subroutine, and then only copy a substring of temp into parray1.
So the modified subroutine will look like this:

  integer                                 :: arraylen,i       ! added 2018 April

  if (.not.associated(parray1)) then
       call array_alloc (parray1,na1,status,msg,keyword,multiple,fill)
       return
  end if
  arraylen=len(parray1(1))  ! needed for gfortran 4.8.5
  nullify (temp)
  keep = size(parray1)
  k1 = keep
  call array_alloc (temp,k1,status2,msg,keyword,multiple)
  if (status2 /= 0) then
       if (present(status)) status = status2
       return
  end if
  temp = parray1
  deallocate (parray1)
  call array_alloc (parray1,na1,status2,msg,keyword,multiple)
  if (status2 /= 0) then
       call array_free (temp)
       if (present(status)) status = status2
       return
  end if
  k1 = min(na1,k1)
  parray1(1:k1) = ' '
  do i=1,k1
   parray1(i) = temp(i)(1:arraylen) ! for gfortran 4.8
  end do
  if (present(fill) .and. na1 > keep) parray1(keep+1:) = fill
  call array_free (temp)
  if (present(status)) status = 0
  if (present(msg   )) msg    = ' '
  return
  end subroutine array_realloc_char_1d

Subroutines array_realloc_char_2d and array_realloc_char_3d would also have
the same problem, but I can't see that these are actually used.

Discussion

  • Bill Menger

    Bill Menger - 2018-05-06
    • status: open --> accepted
    • assigned_to: Bill Menger
     
  • Bill Menger

    Bill Menger - 2018-05-06

    Fixed this and tested, ready to check in later today or tomorrow.

     
  • Bill Menger

    Bill Menger - 2018-05-06
    • status: accepted --> closed
     
  • Bill Menger

    Bill Menger - 2018-05-06

    Used "size(array" instead of "len(array", other minor mods. Great fix, thanks for finding it!

     

Log in to post a comment.

MongoDB Logo MongoDB