Help me isolate a bug!

David Rasmussen david.rasmussen@gmx.net
Sat Sep 28 07:54:00 GMT 2002


Hello there!

I think I've found a bug in libstdc++, but I'm not sure. And I'm not sure
how to isolate it. Could someone help me?

What I am doing is basically this:

I want to have non-blocking input from stdin. Of course, C++ doesn't make
this possible. So I use a combination of POSIX and C++. What I do is this:

I have a function, InputWaiting(), that return true if there unprocessed
input on stdin, and false if there isn't:

bool InputWaiting()
{
 if (cin.rdbuf()->in_avail())
  return true;

 fd_set readfds;
 FD_ZERO(&readfds);
 FD_SET(fileno(stdin), &readfds);

 struct timeval tv;
 tv.tv_sec = 0;
 tv.tv_usec = 0;
 select(16, &readfds, 0, 0, &tv);

 int data = FD_ISSET(fileno(stdin), &readfds);
 return (data != 0);
}

The idea is that data is either waiting in cin's buffer, or in the stdin
file of the OS, which is checked by select. As I see it, the data can't be
anywhere else.
>From another function, I check if input is waiting, and if it is, I fetch a
whole line. If a whole line is not yet available, this will be blocking. But
due to the nature of my application, the rest of the line will come quickly,
so this is ok:

void ProcessOneInputLine()
{
 if (currentLineParsed)
  getline(cin,currentLine);

 currentLineParsed = ParseInput(currentLine); // ParseInput returns false if
the line couldn't be parsed, yet. This means we have to abort what we are
doing.
}

void ProcessWaitingInput()
{
 while (!currentLineParsed || InputWaiting())
 {
  ProcessOneInputLine();

  if (!currentLineParsed)
   abortSearch = true; // The line couldn't be passed while we're busy, so
we abort, and the line gets processed elsewhere.

  if (abortSearch)
   return;
 }
}

This works on all sorts of platforms, and compilers I've tried (Sun, Intel,
gcc 2.95.x with it's libstdc++2), but it hasn't worked since gcc 3.0, and
libstdc++3.
Is my code incorrect? Or does libstdc++3 have a bug?
What happens, apparently, is that sometimes, InputWaiting() will return
false, even if there is input. And it will keep doing so from then on. It
happens, I think, for instance when more than one line is sent at a time on
stdin. For instance if this is coming on stdin:
foo\nbar\n
It doesn't happen when just
foo\n
is sent and then a moment later
bar\n
is sent.

I've tried both cin.setf(ios::unitbuf), and cin.rdbuf()->setbuf(NULL,0) to
make cin unbuffered. But this doesn't help.

Any ideas?

/David



More information about the Libstdc++ mailing list