Re: fork() memory corruption... is this glibc2 or kernel?

Adam Sulmicki (adam@cfar.umd.edu)
Sun, 21 Jun 1998 13:13:08 -0400


->That is, glibc is correct and the bug is in your program. And
->issuing a fflush() before the fork() is the correct fix.

Exactly.

[note, I have not seen the original program, but from all the talk
it seems as if it the cause.]

To quote from "Advanced Programming in the UNIX Environment" by
W. Richard Stevens. [pp744, ISBN 0-201-56317-7 ]

Ch 5 Standard I/O Library
5.4 Buffering.
pg 123 (seriously, it is 123 :)
"
ANSI C requires the following buffering characteristics:

1. Standard input and standard output are fully buffered, if and only
if they do not refer to an interactive device.
2. Standard error is never fully buffered.
"
...
"
doesn't tell us whether standard input and standard output can be
unbufffered or line bufffered if they refer to an interactive device
"
...
"
Both SVR4 and 4.3+BSD default to the following types of buffering:

o Standard error is always unbuffered.
o All other streams are line buffered if they refer to a terminal
device; otherwise they are fully buffered.
"

Ch 8 Process Control
8.3 /fork/ function
pg 189-190

the page present an example of program program using fork which has
"correct" output if the output goes to stdio, and "doubles" lines
if the output it piped to file (non-interactive output). And gives
the following explanation:
"
we never know if the child starts executing before the parent or vice versa
"
..
" note the interaction of /fork/ with the I/O functions in the example
program ".."the /write/ function is not buffered. Since /write/ is called
before the /fork/, its data is written once to standard output. The
standard I/O library, however, is buffered.".."standard output is
line buffered if it's connected to a terminal device, otherwise
it is fully buffered. When we run program interactively we get
only a single copy of the /printf/ line, because the standard output
buffer is flushed by newline. But when we redirect standard output
to a file we get two copies of the /printf/ line. What has happened
in the second case is that the /printf/ before the /fork/ is called once,
but the line remains in the buffer when /fork/ is called.
This buffer is then copied into the child, when parent's data space is
copied to the child. Both the parent and child now have a standard
I/O buffer with this line in it. The second /printf/ right before the
/exit/, just appends its data to the existing buffer. When each
process terminates, its copy of the buffer is finally flushed.
"

Hope it helps

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu