Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Behavior of Open Pipes with Kill

by tedv (Pilgrim)
on Dec 19, 2000 at 03:41 UTC ( [id://47289]=perlquestion: print w/replies, xml ) Need Help??

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

I recently fixed an extremely odd bug in one of my perl scripts. Here's the general context. I loop through a number of files (lets say 10 of them) in serial. For each file, I spawn off a system process that runs on a simulation on that file. The behaviour of the simulator makes it so that sometimes the simulator will deadlock and the simulator's parent needs to kill the process. So I used $SIG{ALRM} to trap this. If I haven't received output after 5 seconds, I kill the process (actually the entire group of processes it might have spawned), close the filehandle, and process the next file in the list.

Here's the odd part. If I ever manually kill the file through the sig alarm handler, then the next time I execute the open pipe, perl seg-faults. The only way (that I've found) to fix this problem is to read either $! or $? after the close(). When the script reads one of these variables, the script no longer seg-faults.

Here is the output of perl -v:
This is perl, version 5.005_03 built for i386-linux Copyright 1987-1999, Larry Wall Perl may be copied only under the terms of either the Artistic License + or the GNU General Public License, which may be found in the Perl 5.0 source +kit. Complete documentation for Perl, including FAQ lists, should be found +on this system using `man perl' or `perldoc perl'. If you have access to + the Internet, point your browser at http://www.perl.com/, the Perl Home Pa +ge.

And here is the subroutine that's causing these problems:
sub anysim_tests { my ($flag, $class, $tests) = @_; my $program = $flag . "sim"; my $progname = uc($flag) . "sim"; return 1 unless flag_present($tests, $flag); print "\n\n*** ", uc($program), " TESTING ***\n\n"; # Autoflush sim output local $| = 1; foreach my $file (sort keys %$tests) { # Check if this file didn't need xsim testing next if index($tests->{$file}[0], $flag) < 0; # Compute actual file names my $output = $file; $output =~ s/vo$/${program}.mem/g or next; # Should never fail delete_mem($output) or next; # Delete old memory image use vars qw($abort $pid $sim); local $sim = new FileHandle; local $pid = open($sim, "exec /usr/local/java/bin/java $class $file 2>&1 +|"); unless (defined($pid)) { print "Warning: Could not run 'java $class $file': $!\n\n" +; next; } print "\n$progname testing $file\n"; local $abort = 0; local $SIG{ALRM} = sub { alarm(0); print "\nWarning: $progname deadlocked on $file\n"; kill "TERM", $pid; # This close will probably fail close($sim); # We need to read $! or $?, or else the next open pipe +will # seg fault perl my $garbage = $!; $abort = -1; }; my $found_data = 0; do { alarm(5); $_ = <$sim>; if (defined $_) { ++$found_data; print "#" if ($found_data % 500) == 0; } else { $abort = 1 unless $abort; } } while (!$abort); print $/; alarm(0); if ($abort > 0 && !close($sim)) { print "Warning: $progname could not successfully run $file +\n"; next; } else { my $source = $progname . ".vout"; system "mv $source $output" if is_readable($source); } } }


-Ted

Replies are listed 'Best First'.
Re: Behavior of Open Pipes with Kill
by merlyn (Sage) on Dec 19, 2000 at 03:56 UTC
    You're probably doing wayyy too much in a signal handler. You're probably tripping over some half-created hash element or something. Remember, Perl signals are not reliable, and will break. For good alarm handling, look at Event or POE or something else. Not straight Perl.

    -- Randal L. Schwartz, Perl hacker

Problem Solved
by tedv (Pilgrim) on Dec 19, 2000 at 04:39 UTC
    Okay, Per merlyn's suggestion I rewrote the code so that it doesn't use SIG{ALRM}. Instead it just uses a standard select call (as opposed to two system calls inside of a signal handler) and the code works much smoother. It's also shorter so that's a good sign too. Thanks for the help.

    -Ted
Re: Behavior of Open Pipes with Kill
by agoth (Chaplain) on Dec 19, 2000 at 14:02 UTC
    Also using perl -V (BIG V) gives more info than little v, in case you werent aware....
Re: Behavior of Open Pipes with Kill
by tedv (Pilgrim) on Dec 19, 2000 at 03:44 UTC
    And before you ask, yes, I'm using -w and use strict;.

    -Ted

Log In?
Username:
Password:

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

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

    No recent polls found