Tuesday, January 08, 2013

A simple solution to unbuffering for a debugger

A problem which I have run into recently is the fact that pipes in Windows are not recognized as interactive and thus the C standard library routines does full buffering.  I am using two pipes to implement the stdin, stdout and stderr for C/C++ programs being debugged.  My luck was great with Linux and OSX - not so good with Windows.  On Windows I had to do fflush(stdout) to see the test printed by printf.  (and also cout using \n rather than endl)  The problem exists in the library code which inspects the attached file descriptors (or handles) and decides that this is a batch type operation and buffering perhaps 4096 bytes is perfect.

The solution I came up with is to mix C and C++.  It works just fine with gcc compiling a C program and g++ compiling a C class file and finally linking the 2 object files with g++.  The trick is to take advantage of the fact that C++ constructors for static objects are called before main is called.  Fortunately they are called after the library has prepared all the I/O routines for normal use.

Here is my C++ code:


#include <cstdio>

class __UnBuffer
{
public:
    __UnBuffer();
    int x;
};

__UnBuffer::__UnBuffer()
{
    printf("Here we go\n");
    setbuf(stdout,NULL);
}

__UnBuffer _unBuffer;

The constructor is called for the one __UnBuffer object which sets the buffering to unbuffered for stdout and also prints a message.  This message was printed first in  my test and the data made it through the pipe immediately.  Surprisingly I got some 1 byte messages which I will have to accommodate in the Qt ebe, but at least I have a simple solution which works well.

I ran into other folks who were writing GUI debuggers and they seemed to have difficulties.  I am not sure how they coped, but I didn't read a solution from any of those people.  Hopefully they will run into my solution and get past this stupid issue.

No comments: