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]

[patch, libgfortran] [4.3 Regression] crash when printing big character variable


:ADDPATCH fortran:

The attached patch is a partial revert of r125099 which introduced this problem.

I have tested it with the reporters test case and fully regression tested on x86-64-Gnu/Linux.

I intend to commit this patch tonight under obvious rule to fix this regression. The problem is that buffer space beyond the initial (8192) size is not getting allocated.

I will also commit a new test case to catch this problem.

Best regards,

Jerry

2007-07-09 Jerry DeLisle <jvdelisle@gcc.gnu.org>

	PR libgfortran/32702
	* io/unix.c (unix_stream): Restore buffer pointer and small_buffer.
	(fd_alloc): If the number of bytes needed is greater than the default
	BUFFER_SIZE, allocate a new buffer large enough.  Free the old buffer if
	necessary. (fd_sfree): Restore use of buffer pointer.
	(fd_close): Likewise. (fd_open): Likewise.
	(init_error_stream): Likewise.
Index: unix.c
===================================================================
*** unix.c	(revision 126506)
--- unix.c	(working copy)
*************** typedef struct
*** 97,102 ****
--- 97,103 ----
    gfc_offset dirty_offset;	/* Start of modified bytes in buffer */
    gfc_offset file_length;	/* Length of the file, -1 if not seekable. */
  
+   char *buffer;
    int len;			/* Physical length of the current buffer */
    int active;			/* Length of valid bytes in the buffer */
  
*************** typedef struct
*** 107,113 ****
  
    int unbuffered;               /* =1 if the stream is not buffered */
  
!   char buffer[BUFFER_SIZE];
  }
  unix_stream;
  
--- 108,115 ----
  
    int unbuffered;               /* =1 if the stream is not buffered */
  
!   char small_buffer[BUFFER_SIZE];
! 
  }
  unix_stream;
  
*************** static void
*** 437,453 ****
  fd_alloc (unix_stream * s, gfc_offset where,
  	  int *len __attribute__ ((unused)))
  {
!   int n;
  
    /* Salvage bytes currently within the buffer.  This is important for
     * devices that cannot seek. */
  
!   if (s->buffer_offset <= where &&
        where <= s->buffer_offset + s->active)
      {
  
        n = s->active - (where - s->buffer_offset);
!       memmove (s->buffer, s->buffer + (where - s->buffer_offset), n);
  
        s->active = n;
      }
--- 439,467 ----
  fd_alloc (unix_stream * s, gfc_offset where,
  	  int *len __attribute__ ((unused)))
  {
!   char *new_buffer;
!   int n, read_len;
! 
!   if (*len <= BUFFER_SIZE)
!     {
!       new_buffer = s->small_buffer;
!       read_len = BUFFER_SIZE;
!     }
!   else
!     {
!       new_buffer = get_mem (*len);
!       read_len = *len;
!     }
  
    /* Salvage bytes currently within the buffer.  This is important for
     * devices that cannot seek. */
  
!   if (s->buffer != NULL && s->buffer_offset <= where &&
        where <= s->buffer_offset + s->active)
      {
  
        n = s->active - (where - s->buffer_offset);
!       memmove (new_buffer, s->buffer + (where - s->buffer_offset), n);
  
        s->active = n;
      }
*************** fd_alloc (unix_stream * s, gfc_offset wh
*** 458,464 ****
  
    s->buffer_offset = where;
  
!   s->len = BUFFER_SIZE;
  }
  
  
--- 472,484 ----
  
    s->buffer_offset = where;
  
!   /* free the old buffer if necessary */
! 
!   if (s->buffer != NULL && s->buffer != s->small_buffer)
!     free_mem (s->buffer);
! 
!   s->buffer = new_buffer;
!   s->len = read_len;
  }
  
  
*************** static try
*** 590,596 ****
  fd_sfree (unix_stream * s)
  {
    if (s->ndirty != 0 &&
!       (options.all_unbuffered || s->unbuffered))
      return fd_flush (s);
  
    return SUCCESS;
--- 610,617 ----
  fd_sfree (unix_stream * s)
  {
    if (s->ndirty != 0 &&
!       (s->buffer != s->small_buffer || options.all_unbuffered ||
!        s->unbuffered))
      return fd_flush (s);
  
    return SUCCESS;
*************** fd_close (unix_stream * s)
*** 791,796 ****
--- 812,820 ----
    if (fd_flush (s) == FAILURE)
      return FAILURE;
  
+   if (s->buffer != NULL && s->buffer != s->small_buffer)
+     free_mem (s->buffer);
+ 
    if (s->fd != STDOUT_FILENO && s->fd != STDERR_FILENO)
      {
        if (close (s->fd) < 0)
*************** fd_open (unix_stream * s)
*** 819,824 ****
--- 843,849 ----
    s->st.write = (void *) fd_write;
    s->st.set = (void *) fd_sset;
  
+   s->buffer = NULL;
  }
  
  
*************** init_error_stream (unix_stream *error)
*** 1377,1383 ****
    error->st.sfree = (void *) fd_sfree;
  
    error->unbuffered = 1;
! 
    return (stream *) error;
  }
  
--- 1402,1408 ----
    error->st.sfree = (void *) fd_sfree;
  
    error->unbuffered = 1;
!   error->buffer = error->small_buffer;
    return (stream *) error;
  }
  

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