Weird error after Perl upgrade: Unable to flush st

2019-01-19 09:16发布

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?

3条回答
对你真心纯属浪费
2楼-- · 2019-01-19 09:32

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.

查看更多
【Aperson】
3楼-- · 2019-01-19 09:38

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).

查看更多
虎瘦雄心在
4楼-- · 2019-01-19 09:46

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.

查看更多
登录 后发表回答