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

Fellow monks, I have a script similar to this one (only much bigger)
use strict; use warnings; use English; use Tk; use ... # lots more modules if (fork()) { sleep(5); } my @out = `myprog`; # produces some output print @out;

The problem is that this script does not actually execute myprog. If, however, I get rid of many of the modules (basically use less memory), then everything is fine and dandy. So, in other words, this seems to be a memory issue - perl is trying to execute another program, but there is not enought memory to run it. How can I validate that this is the case?

Also, I'm seing this on an Spark Ultra 1. The same program works fine on a Sun Blade 150. However, since myprog is still under development and growing, how can I see how much extra memory I have under that hardware when everything is working?

Replies are listed 'Best First'.
Re: quoted execution not working
by Joost (Canon) on Jul 27, 2004 at 18:39 UTC
    First off
    my @out = `myprog`; die "error running myprog: $! $?" if $?;
    Will tell you when things go wrong.

    Secondly, you're guessing that the problem is memory related. I'd recommend using top or vmstat to check the memory use while running the programs. I'd be very surprised if just useing a couple of modules will take up that much memory. If it does, you might have more luck requireing the modules after running myprog, if you can.

Re: quoted execution not working
by blue_cowdawg (Monsignor) on Jul 27, 2004 at 18:28 UTC

        perl is trying to execute another program, but there is not enought memory to run it. How can I validate that this is the case?

    Well... here's a few thoughts: first change how you are doing your forks:

    : : handwaving : my $pid=fork(); if ( $pid == 0 } { : child process goes here } elsif { $pid > 0 ) { : parent process wait(); # Wait for the child to exit } else { # WOAH! We should never get here! die "fork returned $pid"; }
    Within your child process instead of using backticks you couold do the following
    : child open(PIPE,"some_command 2>&1 |") or die $!; my @output=<PIPD>; close PIPE; print @output;
    This way if you fail to fork off the grandchild you will see a diagnostic from die.

      my $pid=fork(); if ( $pid == 0 } { : child process goes here } elsif { $pid > 0 ) { : parent process wait(); # Wait for the child to exit } else { # WOAH! We should never get here! die "fork returned $pid"; }
      There are two things wrong with that. If the fork fails, $pid is undef, but will still compare true to 0. Second, if it fails, the error is in $!, not $pid. So you actually want:
      my $pid=fork(); if (not defined $pid) { die "fork failed: $!\n"; } elsif ( $pid == 0 } { : child process goes here } else { : parent process wait(); # Wait for the child to exit }

      Dave.

            If the fork fails, $pid is undef, but will still compare true to 0. Second, if it fails, the error is in $!, not $pid.

        Good catch! You are correct. My bad. Instead of

        die "fork returned $pid";
        I should have invoked
        die $!;
        as I have in code that I have written in the past where I have done forking. Too much C-code lately the if-tree is a C-ism. As in
        pid = fork(); switch (pid){ -1: perror("Fork failed"); exit(-1); 0: /* Child */ break; default: /* parent */ break; }
        anyway, good catch.

        All all this code is off the top of my head.

Re: quoted execution not working
by Eimi Metamorphoumai (Deacon) on Jul 27, 2004 at 18:15 UTC
    Probably the easiest way is to get another terminal open at the same time and run top to track cpu and memory usage. You can see if you're running out of memory, or processes, or what.
Re: quoted execution not working
by derby (Abbot) on Jul 27, 2004 at 18:11 UTC
    The only reasonable response is here.

    -derby