h1234 has asked for the wisdom of the Perl Monks concerning the following question:

I've been researching perl and forking, and it seems like I'm doing everything correct, however my program doesn't seem to reap all the child processes, resulting in a bunch of zombies accumulating. The code has a master program, and then it looks like the zombies are being created in a supporting library. Sometimes Zombies are created using this subroutine, other times not. Other users of the program don't have any zombie issues, but my system does. I have no idea where to go, so I'd really appreciate any insight or suggestions that anyone can provide:

---------------------------------------- main.pl require 'library.pl'; $SIG{CHLD} = \&child_death; sub child_death { use POSIX ":sys_wait_h"; local ($!, $?); my $pid; do { $pid = waitpid( -1, WNOHANG ); print "reaped $pid" . ($? ? " with exit $?" : '') . "\n"; } until $pid <= 0; } ---------------------------------------- ---------------------------------------- library.pl &print_socket_fork_unix( $socket, $html, $close ); sub print_socket_fork_unix { my ( $socket, $html, $close ) = @_; my $pid = fork; if ( $? == -1 ) { print "$pid - Can't launch child: $!\n"; } elsif ( $? & 0x7F ) { print "$pid - Child killed by signal ".( $? & 0x7F )."\n"; } elsif ( $? >> 8 ) { print "$pid - Child exited with error ".( $? >> 8 )."\n"; } else { print "$pid - Child executed successfully\n"; } if ( defined $pid && $pid == 0 ) { print $socket $html; $socket->shutdown(2) if $close; $socket->close unless $close; print "$pid exiting process\n"; &POSIX::_exit(0) } else { shutdown( $socket, 0 ); print " $pid shutdown socket\n"; } } ----------------------------------------

Replies are listed 'Best First'.
Re: Partial Zombie collection??
by hippo (Archbishop) on Aug 30, 2017 at 21:33 UTC

    There's no definition of $socket in your code as listed so it can't be run as it stands (at least, not to a smooth conclusion).

    Help us to help you:

    • Provide a Short, Self-Contained, Correct Example
    • Use strict. Always.
    • Avoid the perl4isms which exist in the code you've listed. These detract from the legibility of the code and might be the cause of problems which are less familiar these days.
    • Maybe one or two comments explaining why you have chosen the methods you have, eg: why call &POSIX::_exit(0) rather than exit 0?

    A look at the rest of the Basic debugging checklist will stand you in good stead as well. Once we have a runnable code we can test there will be a better understanding of the problem on both sides.

Re: Partial Zombie collection??
by locked_user sundialsvc4 (Abbot) on Aug 30, 2017 at 20:44 UTC

    When you say that “the zombies are being created in a supporting library,” is this library a Perl library?   Are all of the processes being created under the auspices of the Perl interpreter, such that said interpreter would be aware of them?

    (In other words, is the library.pl that you have posted, actually representative of the (Perl?) source-code that you are referring to?   Is all of it Perl, or is anything potentially out-of-band to the context of the Perl interpreter?)

    Also, which operating-system is this?   What perl-version?

      ubuntu 14.04, perl 5.18.2.

      Yes sorry, this is a snippet of a rather large open source program. the perl library is a web server, so I left out all the details around how the sub is called to make the post concise. If it helps, I can put in the URL to the source file on github. If the request is larger than a certain byte size, the print to socket is forked. Sometimes those are reaped, sometimes they are not.

        Caveat lector

        Regards, Karl

        «The Crux of the Biscuit is the Apostrophe»

        perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help