Hi I started to fix some of the issues of Proc::ProcessTable, Jonathan
Swartz created a repo on github for it:
https://github.com/jonswar/perl-proc-processtable
While wading through this bug report, I discovered that you call the sub
"get_process_table()" inside itself, thus creating a recursive call. Is
this intentional?
Given @{$ptable} is indeed < 2 in
while (scalar(@{$ptable}) < 2 && $i < 3) {
, you would call "get_process_table()" infinitely till the whole thing
blows up.
Cheers,
Joachim
Am Mo 26. Apr 2010, 05:31:46,
http://lj.rossia.org/~nit/ schrieb:
Show quoted text>
> > Sure I'm interested in the code. I can't understand
> > your message without it, primarily because
> > I've worked in a project which communicates
> > via sockets and had massive use of Proc::ProcessTable
> > under Linux and AIX.
> >
> > Jens
>
> Here's the code (excerpts from the daemon):
>
> package psProcess;
> sub pid { my ($self) = @_; return $self->{'pid'}; }
> sub ppid { my ($self) = @_; return $self->{'ppid'}; }
> sub pgrp { my ($self) = @_; return $self->{'pgid'}; }
> sub pgid { my ($self) = @_; return $self->{'pgid'}; }
> sub cmndline { my ($self) = @_; return $self->{'cmd'}; }
>
> package main;
> sub get_process_table {
> my $ptable;
>
> # Proc::ProcessTable has some leaks on linux
> # which leads to process dying
> if ($^O eq 'linux') {
> $ptable = [];
>
> my $i = 0;
>
> my $dummy;
> my $open_res;
> while (!($open_res = opendir($dummy, "/proc")) && $i < 3) {
> sleep 1;
> $i++;
> }
> if (!$open_res) {
> psSnake::die("unable to read /proc");
> }
>
> my @all_entries;
> $i = 0;
> while (scalar(@all_entries) < 3 && $i < 3) {
> @all_entries = readdir($dummy);
> sleep 1 if $i > 0;
> $i++;
> }
> close($dummy);
>
> # . + .. eq 2
> if (scalar(@all_entries) < 3) {
> psSnake::die("/proc is not mounted");
> }
>
> my $read_may_fail = sub {
> my ($filename) = @_;
> my $filecontent;
> if (open F, $filename) {
> { local $/ = undef; $filecontent = <F>; }
> close F;
> }
> return $filecontent;
> };
>
> foreach my $e (sort @all_entries) {
> my $pid_dir = "/proc/$e";
>
> next if $e eq '.' || $e eq '..';
> next if $e !~ /^\d+$/o;
> next if ! -d $pid_dir;
>
> my $cmd = $read_may_fail->("$pid_dir/cmdline");
> $cmd =~ s/\0/ /goi if $cmd;
>
> my $stat = $read_may_fail->("$pid_dir/stat");
> next unless $stat;
>
> my @stat_arr = split(" ", $stat);
> next if ! scalar(@stat_arr) > 5;
>
> if (!$cmd) {
> $cmd = $stat_arr[1];
>
> if ($cmd) {
> $cmd =~ s/[\(\)]//goi;
> $cmd = "[" . $cmd . "]";
> }
> }
>
> my $ppid = $stat_arr[3];
> my $pgid = $stat_arr[4];
>
> next if ! $cmd;
> next if ! $ppid =~ /^\d+$/o;
> next if ! $pgid =~ /^\d+$/o;
>
> my $p = {
> 'pid' => $e,
> 'ppid' => $ppid,
> 'pgid' => $pgid,
> 'cmd' => $cmd,
> };
>
> bless ($p, 'psProcess');
> push (@{$ptable}, $p);
> }
>
> return $ptable;
> }
> else {
> my $r = code_may_fail(sub {return Proc::ProcessTable->new()-
>table},
> {'tries' => 3});
>
> if (!$r->{'result'}) {
> psSnake::die("unable to get process table: " . $r->{'warn'});
> }
>
> $ptable = $r->{'result'};
> }
>
> my $i = 0;
> while (scalar(@{$ptable}) < 2 && $i < 3) {
> $i++;
> sleep 1;
> $ptable = get_process_table();
> }
>
> if (scalar(@{$ptable}) < 2) {
> psSnake::die("unable to read process table");
> }
>
> return $ptable;
> }