From: Bill Erickson Date: Fri, 9 Jun 2017 17:01:46 +0000 (-0400) Subject: LP#1697029 Undef syswrite() logging example X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=refs%2Fheads%2Fuser%2Fberick%2Flp1697029-server-syswrite-undef;p=working%2FOpenSRF.git LP#1697029 Undef syswrite() logging example Signed-off-by: Bill Erickson --- diff --git a/src/perl/lib/OpenSRF/Server.pm b/src/perl/lib/OpenSRF/Server.pm index dcf44fe..b6a27fb 100644 --- a/src/perl/lib/OpenSRF/Server.pm +++ b/src/perl/lib/OpenSRF/Server.pm @@ -293,6 +293,31 @@ sub write_child { my($self, $child, $msg) = @_; my $xml = encode_utf8(decode_utf8($msg->to_xml)); + # XXX: LP#1697029 + # Inspect $child first to confirm its initial state. + # $child will stringify to its PID. + my $run_away = 0; + if ($child) { + + if ($child->{dead}) { + $run_away = 1; + $logger->error("server: child $child is dead in write_child()"); + + } elsif (!$child->{pipe_to_child}) { + $run_away = 1; + $logger->error("server: pipe_to_child is undef for child ". + "$child (num_requests=".$child->{num_requests}); + } + } else { + $run_away = 1; + $logger->error("server: write_child() called with undef child"); + } + + if ($run_away) { + $logger->error("server: unable to write message to child: $xml"); + return; # avoid crash + } + # tell the child how much data to expect, minus the header my $write_size; {use bytes; $write_size = length($xml)} @@ -302,6 +327,20 @@ sub write_child { $self->{sig_pipe} = 0; local $SIG{'PIPE'} = sub { $self->{sig_pipe} = 1; }; + + # XXX: LP#1697029 + # Double check pipe_to_child, which could have been closed + # and deleted via SIGCHLD handler. + if ($child->{dead}) { + $logger->error("server: child $child is dead in write_child(). ". + "unable to send message: $xml"); + return; # avoid syswrite crash + + } elsif (!$child->{pipe_to_child}) { + $logger->error("server: pipe_to_child is undef for child $child. ". + "unable to send message: $xml"); + return; # avoid syswrite crash + } # send message to child data pipe syswrite($child->{pipe_to_child}, $write_size . $xml); @@ -415,6 +454,7 @@ sub reap_children { $self->{num_children}--; delete $self->{pid_map}->{$pid}; delete $child->{$_} for keys %$child; # destroy with a vengeance + $child->{dead} = 1; # in case other references to $child exist } $self->spawn_children unless $shutdown; @@ -583,6 +623,7 @@ sub new { $self->{parent} = $parent; # Controller parent process $self->{num_requests} = 0; # total serviced requests $self->{sig_pipe} = 0; # true if last syswrite failed + $self->{dead} = 0; # true if child has been cleaned via SIGCHLD return $self; }