Subject: Re: t7006 sometimes hangs in cronjobs on OS X

From: Jonathan Nieder <[email-masked]>
Date: Fri, 11 Feb 2011 20:03:21 -0600

Jeff King wrote:

> Yeah, it is probably stuck in some syscall. You could try instrumenting
> your test-terminal.perl like:
>
> diff --git a/t/test-terminal.perl b/t/test-terminal.perl
> index ee01eb9..1755017 100755
> --- a/t/test-terminal.perl
> +++ b/t/test-terminal.perl
> @@ -55,11 +55,15 @@ sub copy_stdio {
>  	defined $pid or die "fork failed: $!";
>  	if (!$pid) {
>  		close($out);
> +		print STDERR "child: pumping stderr\n";
[...]

Nice, I can reproduce this (kernel = Darwin 10.5.0, using Apple's perl
5.10.0).  With

	while ./test-terminal.perl echo hi >out.$i 2>&1
	do
		i=$(($i + 1))
		echo $i
	done

I get:

	$ cat out.28 
	child: pumping stdout
	child: pumping stderr
	hi
	child: done pumping stdout

Instrumenting Copy.pm, I can see that we are stuck in sysread.

	31984: child: pumping stdout
	31984: enter copy loop.
	31984: time to read 4096...
	31986: child: pumping stderr
	31984: read returns with 4
	31984: about to write "hi
	"
	31984: pump 4 - 0, result = 4
	31984: time to read 4096...
	31986: enter copy loop.
	31986: time to read 4096...
	31986: read returns with 0
	31986: about to write ""
	31986: done!
	31986: successful return.
	31986: copy returns with 1 errno=
	31986: child: done pumping stderr

Redirecting stderr by using 'xsendfile("elsewhere", $err);' avoids
trouble.  Asking stderr and stdout to go to different places, like so:

	./test-terminal.perl echo hi >out.$i 2>err.$i

does not avoid trouble.  Sometimes output includes some streams of
null bytes, which makes me suspect something awry in the kernel.