#!/bin/sh # # vim: ts=4 sw=4 et # # This script finds miscompiled procedures in a module after the binary script # has identified the module. # # Given # # - a stage2 directory that works (stage2.ok), which must have # its object files, # - a stage2 directory that does not work (stage2.bad), which must have # its Mmake.params file, # - a directory name (library, compiler etc), # - the name of the bad module in that directory (list, hlds_data, etc), and # - a limit number # # this script compiles the bad module with the parameters from # stage2.bad/Mmake.params plus --experiment=N, varying N from 1 to the limit, # and finds out which values of N cause a problem. # # The test for the cobbled-up stage2 compiler is either bootstrap checking # (the default), some initial part of bootstrap checking (making dependencies, # compiling the library), the successful execution of all the test cases in # one or more subdirectories of the tests directory, or the successful # execution of a single command. usage="\ Usage: $0 [options] dirname modulename merfilename limit Options: -b-, --no-bootcheck Do not perform a bootcheck; check only the tests directory or the single command. -c, --compile-only Check the successful creation of the stage3 .c files, but do not compare stage2.ok and stage3. -C Use the given string as the command to invoke the Mercury compiler. The string may include options. -d, --dependency-only Make dependencies for stage3 only. Do not compile stage3. -h, --help Display this usage message. -j , --jobs Run using different parallel processes. -l, --library-only Check the successful creation of the stage3 .c files in the library, but do not compile the compiler directory. -m , --mmake-args Pass as options to \`mmake'. -o , --output-file Output results to . -r, --copy-runtime Copy the runtime directory instead of linking it. This is necessary if the test uses a compilation model option that differs from the one used in the main runtime directory. -s , --single-command Execute the given command using each constructed compiler. -t , --test-dir Execute runtests from the named subdirectory of tests. " # If you change this, you will also need to change the files indicated # in scripts/c2init.in. STD_LIB_NAME=mer_std set -x bootcheck="" compile_only="" mmc_command="mmc" dependency_only="" library_only="" jfactor= mmake_opts="" outfile="" copy_runtime=false single_command="" testdirs="" alldirs="" compare_to_bad="" basis="ok" while [ $# -gt 0 ]; do case "$1" in -b-|--no-bootcheck) bootcheck="-b-" ;; -c|--compile-only) compile_only="-c" ;; -C) mmc_command="$2"; shift ;; -d|--dependency-only) dependency_only="-d" ;; -h|--help) echo "$usage" exit 0 ;; -j|--jobs) jfactor="-j$2"; shift ;; -j*) jfactor="-j` expr $1 : '-j\(.*\)' `" ;; --jobs*) jfactor="--jobs` expr $1 : '--jobs\(.*\)' `" ;; -l|--library-only) library_only="-l" ;; -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 ;; -s|--single-command) single_command="$2"; shift ;; -s*) single_command=` expr "$1" : '-s\(.*\)' ` ;; --single-command*) single_command=` expr "$1" : '--single-command\(.*\)' ` ;; -t|--test-dir) testdirs="$testdirs -t$2"; shift ;; -t*) testdirs="$testdirs ` expr $1 : '-t\(.*\)' `" ;; -*) echo "$0: unknown option \`$1'" 1>&2 echo "$usage" 1>&2 exit 1 ;; *) break ;; esac shift done case "$#" in 4) tested_dir_name="$1" tested_module_name="$2" tested_file_name="$3" limit="$4" ;; *) echo "$usage" 1>&2 exit 1 ;; esac base=ok trial=bad expected=success 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 if test ! -d stage2.ok/${tested_dir_name} then echo stage2.ok/${tested_dir_name} does not exist exit 1 fi if test ! -f stage2.ok/${tested_dir_name}/${tested_file_name}.m then echo stage2.ok/${tested_dir_name}/${tested_file_name}.m does not exist exit 1 fi if test ! -f stage2.ok/${tested_dir_name}/${tested_module_name}.c then echo stage2.ok/${tested_dir_name}/${tested_module_name}.c does not exist exit 1 fi root=`/bin/pwd` trueroot=`echo $root | sed ' s:/mount/munkora/mercury:/home/mercury: s:/mount/munkora/home/mercury:/home/mercury: s:/mount/munkora/clp/mercury:/home/mercury:'` PATH=$root/tools:$PATH export PATH if test "$RMSTAGECMD" = "" then RMSTAGECMD="/bin/rm -fr" fi echo "starting at `date`" for dir in $base $trial do for subdir in library mdbcomp compiler do case $subdir in library) example_o=builtin.o ;; mdbcomp) example_o=mdbcomp.prim_data.o ;; compiler) example_o=check_hlds.cse_detection.o ;; esac if test -f stage2.$dir/$subdir/$example_o then echo "stage2.$dir/$subdir seems to have its object files" else echo "reconstructing object files in stage2.$dir/$subdir" ( cd stage2.$dir/$subdir; mmake ) fi done done echo "starting unary at `date`" set +x [ -d stage2 ] || mkdir stage2 $RMSTAGECMD $trueroot/stage2/compiler < /dev/null & $RMSTAGECMD $trueroot/stage2/library < /dev/null & wait $RMSTAGECMD $trueroot/stage2/* < /dev/null echo linking stage 2... 1>&2 cd stage2 ln -s $root/main.c . mkdir compiler cd compiler ln -s $root/compiler/[a-h]*.m . ln -s $root/compiler/[i-o]*.m . ln -s $root/compiler/[p-s]*.m . ln -s $root/compiler/[t-z]*.m . cp $root/compiler/Mmake* . cp $root/compiler/Mercury* . cp $root/compiler/*FLAGS* . cp $root/compiler/.mgnuc* . cd $root/stage2 mkdir library cd library ln -s $root/library/[a-l]*.m . ln -s $root/library/[m-z]*.m . ln -s $root/library/*.init . cp $root/library/print_extra_inits . cp $root/library/Mmake* . cp $root/library/Mercury* . cp $root/library/*FLAGS* . cp $root/library/mer_std.trans_opt_deps_spec . cp $root/library/.mgnuc* . cd $root/stage2 mkdir mdbcomp cd mdbcomp ln -s $root/mdbcomp/*.m . ln -s $root/mdbcomp/*.init . cp $root/mdbcomp/Mmake* . cp $root/mdbcomp/Mercury* . cp $root/mdbcomp/*FLAGS* . cp $root/mdbcomp/.mgnuc* . cd $root/stage2 if "$copy_runtime" then mkdir runtime cd runtime ln -s $root/runtime/*.h . ln -s $root/runtime/*.c . ln -s $root/runtime/*.in . ln -s $root/runtime/machdeps . cp $root/runtime/Mmake* . cd $root/stage2 else # $root/runtime may be in a different grade from the stage2 directories. ln -s $root/stage2.ok/runtime . fi ln -s $root/boehm_gc . ln -s $root/browser . ln -s $root/ssdb . ln -s $root/trace . ln -s $root/robdd . ln -s $root/doc . ln -s $root/scripts . ln -s $root/util . ln -s $root/profiler . ln -s $root/deep_profiler . ln -s $root/tools . ln -s $root/conf* . ln -s $root/aclocal.m4 . ln -s $root/VERSION . ln -s $root/Mercury.options . ln -s $root/.*.in . rm -f config*.log cp $root/stage2.ok/Mmake* . cd $root # 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/*.dv stage2/library cp stage2.ok/library/*.int0 stage2/library cp stage2.ok/library/*.int3 stage2/library cp stage2.ok/library/*.date3 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/library/*.opt stage2/library cp stage2.ok/library/*.optdate stage2/library cp stage2.ok/library/*.trans_opt stage2/library cp stage2.ok/library/*.trans_opt_date stage2/library cp stage2.ok/library/*.mh stage2/library cp stage2.ok/library/*.mih stage2/library # cp stage2.ok/mdbcomp/*.d stage2/mdbcomp cp stage2.ok/mdbcomp/*.dep stage2/mdbcomp cp stage2.ok/mdbcomp/*.dv stage2/mdbcomp cp stage2.ok/mdbcomp/*.int0 stage2/mdbcomp cp stage2.ok/mdbcomp/*.int3 stage2/mdbcomp cp stage2.ok/mdbcomp/*.date3 stage2/mdbcomp cp stage2.ok/mdbcomp/*.int stage2/mdbcomp cp stage2.ok/mdbcomp/*.int2 stage2/mdbcomp cp stage2.ok/mdbcomp/*.date stage2/mdbcomp cp stage2.ok/mdbcomp/*.mh stage2/mdbcomp cp stage2.ok/mdbcomp/*.mih stage2/mdbcomp # cp stage2.ok/compiler/*.d stage2/compiler cp stage2.ok/compiler/*.dep stage2/compiler cp stage2.ok/compiler/*.dv stage2/compiler cp stage2.ok/compiler/*.int0 stage2/compiler cp stage2.ok/compiler/*.int3 stage2/compiler cp stage2.ok/compiler/*.date3 stage2/compiler cp stage2.ok/compiler/*.int stage2/compiler cp stage2.ok/compiler/*.int2 stage2/compiler cp stage2.ok/compiler/*.date stage2/compiler cp stage2.ok/compiler/*.mh stage2/compiler cp stage2.ok/compiler/*.mih stage2/compiler if test "$bootcheck" = "" then cd $root [ -d stage3 ] || mkdir stage3 $RMSTAGECMD $trueroot/stage3/compiler < /dev/null & $RMSTAGECMD $trueroot/stage3/library < /dev/null & wait $RMSTAGECMD $trueroot/stage3/* < /dev/null echo linking stage 3... 1>&2 cd stage3 ln -s $root/main.c mkdir compiler cd compiler # Break up the links into several chunks. # This is needed to cope with small limits # on the size of argument vectors. ln -s $root/compiler/[a-h]*.m . ln -s $root/compiler/[i-o]*.m . ln -s $root/compiler/[p-s]*.m . ln -s $root/compiler/[t-z]*.m . cp $root/compiler/Mmake* . cp $root/compiler/Mercury* . cp $root/compiler/*FLAGS* . cp $root/compiler/.mgnuc* . cd $root/stage3 mkdir library cd library ln -s $root/library/[a-l]*.m . ln -s $root/library/[m-z]*.m . ln -s $root/library/*.init . cp $root/library/Mercury* . cp $root/library/*FLAGS* . cp $root/library/mer_std.trans_opt_deps_spec . cp $root/library/.mgnuc* . cp $root/library/Mmake* . cd $root/stage3 mkdir mdbcomp cd mdbcomp ln -s $root/mdbcomp/*.m . ln -s $root/mdbcomp/*.init . cp $root/mdbcomp/Mercury* . cp $root/mdbcomp/*FLAGS* . cp $root/mdbcomp/.mgnuc* . cp $root/mdbcomp/Mmake* . cd $root/stage3 ln -s $root/boehm_gc . ln -s $root/browser . ln -s $root/ssdb . ln -s $root/trace . ln -s $root/doc . ln -s $root/scripts . ln -s $root/util . ln -s $root/profiler . ln -s $root/deep_profiler . ln -s $root/runtime . ln -s $root/tools . ln -s $root/conf* . ln -s $root/aclocal.m4 . ln -s $root/VERSION . ln -s $root/Mercury.options . ln -s $root/.*.in . rm -f config*.log /bin/rm -f Mmake* cp $root/stage2.$basis/Mmake* . # cp $root/stage2.ok/so_locations . cd $root fi set -x if "$copy_runtime" then if (cd stage2 ; mmake $mmake_opts $jfactor runtime) then echo "building of stage 2 runtime successful" else echo "building of stage 2 runtime not successful" exit 1 fi fi cp stage2.ok/main.o stage2 for subdir in library mdbcomp do echo linking stage2/$subdir from stage2.ok/$subdir 1>&2 cp stage2.ok/$subdir/*.[co] stage2/$subdir cp stage2.ok/$subdir/*.pic_o stage2/$subdir done for subdir in compiler do echo linking stage2/$subdir from stage2.ok/$subdir 1>&2 cp stage2.ok/$subdir/*.[co] stage2/$subdir done # start out with all files in stage2 coming from stage2.$base set +x echo linking stage2 from stage2.$base 1>&2 cp stage2.$base/library/*.[co] stage2/library cp stage2.$base/library/*.pic_o stage2/library cp stage2.$base/compiler/*.[co] stage2/compiler set -x # find the set of candidate modules samen="" goodn="" badn="" /bin/rm -fr $root/SAME_C > /dev/null 2>&1 /bin/rm -fr $root/GOOD_C > /dev/null 2>&1 /bin/rm -fr $root/BAD_C > /dev/null 2>&1 mkdir $root/SAME_C mkdir $root/GOOD_C mkdir $root/BAD_C /bin/rm $root/.unary.progress n=1 while test "$n" -le "$limit" do # at this point, all the files in stage2 should be from stage2.$base echo "testing $n" echo $n > $root/.unary.checkpoint echo $n >> $root/.unary.progress date >> $root/.unary.progress cd $root/stage2/${tested_dir_name} cp $root/stage2.ok/${tested_dir_name}/${tested_module_name}.d . $mmc_command --experiment=$n -C ${tested_file_name}.m /bin/rm ${tested_module_name}.d if cmp $root/stage2.ok/${tested_dir_name}/${tested_module_name}.c ${tested_module_name}.c then echo "test $n generated same .c file" samen="$samen $n" cp $root/stage2/${tested_dir_name}/${tested_module_name}.c $root/SAME_C/$n.c else mmake ${tested_module_name}.o if test "${tested_dir_name}" = "library" then mmake ${tested_module_name}.pic_o fi cd $root if binary_step $bootcheck $compile_only $compare_to_bad $dependency_only $library_only $jfactor -m "$mmake_opts" $outfile $testdirs -s "$single_command" then echo "test $n succeeded" goodn="$goodn $n" cp $root/stage2/${tested_dir_name}/${tested_module_name}.c $root/GOOD_C/$n.c else echo "test $n failed" badn="$badn $n" cp $root/stage2/${tested_dir_name}/${tested_module_name}.c $root/BAD_C/$n.c fi fi n=`expr $n + 1` done echo "the parameter values for same .c are: $samen" echo "the parameter values for success are: $goodn" echo "the parameter values for failure are: $badn" echo echo echo "finishing at `date`" exit 0