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