Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked

Behavior of Open Pipes with Kill

by tedv (Pilgrim)
on Dec 19, 2000 at 03:41 UTC ( #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, 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); } } }


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.

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;.


Log In?

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

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (10)
As of 2016-10-27 13:17 GMT
Find Nodes?
    Voting Booth?
    How many different varieties (color, size, etc) of socks do you have in your sock drawer?

    Results (362 votes). Check out past polls.