Bug 25697 - libfortran - Segmentation fault/ Bad Address on unformatted read
Summary: libfortran - Segmentation fault/ Bad Address on unformatted read
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libfortran (show other bugs)
Version: 4.2.0
: P3 normal
Target Milestone: 4.1.0
Assignee: Jerry DeLisle
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-01-06 18:24 UTC by Dale Ranta
Modified: 2006-01-25 07:41 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2006-01-08 09:40:18


Attachments
Prposed patch for pr 25697 (312 bytes, patch)
2006-01-11 03:45 UTC, Jerry DeLisle
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dale Ranta 2006-01-06 18:24:17 UTC
On the Macintosh this program gives a "Segmentation fault" on Linux it gives "Fortran runtime error: Bad address"

dranta:~/tests/gfortran-D] dir% gfortran -o write19 write19.f
[dranta:~/tests/gfortran-D] dir% write19
Segmentation fault
[dranta:~/tests/gfortran-D] dir% cat write19.f
      integer data(500)
      do i = 1,500
        data(i)=-1
      enddo
      open(unit=11,status='scratch',form='unformatted')
       read(11,end=        1000 )data
 1000  continue
       backspace 11
       write(11)data
       read(11,end=        1001 )data
 1001  continue
       backspace 11
       backspace 11
       write(11)data
       rewind 11
       backspace 11
       read(11,end=        1002 )data
 1002  continue
       read(11,end=        1003 )data
 1003  continue
       close(11)
       end

dranta:~/tests/gfortran-D] dir% gfortran --v
Using built-in specs.
Target: powerpc-apple-darwin8.3.0
Configured with: ../gcc/configure --prefix=/Users/dir/gfortran --enable-languages=c,f95
Thread model: posix
gcc version 4.2.0 20060106 (experimental)
[dranta:~/tests/gfortran-D] dir%
Comment 1 Dale Ranta 2006-01-06 20:11:24 UTC
Here is a shorter one that also crashes on the Macintosh -

[dranta:~/tests/gfortran-D] dir% gfortran -o write20 write20.f
[dranta:~/tests/gfortran-D] dir% write20
Segmentation fault
[dranta:~/tests/gfortran-D] dir% cat write20.f
      integer data(500)
      do i = 1,500
        data(i)=-1
      enddo
      open(unit=11,status='scratch',form='unformatted')
       write(11)data
       read(11,end=        1000 )data
 1000  continue
       backspace 11
       backspace 11
       write(11)data
       rewind 11
       read(11,end=        1001 )data
 1001  continue
       read(11,end=        1002 )data
 1002  continue
       close(11)
       end
Comment 2 Jerry DeLisle 2006-01-07 00:59:33 UTC
Confirmed
Comment 3 Jerry DeLisle 2006-01-08 09:40:18 UTC
I will take a gander at this.
Comment 4 Dale Ranta 2006-01-09 01:52:59 UTC
Having a read immediately follow a write - seems to cause the errors.  I have run several million I/O tests where the only legal thing not permitted is a read immediately after a write -  without getting a single error.
Comment 5 Jerry DeLisle 2006-01-09 05:27:01 UTC
This one is cute.  We have user space data showing up in the bytes_left counter.  Really!  I may have found the root of all evils.
Comment 6 Dale Ranta 2006-01-09 18:18:22 UTC
  Hurray - Let there be an end to I/O problems.
Comment 7 Jerry DeLisle 2006-01-11 03:45:02 UTC
Created attachment 10618 [details]
Prposed patch for pr 25697

Dale, can you give this s spin.  I think this fixes it.
Comment 8 Dale Ranta 2006-01-11 15:34:03 UTC
That fixed all the posted examples and it passed the 1048576 tests of all combinations of read,write,backspace, and rewind taken 10 at a time writing a single word, but when I increased the write size to 500 words it failed. The strange thing with this example is that if one of the five writes is removed it no longer fails (buffer flush problem ?) -

[dranta:~/tests/gfortran-D] dir% gfortran -o write21 write21.f
[dranta:~/tests/gfortran-D] dir% write21
Segmentation fault
[dranta:~/tests/gfortran-D] dir% cat write21.f
      integer data(500)
      do i = 1,500
        data(i)=-1
      enddo
      open(unit=11,status='scratch',form='unformatted')
       write(11)data
       write(11)data
       write(11)data
       write(11)data
       write(11)data
       read(11,end=        1000 )data
       call abort()
 1000  continue
       backspace 11
       backspace 11
       read(11,end=        1001 )data
 1001  continue
       read(11,end=        1002 )data
       call abort()
 1002  continue
       close(11)
       end

Comment 9 Dale Ranta 2006-01-11 16:02:55 UTC
With a larger amount of data it only takes one write -


[dranta:~/tests/gfortran-D] dir% gfortran -o write22 write22.f
[dranta:~/tests/gfortran-D] dir% write22
Bus error
[dranta:~/tests/gfortran-D] dir% cat write22.f
      integer data(10000)
      do i = 1,10000
        data(i)=-1
      enddo
      open(unit=11,status='scratch',form='unformatted')
       data(1)=1
       data(10000)=-1
       write(11)data
       read(11,end=        1000 )data
       call abort()
 1000  continue
       backspace 11
       backspace 11
       read(11,end=        1001 )data
        if(data(1).ne.   1.or.data(10000).ne.  -1)then
            call abort()
        endif
 1001  continue
       read(11,end=        1002 )data
       call abort()
 1002  continue
       close(11)
       end
Comment 10 Dale Ranta 2006-01-11 16:50:14 UTC
My thought on a possible fix is that the I/O buffers should be dumped before the read whenever a read immediately follows a write, but I have no idea how you would detect the situation. 
Comment 11 Jerry DeLisle 2006-01-12 06:46:43 UTC
This is interesting.  I noticed before that with the previous test case i could get two different error message depending on the size of the data.  I will have to study this a bit closer.

BTW Thanks for the testing.  We really wantthis I/O bullet proof as we can get it.
Comment 12 Jerry DeLisle 2006-01-18 06:21:34 UTC
Subject: Bug 25697

Author: jvdelisle
Date: Wed Jan 18 06:21:28 2006
New Revision: 109870

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=109870
Log:
2006-01-17  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

	PR libgfortran/25697
	* io/transfer.c (us_read): Detect end of file condition from previous
	operations and bail out (no need to pre-position).

Modified:
    trunk/libgfortran/ChangeLog
    trunk/libgfortran/io/transfer.c

Comment 13 Jerry DeLisle 2006-01-18 06:23:26 UTC
Subject: Bug 25697

Author: jvdelisle
Date: Wed Jan 18 06:23:24 2006
New Revision: 109872

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=109872
Log:
2006-01-17  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

	PR fortran/25697
	* gfortran.dg/read_eof.f90: New test.

Added:
    trunk/gcc/testsuite/gfortran.dg/read_eof.f90
Modified:
    trunk/gcc/testsuite/ChangeLog

Comment 14 Jerry DeLisle 2006-01-18 06:41:19 UTC
Fixed on 4.2, will commit to 4.1 in a few days.  PR 25835 remains a separate problem.  Cases in comment #8 and #9 go to PR25835.
Comment 15 Jerry DeLisle 2006-01-21 07:19:45 UTC
Subject: Bug 25697

Author: jvdelisle
Date: Sat Jan 21 07:19:39 2006
New Revision: 110061

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=110061
Log:
2006-01-20  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

	PR libgfortran/25697
	* io/transfer.c (us_read): Detect end of file condition from previous
	operations and bail out (no need to pre-position).

Modified:
    branches/gcc-4_1-branch/libgfortran/ChangeLog
    branches/gcc-4_1-branch/libgfortran/io/transfer.c

Comment 16 Jerry DeLisle 2006-01-21 07:21:15 UTC
Subject: Bug 25697

Author: jvdelisle
Date: Sat Jan 21 07:21:11 2006
New Revision: 110062

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=110062
Log:
2006-01-20  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

	PR fortran/25697
	* gfortran.dg/read_eof.f90: New test.

Added:
    branches/gcc-4_1-branch/gcc/testsuite/gfortran.dg/read_eof.f90
Modified:
    branches/gcc-4_1-branch/gcc/testsuite/ChangeLog

Comment 17 Jerry DeLisle 2006-01-25 07:41:36 UTC
Fixed on 4.1 and 4.2