[comp.lang.perl] Memory fault

andyd@pogo.WV.TEK.COM (Andy Davidson) (07/13/90)

I don't understand what I am doing wrong with the following program, but it
gets a memory fault (almost always SIGSEGV, occasionally SIGBUS) sometimes,
usually with longer input files.  Changing the program --- adding print
statements or removing some pieces --- generally causes the point at which it
fails to move.  Removing all the print statements helps to make it run, but
isn't foolproof.  Pretty clearly something is getting stomped on. Can
somebody see an obvious goof?

            andy

Andy Davidson    Toolsmith-in-residence    Tektronix  	(503) 685-3033
Internet: andyd@pogo.WV.tek.com     uucp: ...!tektronix!pogo!andyd

--------------------------------------------------
#!/usr/bin/perl

# read the output from sa -u and build associative arrays.  Each input line
# has the form
#        uid   cputime "cpu"  memoryused "mem"  iocalls "io"   command
# e.g.,
#       1026   2.00     cpu       40k     mem      2     io    findx
# and we should end up with the following arrays:
#       %user       total cpu time for user with name $name
#       %command    total cpu time for command $cmd
#       %usercmd    total cpu time for user-command combination $name.$cmd

$SIG{'INT'} = 'quitnow';
$SIG{'ILL'} = 'quitnow';
$SIG{'BUS'} = 'quitnow';
$SIG{'SEGV'} = 'quitnow';
$SIG{'TERM'} = 'quitnow';

$nrecord = 0;
while(<>) {
    chop;
    $nrecord = $nrecord + 1;
    print "$nrecord: $_\n";
    ($uid,$cpu,$junk1,$mem,$junk2,$io,$junk3,$cmd) = split;
# remove any '*' from the command, so that foo and foo* aren't treated
# differently.  (I think the '*' indicates one of the accounting flags
# was set on this command execution.)
    $cmd =~ s/\*//;
    
# if we haven't already done so for this uid, get the username that goes
# with it.  In either case, set $name to that username.
    if (defined $username{$uid}) {
        $name = $username{$uid};
    }
    else {
        ($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell) =
            getpwuid($uid);
        $username{$uid} = $name;
    }

    print "    $uid $name $cpu\t";
    if (defined $user{$name}) {
    }
    else {
        $users = $users + 1;
    }
    if (defined $command{$cmd}) {
    }
    else {
        $commands = $commands + 1;
    }
    
    $uc = $name . "." . $cmd;
    print " $uc\n";
    if (defined $usercmd{$uc}) {
    }
    else {
        $usercommands = $usercommands + 1;
    }
    $user{$name} = $user{$name} + $cpu;
    print " $user{$name}\n";
    $command{$cmd} = $command{$cmd} + $cpu;
    $usercmd{$uc} = $usercmd{$uc} + $cpu;
}
print "Done.\n";
exit 0;

sub quitnow {
    local($sig) = @_;
    print STDERR "Error exit: SIG$sig\n";
    print STDERR "Nrecord = $nrecord\n";
    print STDERR "record = <$_>\n";
    print STDERR "usercmd count=$usercommands\n";
    print STDERR "uc=$uc\n";
    exit 1;
}

-- 
Andy Davidson    Toolsmith-in-residence    Tektronix  	(503) 685-3033
Internet: andyd@pogo.WV.tek.com     uucp: ...!tektronix!pogo!andyd