Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

YA fork() question: catching runaway and erroneous processes

by stefan k (Curate)
on Jul 28, 2004 at 07:16 UTC ( [id://377945]=perlquestion: print w/replies, xml ) Need Help??

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

Fellow Monks,
once again yet another fork()-question is posted. I definetely think there should be a tutorial around but I couldn't find any. And reading man perlipc didn't make me much smarter, too. Thus here I go...

The problem is: I need to start a program that is known to hang from time to time and to crash at other times. Well, OK, sometimes it works, too :-)

What I did so far is: loop over a certain amount of tries, each time fork and excute the program in the child while the parent process waits for a maximum amount of time, eventually killing the child. Speaking in code:

my $prg = "./runaway.pl"; # program that hangs, dies or exits 0 my $timeout = 4; # seconds to wait my $tries = 4; # number of tries my $run_ok = 0; # just another flag for my $try (0..$tries) { print "\n\n-----------------#$try\n"; if (run()) { print "--- run OK\n"; $run_ok = 1; last; } } unless ($run_ok) { die "---Ieerg!\n"; } #################### sub run { my $return_code = undef; my $pid = fork(); unless (defined $pid) { die "could not fork\n"; } if ($pid == 0) { # child print " child: exec\n"; exec("$prg arguments"); exit; } else { # parent print " parent: wait\n"; my $time = time(); my $kill_flag = 1; while (time() - $time < $timeout) { my $kid = waitpid(-1,WNOHANG); # needs a use POSIX ":sys_wait_h" if ($kid == -1) { $kill_flag = 0; $return_code = 1; last; } sleep 1; } kill(9, $pid) if $kill_flag; } return $return_code; }
The problem with this solution is that I don't get any information whether the program exited with an error or not. Substituting the exec for a system resulted in many processes hanging in the process table.

Can you give me any clues?

Regards... Stefan
you begin bashing the string with a +42 regexp of confusion

Replies are listed 'Best First'.
Re: YA fork() question: catching runaway and erroneous processes
by stefan k (Curate) on Jul 28, 2004 at 09:18 UTC
    Hi,
    I could help myself. At least this works with my testing programms.
    1. I need to wait for the $pid instead of -1
    2. I can check $? for the exit status
    3. I need to check the result of waitpid for >0 instead of == -1
    So now the relevant code section reades likes this:
    if ($pid == 0) { # child print " child: exec\n"; exec("$prg arguments"); exit; } else { # parent print " parent: wait\n"; my $time = time(); my $kill_flag = 1; while (time() - $time < $timeout) { sleep 1; my $kid = waitpid($pid,WNOHANG); my $exit_value = $? >> 8; if ($kid > 0) { $kill_flag = 0; $return_code = !$exit_value; last; } } if($kill_flag) { kill(9, $pid); $return_code = 0; } } return $return_code;
    Thanks for reading anyway :-)

    Regards... Stefan
    you begin bashing the string with a +42 regexp of confusion

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://377945]
Approved by Wampa
Front-paged by broquaint
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (5)
As of 2024-03-28 19:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found