This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch fortran] PR 13919 - Runtime "internal error" in IO


On Wed, 2004-03-03 at 01:26, Steven Bosscher wrote:
> On Saturday 21 February 2004 02:14, bud davis wrote:
> > Let's try this again :)
> >
> > problem was a segfault with an empty input file, finish_list_read has to
> > have something to work with or the setjmp / longjmp has big problems.
> 
> I may misunderstand the problem, but shouldn't at_eol in
> finish_list_read just be set in this case?
> 
> Gr.
> Steven
> 

Steven,

You didn't misunderstand the problem, I did.

First off, let's just ignore the previous patch. :)

I went to look at the problem again from the beginning and found that it
only happened when dynamically linked. A few hours of confusion later.. 

This is what happens:

a routine called from st_read() was doing the setjmp(eof_jmp).  
st_read then returns.
< a lot of things happen...>
a routine called from st_done() calls longjmp(eof_jmp).

AFAIK, this is wrong, you must cannot longump to a spot in a subroutine
you have already returned from.

This only happens when you are reading more than is available. If you
have 5 items in the file, and read only 5, then the longjump happens in
a "child" function from st_read which is OK.

Why this works on some platforms, and when statically linked on
i686/linux I dunno...
    
The patch below moves eof_jmp to the io lib global structure, and makes
sure eof_jmp is always initialized to a valid return point in st_done.


Here is a testsuite file, read_eof.f90:

! pr 13919, segfault when file is empty
      open(unit=8,file='/tmp/any_file')
      read(8,*,end=1)i
1     continue
      end

Works with this test as well as the code snippet included in the PR. no
additional regressions.

Tested i686 / linux
 


--bud  

2004-03-05   Bud Davis	<bdavis9659@comcast.net>

	PR 13919
	* io/io.h (global_t):
        * io/list_read.c (next_char,list_formatted_read,ist_formatted_read):
          Move eof_jmp to a global structure.
        * io/transfer.c(finalize_transfer) : Set up eof_jump for callers.


Index: gcc/libgfortran/io/io.h
===================================================================
RCS file: /cvs/gcc/gcc/libgfortran/io/Attic/io.h,v
retrieving revision 1.1.2.4
diff -c -3 -p -r1.1.2.4 io.h
*** gcc/libgfortran/io/io.h	19 Sep 2003 19:11:12 -0000	1.1.2.4
--- gcc/libgfortran/io/io.h	6 Mar 2004 01:27:35 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 23,30 ****
  
  /* IO library include.  */
  
  #include "libgfortran.h"
- 
  #define DEFAULT_TEMPDIR "/var/tmp"
  
  /* Basic types used in data transfers.  */
--- 23,30 ----
  
  /* IO library include.  */
  
+ #include <setjmp.h>
  #include "libgfortran.h"
  #define DEFAULT_TEMPDIR "/var/tmp"
  
  /* Basic types used in data transfers.  */
*************** typedef struct
*** 300,305 ****
--- 300,306 ----
    unit_blank blank_status;
    enum {SIGN_S, SIGN_SS, SIGN_SP} sign_status;
    int scale_factor;
+   jmp_buf eof_jump;  
  }
  global_t;
  
Index: gcc/libgfortran/io/list_read.c
===================================================================
RCS file: /cvs/gcc/gcc/libgfortran/io/Attic/list_read.c,v
retrieving revision 1.1.2.6
diff -c -3 -p -r1.1.2.6 list_read.c
*** gcc/libgfortran/io/list_read.c	1 Jan 2004 13:57:04 -0000	1.1.2.6
--- gcc/libgfortran/io/list_read.c	6 Mar 2004 01:27:35 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 20,26 ****
  
  
  #include "config.h"
- #include <setjmp.h>
  #include <string.h>
  #include <ctype.h>
  #include "libgfortran.h"
--- 20,25 ----
*************** static int comma_flag, namelist_mode;
*** 48,54 ****
  static char last_char, *saved_string;
  static bt saved_type;
  
- static jmp_buf eof_jump;
  
  
  /* Storage area for values except for strings.  Must be large enough
--- 47,52 ----
*************** next_char (void)
*** 145,151 ****
      }
  
    if (length == 0)
!     longjmp (eof_jump, 1);
    c = *p;
  
  done:
--- 143,149 ----
      }
  
    if (length == 0)
!     longjmp (g.eof_jump, 1);
    c = *p;
  
  done:
*************** list_formatted_read (bt type, void *p, i
*** 1227,1233 ****
  
    namelist_mode = 0;
  
!   if (setjmp (eof_jump))
      {
        generate_error (ERROR_END, NULL);
        return;
--- 1225,1231 ----
  
    namelist_mode = 0;
  
!   if (setjmp (g.eof_jump))
      {
        generate_error (ERROR_END, NULL);
        return;
*************** namelist_read (void)
*** 1413,1419 ****
  
    namelist_mode = 1;
  
!   if (setjmp (eof_jump))
      {
        generate_error (ERROR_END, NULL);
        return;
--- 1411,1417 ----
  
    namelist_mode = 1;
  
!   if (setjmp (g.eof_jump))
      {
        generate_error (ERROR_END, NULL);
        return;
Index: gcc/libgfortran/io/transfer.c
===================================================================
RCS file: /cvs/gcc/gcc/libgfortran/io/Attic/transfer.c,v
retrieving revision 1.1.2.7
diff -c -3 -p -r1.1.2.7 transfer.c
*** gcc/libgfortran/io/transfer.c	7 Feb 2004 15:33:29 -0000	1.1.2.7
--- gcc/libgfortran/io/transfer.c	6 Mar 2004 01:27:36 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 55,61 ****
   */
  
  unit_t *current_unit;
- 
  static int sf_seen_eor = 0;
  
  char scratch[SCRATCH_SIZE];
--- 55,60 ----
*************** next_record (int done)
*** 1294,1299 ****
--- 1293,1305 ----
  static void
  finalize_transfer (void)
  {
+ 
+   if (setjmp (g.eof_jump))
+     {
+        generate_error (ERROR_END, NULL);
+        return;
+     }
+ 
    if ((ionml != NULL) && (ioparm.namelist_name != NULL))
      {
         if (ioparm.namelist_read_mode)

 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]