Skip Menu |

This queue is for tickets about the Net-Server CPAN distribution.

Report information
The Basics
Id: 86815
Status: open
Priority: 0/
Queue: Net-Server

People
Owner: Nobody in particular
Requestors: DROLSKY [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: [PATCH] Add logging when a child exits abnormally
The attached patch adds some additional logging when a child exits unexpectedly. In our case, we had some code segfault but nothing got logged. Unfortunately, I didn't write any tests, but I did test this on a test server here. The test suite didn't have anything I could easily extend to test this.
Subject: net-server.patch
diff -ru Net-Server-2.007/lib/Net/Server/PreFork.pm Net-Server-2.007.new/lib/Net/Server/PreFork.pm --- Net-Server-2.007/lib/Net/Server/PreFork.pm 2013-01-10 01:16:20.000000000 -0600 +++ Net-Server-2.007.new/lib/Net/Server/PreFork.pm 2013-07-09 14:43:16.749470956 -0500 @@ -255,17 +255,20 @@ @{ $prop }{qw(last_checked_for_dead last_checked_for_waiting last_checked_for_dequeue last_process last_kill)} = (time) x 5; + my $reaper = sub { + while ( defined( my $chld = waitpid( -1, WNOHANG ) ) ) { + last unless $chld > 0; + $self->{'reaped_children'}->{$chld} = $? + ; # We'll deal with this in coordinate_children to avoid a race + } + }; + register_sig( PIPE => 'IGNORE', INT => sub { $self->server_close() }, TERM => sub { $self->server_close() }, HUP => sub { $self->sig_hup() }, - CHLD => sub { - while (defined(my $chld = waitpid(-1, WNOHANG))) { - last unless $chld > 0; - $self->{'reaped_children'}->{$chld} = 1; # We'll deal with this in coordinate_children to avoid a race - } - }, + CHLD => $reaper, QUIT => sub { $self->{'server'}->{'kind_quit'} = 1; $self->server_close() }, TTIN => sub { $self->{'server'}->{$_}++ for qw(min_servers max_servers); $self->log(3, "Increasing server count ($self->{'server'}->{'max_servers'})") }, TTOU => sub { $self->{'server'}->{$_}-- for qw(min_servers max_servers); $self->log(3, "Decreasing server count ($self->{'server'}->{'max_servers'})") }, @@ -274,10 +277,7 @@ $self->register_sig_pass; if ($ENV{'HUP_CHILDREN'}) { - while (defined(my $chld = waitpid(-1, WNOHANG))) { - last unless $chld > 0; - $self->{'reaped_children'}->{$chld} = 1; - } + $reaper->(); } while (1) { @@ -345,9 +345,9 @@ # deleted SIG{'CHLD'} reaped children foreach my $pid (keys %{ $self->{'reaped_children'} }) { - delete $self->{'reaped_children'}->{$pid}; # delete each pid one by one to avoid another race + my $exit = delete $self->{'reaped_children'}->{$pid}; # delete each pid one by one to avoid another race next if ! $prop->{'children'}->{$pid}; - $self->delete_child($pid); + $self->delete_child($pid, $exit); } # re-tally the possible types (only twice a minute) @@ -431,7 +431,7 @@ ### delete_child and other modifications contributed by Rob Mueller sub delete_child { - my ($self, $pid) = @_; + my ($self, $pid, $exit) = @_; my $prop = $self->{'server'}; my $child = $prop->{'children'}->{$pid}; @@ -442,6 +442,18 @@ return if ! exists $prop->{'children'}->{$pid}; # Already gone? + # This means there was some sort of abnormal exit for the child, like a + # segfault. + if ($exit) { + my $status = $exit >> 8; + my $signal = $exit & 127; + my $message = "Child process $pid exited with status $status"; + $message .= " - signal was $signal" + if $signal; + + $self->log(1, $message); + } + my $status = $child->{'status'} || $self->log(2, "No status for $pid when deleting child"); --$prop->{'tally'}->{$status} >= 0 || $self->log(2, "Tally for $status < 0 deleting pid $pid"); $prop->{'tally'}->{'time'} = 0 if $child->{'hup'};
On Tue Jul 09 15:47:20 2013, DROLSKY wrote: Show quoted text
> The attached patch adds some additional logging when a child exits > unexpectedly. In our case, we had some code segfault but nothing got > logged. > > Unfortunately, I didn't write any tests, but I did test this on a test > server here. The test suite didn't have anything I could easily extend > to test this.
Bump :)