Странная ошибка после обновления Perl: Невозможно сбросить стандартный вывод - PullRequest
0 голосов
/ 24 мая 2018

После обновления до Perl 5.24.4 мы постоянно получаем эту ошибку в журналах (без указания имени файла и номера строки):

Невозможно очистить стандартный вывод: Сломанный канал

Мы не знаем, что является причиной этой ошибки.

Есть ли какой-нибудь совет, как понять причину ошибки?

Ответы [ 3 ]

0 голосов
/ 31 августа 2018

Ошибка происходит от perl.c, строка 595 :

        PerlIO_printf(PerlIO_stderr(), "Unable to flush stdout: %s",
                      Strerror(errno));

Эта строка является частью perl_destruct, которая вызывается для отключенияинтерпретатор perl в конце программы.

Как часть глобальной процедуры завершения работы, все все еще открытые файловые дескрипторы сбрасываются (т.е. все буферизованные выходные данные записываются).В вышеприведенном комментарии говорится:

 /* Need to flush since END blocks can produce output */
 /* flush stdout separately, since we can identify it */

Сообщение об ошибке не указано в perldoc perldiag, что, возможно, является ошибкой документации.Вероятно, это упустили из виду, потому что это не настоящий вызов warn или die, а просто print STDERR $message.Он не связан с именем файла или номером строки, потому что это происходит только после того, как ваша программа перестает работать (т. Е. После вызова exit или из-за того, что выполнение прекратилось до конца основного сценария).

0 голосов
/ 02 сентября 2018

Broken pipe - строка ошибки, связанная с системной ошибкой EPIPE.Получается эта ошибка при записи в закрытую трубу.Запись в закрытый канал обычно приводит к завершению процесса SIGPIPE, поэтому это означает, что поведение SIGPIPE было изменено по умолчанию.

$ 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

При обнаружении мелпомены ошибкаавтоматически выводится, если вы пишете в разорванный канал в блоке END.

$ perl -e'
   $SIG{PIPE} = "IGNORE";
   sleep(2);
   END { print "foo\n"; }
' | perl -e'sleep(1)'
Unable to flush stdout: Broken pipe

Это не обязательно проблема, хотя это может быть признаком преждевременного завершения процесса.

0 голосов
/ 24 мая 2018

Это очень общий совет, но

use Carp::Always;

в верхней части скрипта или работа с

perl -MCarp::Always the_script.pl arg1 arg2 ...

заставит Perl генерировать трассировки стека при каждом предупреждении и ошибке.

...