David Laight wrote:
>
> We had to fix a nasty bug, a daemon process (written when max fd was 19)
> did close(0), close(1) and close(2) then used them for specific purposes.
> fd 1 was used as a pipe to a different daemon.
>
> A coding error meant that an sprintf() call was actually a printf(),
> since it was only generating a log message no one had noticed that
> the text was incorrect (the buffer contained text from a previous call).
> Everything ran fine until over a hundred cycles through the buggy code,
> at that point the stdio buffer filled and got flushed to fd 1 - the
> daemon at the other end took 4 ascii characters as a message length
> and went into a discard loop for the overlong message.
>
> This wasn't actually easy to find - but trivial to fix!
That's why:
"Some daemons open /dev/null ... and dup the descriptor to std
in/out/err. ... The reason ... is so that any library function called by
the daemon that assumes it can read from stdin, or write to either
stdout/err, will not fail...." W.R. Stevens, UNPv1, page 337.
>
> However it could equally well happen if a library routine wrote to
> stdout, stderr, fd==0 or fd==1.
> About the only valid places are /dev/tty, /dev/console or via syslog().
Not even those (console is only ok if someone is watching the prog
execution, and syslog only if someone looks in, which isn't really the
case for interactive progs). so the only place is nowhere. libc
shouldn't write (except in a function clearly designed to do so).
The err* family functions write to stderr and should thus be called with
care.
> malloc() is borked...
Oh, you reminded me of "chunk is already free"
Once again, I won't sleep ;-p