2003-01-19 21:07:38 +03:00
|
|
|
#!/bin/sh
|
|
|
|
#
|
|
|
|
# Program: RunSafely.sh
|
|
|
|
#
|
|
|
|
# Synopsis: This script simply runs another program. 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.
|
|
|
|
#
|
2003-05-11 21:34:14 +04:00
|
|
|
# This script funnels stdout and stderr from the program into the
|
2006-11-25 11:56:10 +03:00
|
|
|
# fourth argument specified, and outputs a <outfile>.time file which
|
|
|
|
# contains a timing of the program and the program's exit code.
|
|
|
|
#
|
2007-05-04 01:32:39 +04:00
|
|
|
# If the <exitok> parameter is 0 then this script always returns 0,
|
|
|
|
# regardless of the actual exit of the <program>.
|
2006-11-25 11:56:10 +03:00
|
|
|
# If the <exitok> parameter is non-zero then this script returns
|
|
|
|
# the exit code of the <program>. If there is an error in getting
|
|
|
|
# the <program>'s exit code, this script returns 99.
|
2003-01-19 21:07:38 +03:00
|
|
|
#
|
2007-05-04 01:32:39 +04:00
|
|
|
# If optional parameters -r <remote host> -l <remote user> are
|
|
|
|
# specified, it execute the program remotely using rsh.
|
|
|
|
#
|
2006-11-25 11:56:10 +03:00
|
|
|
# Syntax:
|
|
|
|
#
|
2008-09-09 10:12:33 +04:00
|
|
|
# RunSafely.sh [-r <rhost>] [-l <ruser>] [-rc <client>] [-ro <roptions>]
|
2007-05-04 01:32:39 +04:00
|
|
|
# <timeout> <exitok> <infile> <outfile> <program> <args...>
|
2006-11-25 11:56:10 +03:00
|
|
|
#
|
|
|
|
# where:
|
2007-05-04 01:32:39 +04:00
|
|
|
# <rhost> is the remote host to execute the program
|
|
|
|
# <ruser> is the username on the remote host
|
2008-09-09 10:12:33 +04:00
|
|
|
# <client> is the remote client used to execute the program
|
|
|
|
# <roptions>is the extra options passed to the remote client
|
2006-11-25 11:56:10 +03:00
|
|
|
# <timeout> is the maximum number of seconds to let the <program> run
|
|
|
|
# <exitok> is 1 if the program must exit with 0 return code
|
|
|
|
# <infile> is a file from which standard input is directed
|
|
|
|
# <outfile> is a file to which standard output and error are directed
|
|
|
|
# <program> is the path to the program to run
|
|
|
|
# <args...> are the arguments to pass to the program.
|
2003-05-11 21:34:14 +04:00
|
|
|
#
|
2006-06-07 22:57:36 +04:00
|
|
|
if [ $# -lt 4 ]; then
|
2006-11-25 11:56:10 +03:00
|
|
|
echo "./RunSafely.sh <timeout> <exitok> <infile> <outfile> <program> <args...>"
|
|
|
|
exit 1
|
2006-06-07 22:57:36 +04:00
|
|
|
fi
|
|
|
|
|
|
|
|
DIR=${0%%`basename $0`}
|
2007-05-04 01:32:39 +04:00
|
|
|
|
|
|
|
RHOST=
|
|
|
|
RUSER=`id -un`
|
2008-09-09 10:12:33 +04:00
|
|
|
RCLIENT=rsh
|
|
|
|
ROPTIONS=""
|
2007-05-04 01:32:39 +04:00
|
|
|
if [ $1 = "-r" ]; then
|
|
|
|
RHOST=$2
|
|
|
|
shift 2
|
|
|
|
fi
|
|
|
|
if [ $1 = "-l" ]; then
|
|
|
|
RUSER=$2
|
|
|
|
shift 2
|
|
|
|
fi
|
2008-09-09 10:12:33 +04:00
|
|
|
if [ $1 = "-rc" ]; then
|
|
|
|
RCLIENT=$2
|
|
|
|
shift 2
|
|
|
|
fi
|
|
|
|
if [ $1 = "-ro" ]; then
|
|
|
|
ROPTIONS=$2
|
|
|
|
shift 2
|
|
|
|
fi
|
2007-05-04 01:32:39 +04:00
|
|
|
|
2003-05-18 02:32:43 +04:00
|
|
|
ULIMIT=$1
|
2006-11-25 11:56:10 +03:00
|
|
|
EXITOK=$2
|
|
|
|
INFILE=$3
|
|
|
|
OUTFILE=$4
|
|
|
|
PROGRAM=$5
|
|
|
|
shift 5
|
2004-12-30 06:10:38 +03:00
|
|
|
SYSTEM=`uname -s`
|
2003-01-19 21:07:38 +03:00
|
|
|
|
2007-05-05 01:24:42 +04:00
|
|
|
ULIMITCMD=""
|
2004-12-30 06:10:38 +03:00
|
|
|
case $SYSTEM in
|
|
|
|
CYGWIN*)
|
|
|
|
;;
|
2005-08-03 02:04:00 +04:00
|
|
|
Darwin*)
|
2008-04-30 00:45:32 +04:00
|
|
|
# Disable core file emission, the script doesn't find it anyway because it
|
|
|
|
# is put into /cores.
|
2007-05-05 01:24:42 +04:00
|
|
|
ULIMITCMD="$ULIMITCMD ulimit -c 0;"
|
|
|
|
ULIMITCMD="$ULIMITCMD ulimit -t $ULIMIT;"
|
2008-04-30 00:45:32 +04:00
|
|
|
# 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. ;)
|
2007-05-05 01:24:42 +04:00
|
|
|
ULIMITCMD="$ULIMITCMD ulimit -f 10485760;"
|
2005-08-03 02:04:00 +04:00
|
|
|
;;
|
2004-12-30 06:10:38 +03:00
|
|
|
*)
|
2007-05-05 01:24:42 +04:00
|
|
|
ULIMITCMD="$ULIMITCMD ulimit -t $ULIMIT;"
|
|
|
|
ULIMITCMD="$ULIMITCMD ulimit -c unlimited;"
|
2008-04-30 00:45:32 +04:00
|
|
|
# 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. ;)
|
2007-05-05 01:24:42 +04:00
|
|
|
ULIMITCMD="$ULIMITCMD ulimit -f 10485760;"
|
2008-02-15 02:46:20 +03:00
|
|
|
|
2008-07-21 11:10:53 +04:00
|
|
|
# virtual memory: 250 MB should be enough for anybody. ;)
|
|
|
|
ULIMITCMD="$ULIMITCMD ulimit -v 250000;"
|
2004-12-30 06:10:38 +03:00
|
|
|
esac
|
2003-05-11 21:34:14 +04:00
|
|
|
rm -f core core.*
|
2003-07-03 00:42:05 +04:00
|
|
|
|
|
|
|
#
|
|
|
|
# Run the command, timing its execution.
|
|
|
|
# The standard output and standard error of $PROGRAM should go in $OUTFILE,
|
2006-11-25 11:56:10 +03:00
|
|
|
# and the standard error of time should go in $OUTFILE.time. Note that the
|
|
|
|
# return code of the program is appended to the $OUTFILE on an "Exit Val ="
|
|
|
|
# line.
|
2003-07-03 00:42:05 +04:00
|
|
|
#
|
|
|
|
# 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.
|
|
|
|
#
|
2007-05-04 01:32:39 +04:00
|
|
|
PWD=`pwd`
|
2008-03-04 17:38:01 +03:00
|
|
|
COMMAND="$PROGRAM $*"
|
2007-01-10 20:51:45 +03:00
|
|
|
if [ "$SYSTEM" = "Darwin" ]; then
|
2007-05-04 01:32:39 +04:00
|
|
|
COMMAND="${DIR}TimedExec.sh $ULIMIT $PWD $COMMAND"
|
2006-11-25 11:56:10 +03:00
|
|
|
fi
|
|
|
|
|
2007-05-04 01:32:39 +04:00
|
|
|
if [ "x$RHOST" = x ] ; then
|
2008-05-21 14:47:32 +04:00
|
|
|
( sh -c "$ULIMITCMD time -p sh -c '$COMMAND >$OUTFILE 2>&1 < $INFILE; echo exit \$?'" ) 2>&1 \
|
2007-05-04 01:32:39 +04:00
|
|
|
| awk -- '\
|
|
|
|
BEGIN { cpu = 0.0; }
|
|
|
|
/^user/ { cpu += $2; print; }
|
|
|
|
/^sys/ { cpu += $2; print; }
|
|
|
|
!/^user/ && !/^sys/ { print; }
|
|
|
|
END { printf("program %f\n", cpu); }' > $OUTFILE.time
|
|
|
|
else
|
2008-03-04 17:38:01 +03:00
|
|
|
rm -f "$PWD/${PROGRAM}.command"
|
|
|
|
rm -f "$PWD/${PROGRAM}.remote"
|
|
|
|
rm -f "$PWD/${PROGRAM}.remote.time"
|
|
|
|
echo "$ULIMITCMD cd $PWD; (time -p ($COMMAND > $OUTFILE.remote 2>&1 < $INFILE;); echo exit $?) > $OUTFILE.remote.time 2>&1" > "$PWD/${PROGRAM}.command"
|
|
|
|
chmod +x "$PWD/${PROGRAM}.command"
|
|
|
|
|
2008-09-09 10:12:33 +04:00
|
|
|
( $RCLIENT -l $RUSER $RHOST $ROPTIONS "ls $PWD/${PROGRAM}.command" ) > /dev/null 2>&1
|
|
|
|
( $RCLIENT -l $RUSER $RHOST $ROPTIONS "$PWD/${PROGRAM}.command" )
|
2008-02-29 21:01:13 +03:00
|
|
|
cat $OUTFILE.remote.time | awk -- '\
|
2006-06-08 00:11:31 +04:00
|
|
|
BEGIN { cpu = 0.0; }
|
2006-11-25 11:56:10 +03:00
|
|
|
/^user/ { cpu += $2; print; }
|
|
|
|
/^sys/ { cpu += $2; print; }
|
|
|
|
!/^user/ && !/^sys/ { print; }
|
2006-06-08 00:11:31 +04:00
|
|
|
END { printf("program %f\n", cpu); }' > $OUTFILE.time
|
2008-02-29 21:01:13 +03:00
|
|
|
sleep 1
|
|
|
|
cp -f $OUTFILE.remote $OUTFILE
|
2007-05-04 01:32:39 +04:00
|
|
|
rm -f $OUTFILE.remote
|
2008-02-29 21:01:13 +03:00
|
|
|
rm -f $OUTFILE.remote.time
|
2007-05-04 01:32:39 +04:00
|
|
|
fi
|
2003-07-03 00:42:05 +04:00
|
|
|
|
2006-11-28 10:16:45 +03:00
|
|
|
exitval=`grep '^exit ' $OUTFILE.time | sed -e 's/^exit //'`
|
|
|
|
if [ -z "$exitval" ] ; then
|
|
|
|
exitval=99
|
|
|
|
echo "TEST $PROGRAM FAILED: CAN'T GET EXIT CODE!"
|
|
|
|
fi
|
|
|
|
echo "exit $exitval" >> $OUTFILE
|
|
|
|
|
2006-11-25 11:56:10 +03:00
|
|
|
if [ "$EXITOK" -ne 0 ] ; then
|
2006-11-28 10:16:45 +03:00
|
|
|
if test "$exitval" -ne 0 ; then
|
|
|
|
echo "TEST $PROGRAM FAILED: EXIT != 0"
|
2006-11-25 11:56:10 +03:00
|
|
|
fi
|
|
|
|
else
|
|
|
|
exitval=0
|
2003-07-01 22:04:43 +04:00
|
|
|
fi
|
|
|
|
|
2003-01-19 21:07:38 +03:00
|
|
|
if ls | egrep "^core" > /dev/null
|
|
|
|
then
|
2004-11-06 21:07:06 +03:00
|
|
|
# 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
|
|
|
|
|
2004-05-29 23:53:36 +04:00
|
|
|
corefile=`ls core* | head -n 1`
|
2005-07-28 21:02:07 +04:00
|
|
|
echo "where 100" > StackTrace.$$
|
2003-07-03 21:50:57 +04:00
|
|
|
$GDB -q -batch --command=StackTrace.$$ --core=$corefile $PROGRAM < /dev/null
|
2003-01-19 21:07:38 +03:00
|
|
|
rm -f StackTrace.$$ $corefile
|
|
|
|
fi
|
2006-11-25 11:56:10 +03:00
|
|
|
exit "$exitval"
|