Я отвечаю на свой вопрос здесь (насколько мне известно на сегодняшний день):
Ошибка исчезла, если вставить эти две строки:
$SIG{CHLD} ||= 'DEFAULT';
$SIG{HUP} ||= 'DEFAULT';
Я бы не назвал это исправление, а скорее обходной путь, потому что значение «ПО УМОЛЧАНИЮ» должно вызывать то же поведение, что и отсутствие значения, соответственно undef
.
Сообщение об ошибке является внутренней ошибкой Perl. Интерпретатор выручает здесь в качестве защиты от ошибок обработки сигналов в Perl.
При этом нет простого примера, который воспроизводит ошибку. И если бы он был, это было бы ошибкой в Perl.
Подобная ошибка сообщалась для параллельной GNU некоторое время a go: https://lists.gnu.org/archive/html/bug-parallel/2016-10/msg00000.html
Обнаруженная ошибка имеет несколько общих черт с ошибкой, с которой я столкнулся, а именно: она произошла после fork()
ing.
Мое приложение - это сервер, основанный на Net::Server
, и ошибка происходит, когда обработчик запроса порождает дочерний процесс. Интересно, что сообщение об ошибке (и выход) происходит за до , когда дочерний процесс завершается.
Дочерний процесс может потенциально выполняться очень долго. Поэтому он становится лидером сеанса с setsid()
, все открытые дескрипторы файлов закрываются, и стандартный ввод перенаправляется на /dev/null
до вызова exec()
. Другими словами, это своего рода демонизация.
Следует также отметить, что ошибка исчезает при выполнении небольших изменений в коде, например, при сбросе содержимого %SIG
для целей отладки.
Ошибка также не возникла, с Perl версиями 5.8.9, 5.14.4 и 5.16.3. С 5.18.4, 5.26.2 и 5.30.2 его всегда можно воспроизвести. Все эти исполняемые файлы были созданы без поддержки потоков интерпретатора.