Re: g_io_channel_read_chars() loop



> From: Joel Becker <jlbec evilplan org>
>
> 	So, I did an update yesterday.  Lo and behold, my application
> starts looping.  Unfortunately, it seems pretty random, but not at all
> rare.  I am merely doing a g_io_add_watch() on a subprocess file
> descriptor.  In my GPollFunc, I call g_io_channel_read_chars().
> Sometimes the run works just fine.  Others, I get a loop here:
>
>    1676       do
>    1677         {
>    1678           prevchar = nextchar;
>    1679           nextchar = g_utf8_next_char (nextchar);
>    1680         }
>    1681       while (nextchar < channel->encoded_read_buf->str + got_bytes);
>
> 	Much gdbing later, I discover that got_bytes == 17,
> channel->encoded_read_buf->len == 17, but channel->encoded_read_buf->str
> == "\0garbage".  So g_utf8_next_char() will never walk to the end of the
> string, and the while expression will never return false.
> 	I've looked at the code extensively, and at the changes from the
> last checkin, and I don't see anything out of the ordinary.  It looks
> clean to me.  But I'm still getting this behavior.  It happens on both
> Linux 2.2 and 2.4, though it triggers more often on 2.4.

The contents of encoded_read_buf should always be valid UTF-8,
and the length should always match the length of valid data,
so it sounds like it's being corrupted elsewhere and you're
just finding out in g_io_channel_read_chars ().

What this sounds like is a call to g_string_set_size () to
add some space to read in data, without a corresponding call
to g_string_truncate () to set the length of the string
equal to the length of the valid data. The only place
in giochannel.c that g_string_set_size () is called
on encoded_read_buf is in g_io_channel_fill_buffer (),
which is followed by a call to g_string_truncate () about
5-10 lines later. No loops, no branches, nothing.
This is very puzzling.

Two other less likely possiblities for the origin of the
bug are: 1) a bug in g_string_truncate () or 2) g_iconv
is not correctly setting outbytes_left. Neither of these
seem likely. In g_io_channel_fill_buffer, outbytes_left
is declared as size_t instead of gsize, but I don't think
that should matter.

Could you send more details about what you are doing when
the bug occurs?

Ron Steinke




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