Subject: | applications die() because of SIGCHLD vs. SIGCLD confusion |
Hi,
a Debian user reports the following (http://bugs.debian.org/708180):
From: "Steinar H. Gunderson" <sgunderson@bigfoot.com>
To: Debian Bug Tracking System <submit@bugs.debian.org>
Subject: applications die() because of SIGCHLD vs. SIGCLD confusion
Date: Mon, 13 May 2013 21:28:14 +0200
Package: libnet-server-perl
Version: 2.006-1
Severity: grave
Hi,
I have a starman application that regularly dies under load with a backtrace like:
Message: Can't use string ("") as a subroutine ref while "strict refs" in use at /usr/share/perl5/Net/Server/SIG.pm line 72, <$read> line 2002.
at /usr/share/perl5/Net/Server/SIG.pm line 72
Net::Server::SIG::check_sigs() called at /usr/share/perl5/Net/Server/PreForkSimple.pm line 337
Net::Server::PreForkSimple::close_children('Starman::Server=HASH(0x84e7a8)') called at /usr/share/perl5/Net/Server.pm line 735
Net::Server::server_close('Starman::Server=HASH(0x84e7a8)') called at /usr/share/perl5/Starman/Server.pm line 124
(...)
Some debugging shows that the problem is that several Net::Server modules
(e.g. Net::Server::PreforkSimple) tries to trap signals with Net::Server::SIG
using “CHLD” as the signal name. Net::Server::SIG in turn adds a signal handler
like this:
$SIG{$sig} = sub{ $Net::Server::SIG::_SIG{$_[0]} = 1; };
However, when that sub is called, it is called with “CLD” as signal, not
“CHLD” (seemingly Perl has two names for this). This in turn confuses
check_sigs, which wants to do this with $sig set to “CLD”:
$_SIG_SUB{$sig}->($sig);
whereupon the crash happens.
I think the smallest fix around this is something like
$sig = 'CLD' if ($sig eq 'CHLD');
in the top of register_sig(), but I might be mistaken.
In any case, this makes Net::Server::PreforkSimple, and probably several others,
rather unusable, since they may crash at almost any time, and there is no simple
workaround that I can see. (Thus the RC severity.)