This is the mail archive of the libc-hacker@sourceware.cygnus.com mailing list for the glibc project.


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

hounddog.cc



The problem seems to be somewhere in libio.  Basically, hounddog.cc is
doing this:

- read 8 bytes
- seek back to the start of the file, read 3 bytes, seek back
  again, read 5 bytes
- seek to the start again
- read 7 bytes one-at-a-time

- read 8 bytes (1 byte that's been seen before, 7 new bytes)

and the 1 byte is getting lost.

At the start of the 8-byte read, we are in the backup buffer and there
are no characters available, and so _IO_switch_to_main_get_area is called.
*fp looks like this:

$55 = {_flags = -72539765, _IO_read_ptr = 0x1854d65 "", _IO_read_end =
  0x1854d65 "", _IO_read_base = 0x1854d00 "", _IO_write_base =
  0x1853d37 "d\001\205<Ø", _IO_write_ptr = 0x1853d37 "d\001\205<Ø",
  _IO_write_end = 0x1853d37 "d\001\205<Ø", _IO_buf_base = 0x1853d37
  "d\001\205<Ø", _IO_buf_end = 0x1853d38 "\001\205<Ø", _IO_save_base =
  0x1853d37 "d\001\205<Ø", _IO_backup_base = 0x1854d5e "hello!\n",
  _IO_save_end = 0x1853d38 "\001\205<Ø", _markers = 0x7ffff808, _chain
  = 0x0, _fileno = 0, _blksize = 0, _old_offset = 0, _cur_column = 0,
  _vtable_offset = 0 '\000', _shortbuf = "d", _lock = 0x1853cd8,
  _offset = 0xffffffffffffffff, _IO_save_ptr = 0x1853d38 "\001\205<Ø",
  _unused2 = '\000' <repeats 59 times>}

The characters being read are "hello!\nd", the first 7 of them are in
the backup buffer (and have already been read), the last one is in the
usual read buffer (in _IO_save_base).  [I know that the last character
read was the \n.] But _IO_save_ptr is pointing to past the 'd'
(because that's where _IO_read_ptr was pointing when it was saved),
and thus the 'd' gets lost, which is the first problem.

The only marker is
(gdb) print fp->_markers[0]
$57 = {_next = 0x0, _sbuf = 0x1853cf0, _pos = 0}

which looks fine to me---it's pointing to the 'd' (I hope).  It was
set to the file position just before the start of this read.

This is the -b0 case.  The -b2 case is similar except that "\nd" is in
the normal read buffer and "hello!" is in the backup buffer, and the
problem happens on the last of the one-at-a-time reads.  Higher
settings of -b are similar too, problems start when
_IO_switch_to_main_get_area is called.

Further work on this will probably need someone who understands what
the semantics of a streammarker is.  Is it supposed to basically be an
off_t (well, a fpos_t)?

I think the problem is being caused by two uses of the backup area.
One use is for ungetc(), the other use is for seeking in a file that
can't be seeked in.  My suggestion is that the normal read area is a
better choice for the second use, which has the advantage that
ungetc() doesn't appear to change the file's contents.

-- 
Geoffrey Keating <geoffk@ozemail.com.au>


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