Skip Menu |

This queue is for tickets about the Proc-Simple CPAN distribution.

Report information
The Basics
Id: 63833
Status: resolved
Priority: 0/
Queue: Proc-Simple

People
Owner: Nobody in particular
Requestors: perlbotics [...] yahoo.de
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 1.26
Fixed in: (no value)



Subject: exit_status() can fail to return valid exit state after sufficently long runtime.
Problem: A main process that runs sufficiently long might get an 'undef' or -1 form exit_status() instead of the real execution status. Problem reproduced using the attached program under: Solaris 10 / Proc::Simple 1.26 / Perl 5.12.2 / x86-arch SuSE 11.2 / Proc::Simple 1.26 / Perl 5.10.0 AFAIK, all versions of Proc::Simple are affected. Analysis: If a Proc::Simple variable/object is DESTROYed while the associated Proc::Simple-process has already terminated, the PID is unnecessarily remembered in %DESTROYED for later reaping. If another process re-uses the PID (e.g. after the OS' PID wrap-around) the process is reaped by sub THE_REAPER and the execution state is lost since the %DESTROYED hash is checked before the %EXIT_STATUS hash there. Suggested fix: Do not remember the PID of an already terminated process for later reaping - that will try to reap another process that re-used the same PID. It might not even be the PID of a process under control of Proc::Simple. Additionally, it slows down THE_REAPER since it finally has to check 32k PIDs. Suggested patch: In sub DESTROY, change: $DESTROYED{ $self->pid } = 1; to: $DESTROYED{ $self->pid } = 1 if $self->poll(); Applying the patch above fixed the problem (at least for me). Another observation: The associated $INTERVAL{...} could be deleted when process was reaped by checking the PIDs from %DESTROYED or when DESTROY was called for an already terminated process. Thanks for this otherwise very useful module.
Subject: proc-simple-bug.pl
use strict; use warnings; use Proc::Simple; # checked with V1.26 my ($count, $problems) = (0, 0); ## uncomment to see effect immediately # $Proc::Simple::DESTROYED{$_} = 1 for (1..33000); for (1..33) { # assumes 32k PID-range warn "Run $_\n"; run_and_poll() for (1..1000); } warn "Finis: ITERATIONS=$count PROBLEMS=$problems RUNTIME=", time() - $^T, "\n"; # Linux: # Finis: ITERATIONS=33000 PROBLEMS=42 RUNTIME=338 (using: wait() --> -1) # Finis: ITERATIONS=33000 PROBLEMS=1549 RUNTIME=1803 (using: poll() --> undef) # Finis: ITERATIONS=33000 PROBLEMS=0 RUNTIME=222 (using: wait() and patch applied) exit; sub run_and_poll { $count++; my $ex = int rand 50; my $ps = Proc::Simple->new(); $ps->start( qq{/bin/sh -c "exit $ex"} ); my $pid = $ps->pid(); # select(undef, undef, undef, 0.1) while $ps->poll(); # poll()ing --> undef $ps->wait(); # wait()ing --> -1 (Linux) my $ex_state = $ps->exit_status(); # DESTROY now remembers the PID of an already terminated process return $pid if defined $ex_state and $ex_state == $ex * 256; warn "Problem: PID=$pid EXIT-STATUS=(", (defined $ex_state ? "$ex_state but $ex expected" : "undefined"), ") ITERATION=$count Err=$!\n", " KEYS in \%DESTROYED: ", scalar keys %Proc::Simple::DESTROYED, "\n"; $problems++; # DESTROY now remembers the PID of an already terminated process return $pid; }
From: retnyg [...] gmx.net
On Sat Dec 11 12:29:37 2010, Perlbotics wrote: Show quoted text
> Suggested patch: > In sub DESTROY, change: > $DESTROYED{ $self->pid } = 1; > to: > $DESTROYED{ $self->pid } = 1 if $self->poll(); > > Applying the patch above fixed the problem (at least for me).
this problems exists still in 1.27. thanks for sharing the patch, works great now. @perlmeister: pls apply this fix, kthxbye
Thanks for the patch, I'm really sorry that it took so long to apply. I've added your patch here: https://github.com/mschilli/proc-simple-perl/tree/ab4239d842186d3eb3837e44dfc462790d927db0 and regarding your suggestions with %INTERVALS, I've added a cleanup() method long-running processes can use: https://github.com/mschilli/proc-simple-perl/commit/bc641f43c1377f6645807e7c77dde6383643259b Hope this works for you, let me know if not! Proc::Simple 1.28 should be hitting CPAN any minute now. -- Mike