🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.bugs.4bsd
Article #567

concurrent write(2) calls write bad data to file

#567
From: jas
Date: Wed, 04 Mar 1987 18:34
73 lines
2839 bytes
Has anyone ever encountered this one before?

The small program below forks, and then both parent and child
write the integers from 0 to 20000, one to a line, to stdout.
The parent prefixes each integer with 'P', the child with 'C'.
A separate write(2) call is used for each line, so stdio buffering
doesn't figure in here.

What we should all expect to see in the output file (remember, parent
and child share a seek pointer) is some interleaving of the parent's
output lines and the child's.  But on many 4.2-derived systems (see below),
about 20 of the 40,000 total write(2) calls result in nulls being
written to the file, instead of the data pointed at in the write(2) call.

Repeat-by:  Run the program below, directing stdout into a file.
Check the output file for nulls.

This bug appears to exist only on 4.2-derived systems.  So far, I have
found it on the following machines:

Microvax running Ultrix
CCI Power-6 running CCI's 4.2bsd port
CCI Power-6 running CCI's System V (internally, it's still derived from 4.2)
Sequent Balance/whatever
Pyramid 90x
Sun 3/whatever

The bug is NOT on:

AT&T 3B15 and 3B20 running you-know-what

I think I'm also running into a variant of this problem involving
spurious nulls being written to a pipe when a signal occurs at just
the wrong time, and another pipe write is done in the signal handler.
I haven't been able to duplicate that one (yet) in a simple test case, though.

Any of you kernel types care to dig into this one?  Otherwise, I'll have
to, sooner or later.

------------------------ BEGIN TEST PROGRAM -------------------------------
/*
** Do concurrent write(2) calls to the same file; on lots of
** 4.2-derived systems, bad data shows up on the file.
*/

main()

{
    register int seqno = 0;
    register int len;
    register int pid;
    char buf[32];

    if ( ( pid = fork() ) < 0 )
    {
	perror( "fork" );
	exit( 1 );
    }
    for ( seqno = 0; seqno != 20000; ++seqno )
    {
	sprintf( buf, "%c%d\n", pid ? 'P' : 'C', seqno );
	len = strlen( buf );
	if ( write( 1, buf, len ) != len )
	    perror( "write" );
    }
    exit( 0 );
}
------------------------ END TEST PROGRAM -------------------------
-- 
Jim Shankland
 ..!ihnp4!cpsc6a!\
                  rtech!jas
..!ucbvax!mtxinu!/
Technical Details
Message-ID: <692@rtech.UUCP>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!water!watnot!watmath!clyde!cbatt!ihnp4!houxm!mtuxo!mtune!codas!cpsc6a!rtech!jas

Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: arc1-ca.pugleaf.net!utzoo!utgpu!water!watnot!watmath!clyde!cbatt!ihnp4!houxm!mtuxo!mtune!codas!cpsc6a!rtech!jas
From: jas@rtech.UUCP
Newsgroups: comp.bugs.4bsd,comp.unix.wizards
Subject: concurrent write(2) calls write bad data to file
Message-ID: <692@rtech.UUCP>
Date: Wed, 4-Mar-87 13:34:46 EST
Article-I.D.: rtech.692
Posted: Wed Mar  4 13:34:46 1987
Date-Received: Sat, 7-Mar-87 00:19:47 EST
Organization: Relational Technology, Alameda CA
Lines: 73