LP#1697029 Undef syswrite() logging example user/berick/lp1697029-server-syswrite-undef
authorBill Erickson <berickxx@gmail.com>
Fri, 9 Jun 2017 17:01:46 +0000 (13:01 -0400)
committerBill Erickson <berickxx@gmail.com>
Fri, 9 Jun 2017 17:01:46 +0000 (13:01 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
src/perl/lib/OpenSRF/Server.pm

index dcf44fe..b6a27fb 100644 (file)
@@ -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;
 }