lyx_mirror/development/keystest/autolyx

496 lines
11 KiB
Plaintext
Raw Normal View History

#!/bin/bash
# This script starts LyX, and restarts LyX if it is closed
# it logs all output, including backtraces to development/keystest/out/GDB
#Setting the following may give better screen shots
#gconftool-2 /apps/metacity/general/compositing_manager -s -t bool true
DIRNAME0=`dirname "$0"`
OUTDIR="$DIRNAME0/out"
ROOT_OUTDIR="$DIRNAME0/out"
THIS_PID=$$
EXE_TO_TEST=src/lyx
if [ ! -e "$EXE_TO_TEST" ]
then
echo "$EXE_TO_TEST" does not exist
echo Cannot proceed
exit
fi
#BORED_AFTER_SECS=7200 #If we have spend more than 3600 secs (an hour) replaying a file, without learning anything new, go and start looking for more bugs instead
BORED_AFTER_SECS=3600 #If we have spend more than 3600 secs (an hour) replaying a file, without learning anything new, go and start looking for more bugs instead
LAST_CORE=""
#############################
# This section of code is LyX Specific
#############################
if [ ! -e $DIRNAME0/.lyx ]
then
echo WARNING $DIRNAME0/.lyx does not exist
echo will need to regenerate .lyx every test
fi
#if [ ! -e lib/doc.orig ]
#then
# mv lib/doc lib/doc.orig
#fi
kill_all_children() {
kill `list_all_children.sh $1`
sleep 0.1
kill -9 `list_all_children.sh $1`
}
ensure_cannot_print () {
if [ ! -z "$REPLAYFILE" ]
then
return
fi
if lpq
then
echo We can print, this is bad!
echo use lpadmin to stop keytest from destroying a forest.
full_exit
sleep 999999 ; read
else
echo "Phew, lpq reckons we aren't ready to print. This is a *good* thing!"
fi
}
extras_save () {
return
for f in `ls lib/doc`
do
if [ lib/doc/$f -nt lib/doc.orig/$f -o ! -e lib/doc.orig/$f ]
then
#echo making doc dir $OUTDIR/$SEC.doc
mkdir -p $OUTDIR/$SEC.doc
cp -a lib/doc/$f $OUTDIR/$SEC.doc/
fi
done
}
extras_prepare () {
return
mkdir -p lib/doc/
rm lib/doc/*.lyx
cp -p lib/doc.orig/*.lyx lib/doc/
}
get_crash_id () {
name=`(cat $GDB | grep -o ' in lyx::[[:alnum:]:]*' ; cat $GDB | grep -o ' [ai][nt] [[:alnum:]:]*' ) | head -n3 | sed s/in// | sed 's/ //g'`
echo $name | sed 's/ /__/g'
}
calc_confirm_file() {
id=`get_crash_id`
echo "$ROOT_OUTDIR/$id.reproduced"
}
get_pid () {
sleep 3
echo getting pidof "$1" 1>&2
#PID=`ps "-u$USER" "$2" | grep "$1" | grep -v grep | sed 's/^ *//g'| sed 's/ .*$//'`
PID=`ps x | grep "$1" | grep -v grep | sed 's/^ *//g'| sed 's/ .*$//'`
echo "$PID" | ( grep " " > /dev/null && ( echo too many PIDs 1>&2 ; full_exit ) )
nPIDs=`echo PID "$PID" | wc -l`
echo nPIDs $nPIDs 1>&2
sleep 1
echo -- if [ "$nPIDs" != "1" ] 1>&2
if test "$nPIDs" != "1" #2> /tmp/testerr
then
echo autolyx: Wrong number of PIDs "$nPIDs" "($1)" "($2)" 1>&2
fi
echo "$PID"
echo got pidof "$1" 1>&2
}
clean_up () {
KT_PID=`get_pid keytest.py x`
kill $KT_PID
sleep 0.1
kill -9 $KT_PID
}
full_exit() {
clean_up
echo attempting to exit this entire script... normal exit may just exit one function
kill $THIS_PID
sleep 1
echo We should not get this far
sleep 1
kill -9 $THIS_PID
echo We really should not get this far
exit
}
run_gdb () {
echo Starting GDB
(echo "
shell svn info src/
run
bt
shell kill $CHILD_PID
shell wmctrl -l
shell sleep 1
shell kill -9 $CHILD_PID
" ; yes q) | HOME="$NEWHOME" gdb src/lyx 2>&1 | strings| tee $GDB
echo "end run_gdb"
#### gcore $GDB.core
#shell wmctrl -r __renamed__ -b add,shaded
#shell wmctrl -r term -b add,shaded
#shell wmctrl -r term -b add,shaded
#shell wmctrl -R lyx'
#
#shell import -window root '$GDB.png'
#shell import -window root '$GDB..png'
#exit
}
###########################
try_replay () {
id=`get_crash_id`
echo CRASH_ID
export CONFIRM_FILE=`calc_confirm_file`
if [ ! -e "$CONFIRM_FILE" ]
then
echo $CONFIRM_FILE does not exist
echo This bug appears not to have been reproduced before
echo Will try to reproduce now
echo
do_replay
echo
echo Finished attempt at replay
else
echo $CONFIRM_FILE exists
echo This bugs has already been reproduced
echo Will not attempt to reproduce again
fi
}
do_replay() {
(REPLAYFILE="$KEYCODEpure" TAIL_LINES=25 MAX_TAIL_LINES=10000 bash "$0")&
TEST_PID="$!"
echo Backgrounded $TEST_PID
echo waiting for $TEST_PID to finish
wait "$TEST_PID"
}
test_replayed () {
test -e "$f.replay/last_crash_sec" -o -e "$f.replay/Irreproducible"
}
move_to_replayed () {
mkdir -p $REPLAY_DIR/replayed
mv $f* $REPLAY_DIR/replayed
}
do_queued_replays() {
REPLAY_DIR=development/keytest/out/toreplay
for f in `ls $REPLAY_DIR/*KEYCODEpure`
do
if test_replayed
then
move_to_replayed
else
#./development/keytest/killtest
killall lyx
sleep 1
killall -9 lyx
KEYCODEpure="$f" do_replay
#if test_replayed
#then
move_to_replayed
#fi
fi
done
}
#get_pid() {
# ps a | grep $1 | grep -v grep | sed 's/^ *//g'| sed 's/ .*$//'
#}
do_one_test() {
GDB=$OUTDIR/$SEC.GDB
KEYCODE=$OUTDIR/$SEC.KEYCODE
KEYCODEpure=$OUTDIR/$SEC.KEYCODEpure
NEWHOME=~/kt.dir/$SEC.dir
mkdir -p $NEWHOME
NEWHOME=`cd $NEWHOME; pwd`
echo NEWHOME $NEWHOME
mkdir -p "$NEWHOME"
cp -rv $DIRNAME0/.lyx "$NEWHOME"/
killall -9 lyx latex pdflatex
( sleep 9 &&
ps a | grep lyx
echo -- 1 || full_exit
LYX_PID=""
i=0
echo -- while [ -z "$LYX_PID" -a 200 -gt $i ]
while [ -z "$LYX_PID" -a 200 -gt $i ]
do
#export LYX_PID=`ps a | grep /src/lyx | grep -v grep | sed 's/^ *//g'| sed 's/ .*$//'`
export LYX_PID=`get_pid "/src/lyx$" `
echo LYXPID "$LYX_PID" || full_exit
sleep 0.1
i=$(($i+1))
done
echo `ps a | grep /src/lyx`
echo -- 2
echo `ps a | grep /src/lyx | grep -v grep`
echo -- 3
echo `ps a | grep /src/lyx | grep -v grep | sed 's/ [a-z].*$//'`
echo -- 4
echo LYX_PID=$LYX_PID
echo XA_PRIMARY | xclip -selection XA_PRIMARY
echo XA_SECONDARY | xclip -selection XA_SECONDARY
echo XA_CLIPBOARD | xclip -selection XA_CLIPBOARD
echo -- if [ ! -z "$LYX_PID" ]
if [ ! -z "$LYX_PID" ]
then
kill `ps a | grep keytest.py | grep -v grep | cut -c 1-5`
sleep 0.2
kill -9 `ps a | grep keytest.py | grep -v grep | cut -c 1-5`
while ! wmctrl -r lyx -b add,maximized_vert,maximized_horz
do
echo trying to maximize lyx
sleep 1
done
KEYTEST_OUTFILE="$KEYCODEpure" nice -19 python $DIRNAME0/keytest.py | tee $KEYCODE
#echo "$!" > $NEWHOME/keytest_py.pid
fi
killall lyx) &
CHILD_PID="$!"
ls src/lyx ; sleep 1
pwd
#You may want to use the following to simulate SIGFPE
#(sleep 90 && killall -8 lyx) &
echo TTL $TAIL_LINES
extras_prepare
ensure_cannot_print
run_gdb
# (run_gdb) &
# GDBTASK_PID="$!"
# (sleep 600 ; kill "$!")
# echo WAITING FOR: wait $GDBTASK_PID
# wait $GDBTASK_PID
# echo NOLONGER waiting for: wait $GDBTASK_PID
echo END gdb
kill $CHILD_PID
KT_PID=`get_pid keytest.py`
echo KT_PID=$KT_PID
kill $KT_PID
sleep 0.3
kill -9 $CHILD_PID
kill -9 $KT_PID
# Or use "exited normally":
echo END gdb2
# these tend to take up a huge amount of space:
rm -rf $NEWHOME
if (grep " signal SIG[^TK]" $GDB || grep KILL_FREEZE $KEYCODE)
then
extras_save
mkdir -p $OUTDIR/save && (
ln $OUTDIR/$SEC.* $OUTDIR/save ||
cp $OUTDIR/$SEC.* $OUTDIR/save)
LAST_CRASH_SEC=$SEC
echo $LAST_CRASH_SEC > $OUTDIR/last_crash_sec
if [ ! -z "$TAIL_LINES" ]
then
LAST_EVENT="$SEC"
echo Reproducible > $OUTDIR/Reproducible
fi
TAIL_LINES=""
if [ -z "$REPLAYFILE" ]
then
echo ATTEMPTING TO REPLAY
try_replay
else
export KEYTEST_INFILE=$KEYCODEpure
NUM_KEYCODES=`wc -l < $KEYCODEpure`
echo NUM_KEYCODES $NUM_KEYCODES, was $LAST_NUM_KEYCODES
if [ "$NUM_KEYCODES" != "$LAST_NUM_KEYCODES" ]
then
LAST_EVENT="$SEC"
LAST_NUM_KEYCODES=$NUM_KEYCODES
echo "Hooray! we have eleminated some keycodes"
fi
fi
if [ ! -z "$AND_THEN_QUIT" ]
then
RESULT=1
echo RR 1
return 1
fi
if [ ! -z "$LAST_CORE" ]
then
rm "$LAST_CORE"
fi
LAST_CORE="$GDB.core"
else
rm -rf $BAK/*
mv $OUTDIR/$SEC.* $BAK/
if [ ! -z "$TAIL_LINES" ]
then
echo TTL3 $TAIL_LINES
echo MAX_TAIL_LINES "$MAX_TAIL_LINES"
TAIL_LINES=$(($TAIL_LINES*2))
echo TTL4 $TAIL_LINES
if [ "$TAIL_LINES" -ge "0$MAX_TAIL_LINES" -a ! -z "$MAX_TAIL_LINES" ]
then
echo Giving up because $TAIL_LINES '>' $MAX_TAIL_LINES
echo Irreproducible > $OUTDIR/Irreproducible
full_exit
fi
fi
if [ ! -z "$AND_THEN_QUIT" ]
then
RESULT=0
echo RR 0
return 0
fi
echo TTL2 $TAIL_LINES
fi
}
if [ ! -z "$1" ]
then
REPLAYFILE=$1
fi
if [ ! -z "$REPLAYFILE" ]
then
echo REPLAYMODE
OUTDIR="$REPLAYFILE.replay/"
mkdir -p $REPLAYFILE.replay/ || full_exit
export KEYTEST_INFILE=$REPLAYFILE
if [ ! -e "$REPLAYFILE" ]
then
echo "$REPLAYFILE" does not exist
echo exiting
full_exit 1
fi
else
do_queued_replays
echo RANDOM MODE
fi
get_pid [0-9].x-session-manager"$" x
export X_PID=`get_pid [0-9].x-session-manager x`
echo X_PID $X_PID
export TAIL_LINES=$TAIL_LINES
echo TL $TAIL_LINES
BAK="$OUTDIR/backup"
mkdir -p $BAK
#rename other windows to avoid confusion.
wmctrl -N __renamed__ -r lyx
wmctrl -N __renamed__ -r lyx
wmctrl -N __renamed__ -r lyx
wmctrl -N __renamed__ -r lyx
export PATH=`cd $DIRNAME0; pwd`/path:$PATH
if [ ! -z "$1" ]
then
SEC=`date +%s`
export MAX_DROP=0
if [ ".$SCREENSHOT_OUT." = ".auto." ]
then
echo SCREENSHOT_OUT was $SCREENSHOT_OUT.
export SCREENSHOT_OUT="$OUTDIR/$SEC.s"
echo SCREENSHOT_OUT is $SCREENSHOT_OUT.
#exit
fi
export RESULT=179
do_one_test #| tee do_one_test.log
RESULT="$?"
echo Ressult $RESULT
kill `list_all_children.sh $$`
sleep 0.1
kill -9 `list_all_children.sh $$`
exit $RESULT
#echo done ; sleep 1
full_exit
fi
(
echo TTL $TAIL_LINES
LAST_EVENT=`date +%s` # Last time something interesting happened. If nothing interesting has happened for a while, we should quit.
ensure_cannot_print
echo X_PID $X_PID
export X_PID=`get_pid [0-9].x-session-manager"$" x`
echo PATH $PATH
while true
do
echo Currently running autolyx PID=$$
if [ ! -z "$TAIL_LINES" ]
then
echo TAIL_LINES: "$TAIL_LINES"
TAIL_FILE=$OUTDIR/tail_"$TAIL_LINES"
tail -n "$TAIL_LINES" "$REPLAYFILE" > $TAIL_FILE
KEYTEST_INFILE=$TAIL_FILE
MAX_DROP=0
else
MAX_DROP=0.2
fi
export MAX_DROP
SEC=`date +%s`
if [ ! -z "$REPLAYFILE" ]
then
echo Boredom factor: $SEC-$LAST_EVENT'=' $(($SEC-$LAST_EVENT))
if [ $(($SEC-$LAST_EVENT)) -gt $BORED_AFTER_SECS ]
then
echo
echo Is is now $SEC seconds
echo The last time we managed to eliminate a keycode was at $LAST_EVENT
echo We get bored after $BORED_AFTER_SECS seconds
echo Giving up now.
echo
echo $LAST_CRASH_SEC > $OUTDIR/Finished
mkdir $OUTDIR/final
ln $OUTDIR/$SEC* $OUTDIR/final || cp $OUTDIR/$SEC* $OUTDIR/final
CONFIRM_FILE=`calc_confirm_file`
echo Reproducible > "$CONFIRM_FILE"
full_exit
fi
else
do_queued_replays
fi
do_one_test
done
kill_all_children $$
) 2>&1 |tee $OUTDIR/log
kill_all_children $$