After upgrading to Perl 5.24.4 we repeatedly get this error in logs (without pointing the filename and line number):
Unable to flush stdout: Broken pipe
We have no idea what causes this error.
Is there any advice how to understand the cause of the error?
The error comes from perl.c, line 595:
PerlIO_printf(PerlIO_stderr(), "Unable to flush stdout: %s",
Strerror(errno));
This line is part of perl_destruct
, which is called to shut down the perl interpreter at the end of the program.
As part of the global shutdown procedure, all still open filehandles are flushed (i.e. all buffered output is written out). The comment above says:
/* Need to flush since END blocks can produce output */
/* flush stdout separately, since we can identify it */
The error message is not listed in perldoc perldiag
, which is arguably a documentation bug. It was probably overlooked because it's not a real warn
or die
call, it's effectively just print STDERR $message
. It's not associated with a file name or line number because it only happens after your program stops running (i.e. after a call to exit
or because execution fell off the end of the main script).
This is very general advice, but
use Carp::Always;
at the top of the script, or running with
perl -MCarp::Always the_script.pl arg1 arg2 ...
will get Perl to produce stack traces with every warning and error.
Broken pipe
is the error string associated with system error EPIPE
. One receives this error when writing to a closed pipe. Writing to a closed pipe usally results in the process being killed by a SIGPIPE, so it means the behaviour of SIGPIPE was changed from its default.
$ perl -e'
$SIG{PIPE} = "IGNORE";
print "foo\n"
or die("Can\x27t write to STDOUT: $!\n");
sleep(2);
close(STDOUT)
or die("Unable to flush STDOUT: $!\n");
' | perl -e'sleep(1)'
Unable to flush STDOUT: Broken pipe
As melpomene discovered, the error is automatically output if you write to a broken pipe in an END
block.
$ perl -e'
$SIG{PIPE} = "IGNORE";
sleep(2);
END { print "foo\n"; }
' | perl -e'sleep(1)'
Unable to flush stdout: Broken pipe
This isn't necessarily a problem, although it could be a sign that a process is exiting prematurely.