This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch, libgfortran] [4.3 Regression] crash when printing big character variable
- From: Jerry DeLisle <jvdelisle at verizon dot net>
- To: Fortran List <fortran at gcc dot gnu dot org>
- Cc: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 09 Jul 2007 20:32:08 -0700
- Subject: [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;
}