I tried something along the lines of #1 and #2 and it still causes an Apache2 child segmentation fault after a few successful requests. Here is the code I used:
sub RunCommand
{
my $pgm = shift;
my @execargs = @_;
$SIG{CHLD} = 'IGNORE';
# This should flush stdout.
my $ofh = select(STDOUT);$| = 1;select $ofh;
warn "Before first fork $$";
my $kpid = fork;
defined($kpid) || die;
if ($kpid)
{
# Parent process
my $w = waitpid($kpid, 0);
# warn "waitpid returned $w\n";
}
else
{
close STDIN;
close STDOUT;
close STDERR;
setsid() >= 0 or die;
my $gpid = fork;
defined($gpid) or die;
if ($gpid)
{
my $w = waitpid($gpid, 0);
# warn "waitpid returned $w\n";
}
else
{
open(STDIN, "</dev/null") or die;
open(STDOUT, ">/dev/null") or die;
open(STDERR, ">/dev/null") or die;
# Child process
exec($pgm, @execargs) or die;
}
CORE::exit(0);
}
}
I invoked that function from within my mod_perl2 response handler as:
&RunCommand("/home/dbooth/rdf-pipeline/trunk/pid.perl");
The pid.perl command I ran uses no stdin, stdout or stderr, but merely logs its PID and date to /tmp/pid.txt:
#! /usr/bin/perl -w
# Append the PID and date/time to /tmp/pid.txt
# so that we can verify that this ran.
use HTTP::Date;
my $tmp = "/tmp/pid.txt";
open(my $fh, ">>$tmp") or die;
my $t = time2str(time);
print $fh "pid: $$ $t\n";
close $fh or die;
exit 0;
P.S. See also the update to my original post, in which I note that this command still runs successfully during the HTTP request in which the Apache2 child process dies from a segmentation fault.
|