blob: c1c9c64212a674c0812a2084b1ba67af438d977f [file] [log] [blame]
#!/bin/sh
#
# Program: RunSafelyAndStable.sh
#
# Synopsis: This script runs another program three times. If the program works
# correctly, this script has no effect, otherwise it will do things
# like print a stack trace of a core dump. It always returns
# "successful" so that tests will continue to be run.
#
# This script funnels stdout and stderr from the program into the
# first argument specified, and outputs a <outputfile>.time file which
# contains timing information for the fastest of the three runs of the
# program.
#
# Syntax:
# ./RunSafelyAndStable.sh <ulimit> <stdinfile> <stdoutfile> <program> <args...>
#
ULIMIT=$1
INFILE=$2
OUTFILE=$3
PROGRAM=$4
shift 4
ulimit -t $ULIMIT
rm -f core core.*
ulimit -c unlimited
# To prevent infinite loops which fill up the disk, specify a limit on size of
# files being output by the tests. 10 MB should be enough for anybody. ;)
ulimit -f 10485760
#
# Run the command, timing its execution.
# The standard output and standard error of $PROGRAM should go in $OUTFILE,
# and the standard error of time should go in $OUTFILE.time.
#
# Ah, the joys of shell programming!
# To get the time program and the specified program different output filenames,
# we tell time to launch a shell which in turn executes $PROGRAM with the
# necessary I/O redirection.
#
(time -p sh -c "$PROGRAM $* > $OUTFILE 2>&1 < $INFILE") 2>&1 | awk -- '\
BEGIN { cpu = 0.0; }
/^user/ { cpu += $2; print }
/^sys/ { cpu += $2; print }
!/^user/ && !/^sys/ { print }
END { printf("program %f\n", cpu); }' > $OUTFILE.time1
if test $? -eq 0
then
touch $OUTFILE.exitok
fi
if ls | egrep "^core" > /dev/null
then
# If we are on a sun4u machine (UltraSparc), then the code we're generating
# is 64 bit code. In that case, use gdb-64 instead of gdb.
myarch=`uname -m`
if [ "$myarch" = "sun4u" ]
then
GDB="gdb-64"
else
GDB=gdb
fi
corefile=`ls core* | head -n 1`
echo "where" > StackTrace.$$
$GDB -q -batch --command=StackTrace.$$ --core=$corefile $PROGRAM < /dev/null
rm -f StackTrace.$$ $corefile
exit 0
fi
TIME1=`grep program $OUTFILE.time1 | sed 's/^program//'`
echo "Program $PROGRAM run #1 time: $TIME1"
# Do the second and third runs now
(time -p sh -c "$PROGRAM $* > $OUTFILE 2>&1 < $INFILE") 2>&1 | awk -- '\
BEGIN { cpu = 0.0; }
/^real/ { print }
/^user/ { cpu += $2; print }
/^sys/ { cpu += $2; print }
!/^real/ && !/^user/ && !/^sys/ { print }
END { printf("program %f\n", cpu); }' > $OUTFILE.time2
TIME2=`grep program $OUTFILE.time2 | sed 's/^program//'`
echo "Program $PROGRAM run #2 time: $TIME2"
(time -p sh -c "$PROGRAM $* > $OUTFILE 2>&1 < $INFILE") 2>&1 | awk -- '\
BEGIN { cpu = 0.0; }
/^real/ { print }
/^user/ { cpu += $2; print }
/^sys/ { cpu += $2; print }
!/^real/ && !/^user/ && !/^sys/ { print }
END { printf("program %f\n", cpu); }' > $OUTFILE.time3
TIME3=`grep program $OUTFILE.time3 | sed 's/^program//'`
echo "Program $PROGRAM run #3 time: $TIME3"
# Figure out which run had the smallest run time:
SHORTEST=`echo -e "$TIME1 time1\n$TIME2 time2\n$TIME3 time3" | sort |
head -1 | sed "s|.*time||"`
echo "Program $PROGRAM run #$SHORTEST was fastest"
cp $OUTFILE.time$SHORTEST $OUTFILE.time
exit 0