mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-22 04:43:53 +00:00
Estimated hours taken: 1 <overview or general description of changes> <directory>/<file>: <detailed description of changes>
328 lines
7.0 KiB
Bash
Executable File
328 lines
7.0 KiB
Bash
Executable File
#!/bin/sh
|
|
# This script find miscompiled procedures.
|
|
#
|
|
# Given a stage2 directory that works (stage2.ok) and one that doesn't
|
|
# (stage2.bad), this script uses binary search to try to find in stage2.bad
|
|
# first the C source file and then the module within that C source file that
|
|
# when put together with everthing else from the stage2.ok directory, still
|
|
# causes the compiler to fail.
|
|
#
|
|
# If the bad C source file has different numbers of modules in the bad and ok
|
|
# versions, then the script stops after identifying only the file.
|
|
#
|
|
# The test for the composite stage2 compiler is either bootstrap checking
|
|
# (the default, or the successful execution of the all the test cases in
|
|
# one or more dubdirectories of the tests directory.
|
|
|
|
usage="\
|
|
Usage: $0 [options]
|
|
Options:
|
|
-b, --no-bootcheck
|
|
Do not perform a bootcheck; check only the tests directory.
|
|
-c, --compile-only
|
|
Compile only. Do not compare stage2.ok and stage3.
|
|
-h, --help
|
|
Display this usage message.
|
|
-j <num-jobs>, --jobs <num-jobs>
|
|
Run using <num-jobs> different parallel processes.
|
|
-m <mmake-args>, --mmake-args <mmake-args>
|
|
Pass <mmake-args> as options to \`mmake'.
|
|
-o <filename>, --output-file <filename>
|
|
Output results to <filename>.
|
|
-r, --copy-runtime
|
|
Copy the runtime directory instead of linking it.
|
|
-t <testdir>, --test-dir <testdir>
|
|
Execute runtests from the named subdirectory of tests.
|
|
"
|
|
|
|
bootcheck=""
|
|
compile_only=""
|
|
jfactor=
|
|
mmake_opts=""
|
|
outfile=""
|
|
copy_runtime=false
|
|
testdirs=""
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
|
|
-b|--no-bootcheck)
|
|
bootcheck="-b"; shift ;;
|
|
|
|
-c|--compile-only)
|
|
compile_only="-c"; shift ;;
|
|
|
|
-h|--help)
|
|
echo "$usage"
|
|
exit 0 ;;
|
|
|
|
-j|--jobs)
|
|
jfactor="-j$2"; shift ;;
|
|
-j*)
|
|
jfactor="-j` expr $1 : '-j\(.*\)' `" ;;
|
|
--jobs*)
|
|
jfactor="--jobs` expr $1 : '--jobs\(.*\)' `" ;;
|
|
|
|
-m|--mmake)
|
|
mmake_opts="$mmake_opts $2"; shift ;;
|
|
|
|
-o|--output-file)
|
|
outfile="-o $2"; shift ;;
|
|
-o*)
|
|
outfile="-o ` expr $1 : '-o\(.*\)' `"; ;;
|
|
|
|
-r|--copy-runtime)
|
|
copy_runtime=true ;;
|
|
|
|
-t|--test-dir)
|
|
testdirs="$testdirs -t$2"; shift ;;
|
|
-t*)
|
|
testdirs="$testdirs ` expr $1 : '-t\(.*\)' `"; ;;
|
|
|
|
--)
|
|
shift; break ;;
|
|
-*)
|
|
echo "$0: unknown option \`$1'" 1>&2
|
|
echo "$usage" 1>&2
|
|
exit 1 ;;
|
|
*)
|
|
break ;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
root=`/bin/pwd`
|
|
PATH=$root/tools:$PATH
|
|
export PATH
|
|
|
|
if test -d stage2.ok -a -d stage2.bad
|
|
then
|
|
echo "stage2.ok and stage2.bad both present"
|
|
else
|
|
echo "at least one of stage2.ok and stage2.bad is missing"
|
|
exit 1
|
|
fi
|
|
|
|
echo "starting at `date`"
|
|
|
|
[ -d stage2 ] || mkdir stage2
|
|
/bin/rm -fr stage2/*
|
|
cd stage2
|
|
mkdir compiler
|
|
cd compiler
|
|
ln -s ../../compiler/*.m .
|
|
ln -s ../../compiler/Mmake* .
|
|
cd ..
|
|
mkdir library
|
|
cd library
|
|
ln -s ../../library/*.m .
|
|
ln -s ../../library/*.nl .
|
|
ln -s ../../library/Mmake* .
|
|
ln -s ../../library/library.init .
|
|
cd ..
|
|
if test "$copy_runtime" = "true"
|
|
then
|
|
mkdir runtime
|
|
cd runtime
|
|
ln -s ../../runtime/*.h .
|
|
ln -s ../../runtime/*.c .
|
|
ln -s ../../runtime/*.mod .
|
|
ln -s ../../runtime/*.in .
|
|
ln -s ../../runtime/Mmake* .
|
|
ln -s ../../runtime/machdeps .
|
|
cd ..
|
|
else
|
|
ln -s ../runtime .
|
|
fi
|
|
ln -s ../boehm_gc .
|
|
ln -s ../doc .
|
|
ln -s ../scripts .
|
|
ln -s ../util .
|
|
ln -s ../profiler .
|
|
ln -s ../conf* .
|
|
rm -f config*.log
|
|
cp ../stage2.ok/Mmake* .
|
|
cd ..
|
|
|
|
# We don't copy the .d files. This prevents mmake from trying to remake any
|
|
# of the .c and .o files, which we provide in the form they should be used.
|
|
|
|
# cp stage2.ok/library/*.d stage2/library
|
|
cp stage2.ok/library/*.dep stage2/library
|
|
cp stage2.ok/library/*.int stage2/library
|
|
cp stage2.ok/library/*.int2 stage2/library
|
|
cp stage2.ok/library/*.date stage2/library
|
|
# cp stage2.ok/compiler/*.d stage2/compiler
|
|
cp stage2.ok/compiler/*.dep stage2/compiler
|
|
cp stage2.ok/compiler/*.int stage2/compiler
|
|
cp stage2.ok/compiler/*.int2 stage2/compiler
|
|
cp stage2.ok/compiler/*.date stage2/compiler
|
|
|
|
echo testing whether the stage2.bad library works
|
|
|
|
cp stage2.bad/library/*.[co] stage2/library
|
|
cp stage2.ok/compiler/*.[co] stage2/compiler
|
|
|
|
set -x
|
|
|
|
if binary_step $compile_only $jfactor -m "$mmake_opts" $outfile $bootcheck $testdirs
|
|
then
|
|
problemdir=compiler
|
|
else
|
|
problemdir=library
|
|
fi
|
|
|
|
echo "problem seems to be in the $problemdir directory"
|
|
|
|
# start out with all files in stage2 coming from stage2.ok
|
|
|
|
cp stage2.ok/library/*.[co] stage2/library
|
|
|
|
# find the set of candidate modules
|
|
|
|
cd stage2/$problemdir
|
|
allfiles=`sub X.c X *.c`
|
|
cd ../..
|
|
|
|
doubtful="$allfiles"
|
|
tested=`half $doubtful`
|
|
knowngood=
|
|
|
|
while test "$tested" != ""
|
|
do
|
|
# at this point, all the files in stage2 should be from stage2.ok
|
|
|
|
echo "doubtful modules: $doubtful"
|
|
echo "testing modules: $tested"
|
|
|
|
for module in $tested
|
|
do
|
|
cp stage2.bad/$problemdir/$module.[co] stage2/$problemdir
|
|
done
|
|
|
|
if binary_step $compile_only $jfactor -m "$mmake_opts" $outfile $bootcheck $testdirs
|
|
then
|
|
echo "test succeeded"
|
|
knowngood="$knowngood $tested"
|
|
newdoubtful=""
|
|
for module in $doubtful
|
|
do
|
|
if not appears $module $tested
|
|
then
|
|
newdoubtful="$newdoubtful $module"
|
|
fi
|
|
done
|
|
doubtful="$newdoubtful"
|
|
lasttest=success
|
|
else
|
|
echo "test failed"
|
|
doubtful="$tested"
|
|
lasttest=failure
|
|
fi
|
|
|
|
for module in $tested
|
|
do
|
|
cp stage2.ok/$problemdir/$module.[co] stage2/$problemdir
|
|
done
|
|
|
|
tested=`half $doubtful`
|
|
if test "$tested" = "" -a "$lasttest" = success
|
|
then
|
|
tested="$doubtful"
|
|
fi
|
|
done
|
|
|
|
if test "$doubtful" = ""
|
|
then
|
|
echo "cannot find the problem; all modules seem ok"
|
|
exit 1
|
|
fi
|
|
|
|
module=`echo $doubtful | tr -d ' '`
|
|
# arg $module
|
|
|
|
echo "there is a problem in $problemdir/$module"
|
|
echo "the modules known to be ok are: $knowngood"
|
|
echo
|
|
|
|
okcnt=`egrep '^END_MODULE' stage2.ok/$problemdir/$module.c | wc -l`
|
|
badcnt=`egrep '^END_MODULE' stage2.bad/$problemdir/$module.c | wc -l`
|
|
|
|
if test $okcnt -ne $badcnt
|
|
then
|
|
okcnt=`echo $okcnt | tr -d ' '`
|
|
badcnt=`echo $badcnt | tr -d ' '`
|
|
|
|
echo "the two versions of the problem module"
|
|
echo "differ in the number of C modules they have"
|
|
echo "ok version: $okcnt vs bad version: $badcnt"
|
|
exit 1
|
|
fi
|
|
|
|
for dir in ok bad
|
|
do
|
|
cd stage2.$dir/$problemdir
|
|
divide $module.c $okcnt
|
|
cd ../..
|
|
done
|
|
|
|
doubtful=
|
|
i=0
|
|
while test $i -le $okcnt
|
|
do
|
|
doubtful="$doubtful $i"
|
|
i=`expr $i + 1`
|
|
done
|
|
|
|
tested=`half $doubtful`
|
|
knowngood=
|
|
|
|
while test "$tested" != ""
|
|
do
|
|
echo "doubtful: $doubtful"
|
|
echo "testing: $tested"
|
|
|
|
assemble $problemdir $module $okcnt $tested
|
|
cd stage2/$problemdir
|
|
/bin/rm $module.o
|
|
mmake $module.o
|
|
cd ../..
|
|
|
|
if binary_step $compile_only $jfactor -m "$mmake_opts" $outfile $bootcheck $testdirs
|
|
then
|
|
echo "test succeeded"
|
|
knowngood="$knowngood $tested"
|
|
newdoubtful=""
|
|
for part in $doubtful
|
|
do
|
|
if not appears $part $tested
|
|
then
|
|
newdoubtful="$newdoubtful $part"
|
|
fi
|
|
done
|
|
doubtful="$newdoubtful"
|
|
lasttest=success
|
|
else
|
|
echo "test failed"
|
|
doubtful="$tested"
|
|
lasttest=failure
|
|
fi
|
|
|
|
tested=`half $doubtful`
|
|
if test "$tested" = "" -a "$lasttest" = success
|
|
then
|
|
tested="$doubtful"
|
|
fi
|
|
done
|
|
|
|
echo "the parts known to be ok are: $knowngood"
|
|
echo "there is a problem in $problemdir/$module.c.part.$doubtful"
|
|
echo "the difference is:"
|
|
echo
|
|
|
|
diff -u stage2.ok/$problemdir/$module.c.part.$doubtful stage2.bad/$problemdir/$module.c.part.$doubtful
|
|
|
|
echo
|
|
echo "finishing at `date`"
|
|
exit 0
|