Michael Tokarev wrote:

...
>   if (__fpending (stdout) == 0)
[]
> size_t
> __fpending (FILE *fp)
> {
>   if (fp->_mode > 0)
>     return fp->_wide_data->_IO_write_ptr - fp->_wide_data->_IO_write_base;
>   else
>     return fp->_IO_write_ptr - fp->_IO_write_base;
> }

I was able to debug it with gdb-5.1 (gdb-5.0 wan't do this).
Now, at in the __fpending(fp = stdout) I have:

(gdb) p fp
$9 = (FILE *) 0x401468c0
(gdb) p *fp
$10 = {_flags = -72540028, _IO_read_ptr = 0x0, _IO_read_end = 0x0, 
  _IO_read_base = 0x0, _IO_write_base = 0x0, _IO_write_ptr = 0x0, 
  _IO_write_end = 0x0, _IO_buf_base = 0x0, _IO_buf_end = 0x0, 
  _IO_save_base = 0x0, _IO_backup_base = 0x0, _IO_save_end = 0x0, 
  _markers = 0x0, _chain = 0x40146840, _fileno = 1, _blksize = 0, 
  _old_offset = -1, _cur_column = 0, _vtable_offset = -72 '¸', _shortbuf = "", 
  _lock = 0x40146890, _offset = 1075079104, _codecvt = 0x0, _wide_data = 0x0, 
  _mode = 1, 
  _unused2 = '\000' <repeats 32 times> ... }

Here, mode is > 1, so __fpending will try to dereference null pointer,
hence the sigsegv.  This was the `rm' command, run w/o any argument
(it should produce error message and exit in this case) -- there was
no output produced to stdout yet.  In contrast, stderr (rm was written
to stderr something) looks good:

(gdb) p *stderr
$13 = {_flags = -72537977, _IO_read_ptr = 0x40146987 "\n\020i\024@Àg\024@", 
  _IO_read_end = 0x40146987 "\n\020i\024@Àg\024@", 
  _IO_read_base = 0x40146987 "\n\020i\024@Àg\024@", 
  _IO_write_base = 0x40146987 "\n\020i\024@Àg\024@", 
  _IO_write_ptr = 0x40146987 "\n\020i\024@Àg\024@", 
  _IO_write_end = 0x40146987 "\n\020i\024@Àg\024@", 
  _IO_buf_base = 0x40146987 "\n\020i\024@Àg\024@", 
  _IO_buf_end = 0x40146988 "\020i\024@Àg\024@", _IO_save_base = 0x0, 
  _IO_backup_base = 0x0, _IO_save_end = 0x0, _markers = 0x0, 
  _chain = 0x401468c0, _fileno = 2, _blksize = 0, _old_offset = -1, 
  _cur_column = 0, _vtable_offset = -72 '¸', _shortbuf = "\n", 
  _lock = 0x40146910, _offset = 1075079104, _codecvt = 0x0, _wide_data = 0x0, 
  _mode = 0, 
  _unused2 = ... }

I can force the stdout to initialize at this point, by calling
e.g. `p puts("")' from within gdb, and after that *fp looks like
(another session so addresses should be different):

(gdb) p *fp
$12 = {_flags = -72537468, _IO_read_ptr = 0x4014e000 "\n", 
  _IO_read_end = 0x4014e000 "\n", _IO_read_base = 0x4014e000 "\n", 
  _IO_write_base = 0x4014e000 "\n", _IO_write_ptr = 0x4014e000 "\n", 
  _IO_write_end = 0x4014e000 "\n", _IO_buf_base = 0x4014e000 "\n", 
  _IO_buf_end = 0x4014e400 "", _IO_save_base = 0x0, _IO_backup_base = 0x0, 
  _IO_save_end = 0x0, _markers = 0x0, _chain = 0x40146880, _fileno = 1, 
  _blksize = 0, _old_offset = -1, _cur_column = 0, _vtable_offset = -72 '¸', 
  _shortbuf = "", _lock = 0x401468d0, _offset = 1075079168, _codecvt = 0x0, 
  _wide_data = 0x0, _mode = 1, 
  _unused2 = ... }

Here, while other pointers was inited, _mode and _wide_data are still
conflicting from the __fpending point of view (it will sigsegv just fine).

This is 2.2.4-19.3.  The same is with 2.2.4-19.  The same is with older
binutils I used since Jun.  But I have glibc-2.2.4-19 compiled at october
that is happy at this point.  I can't debug it since I stripped the
library symbols, unfortunately...  Next is to try 2.2.3 -- tomorrow.

Interesting.  And, very unfortunate for me, I have no time debugging
this now -- a machine should be ready yesterday but it wan't run... :(
Oh well... :)

Regards,
 Michael.



_______________________________________________
Redhat-devel-list mailing list
[EMAIL PROTECTED]
https://listman.redhat.com/mailman/listinfo/redhat-devel-list

Reply via email to