Re: Oops... strange (to me) segfault problem



On Wed, 4 Aug 2004 18:55:47 +0900
Derek Martin <code pizzashack org> wrote:

On Wed, Aug 04, 2004 at 02:23:27AM -0400, John Vetterli wrote:
It looks like you're corrupting the free store.

A bonehead mistake... Sigh.  I was concerned about that, but I figured
that if the read returned less than BLOCK_SZ (the size of the pipe
buffer on Linux, IIRC), then the pipe must be empty, i.e. there's no
more input to read.

This is not true: read() can always return without having actually read
the amount of characters you specified.

I suspect the first call to read() reads less than BLOCK_SZ bytes,
in which case offset gets incremented but the memory block doesn't
get resized, so the next call to read() overwrites the data after
the end of the memory block.  



You may want to use the following to avoid buffer overflow:

while ( (status = read(pd[0], (buf + offset), BLOCK_SZ - offset)) 


  while ( (status = read(pd[0], (buf + offset), BLOCK_SZ)) ){
    if ( status == -1 ){

At this point you should examine errno to see what actually happend.

      fprintf(stderr, "get_keys(): read from pipe failed\n");
      free(buf);
      return NULL;
    }

    else if ( status == BLOCK_SZ ){
      if ( !(buf = (char *)realloc(buf, offset + BLOCK_SZ)) ){
        fprintf(stderr, "realloc() failed");
        free(buf);
        return NULL;
      }
    }

      else if ( !(buf = (char *)realloc(buf, offset + status)) ){
      /* handle error */
      }
      
    offset += status;
  }

I believe that will solve it (leaving BLOCK_SZ bytes available in the
region), and reduce memory wastage.



Gerald Emig



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]