New keytest version from John McCabe-Dansted

http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg156659.html

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@32740 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Pavel Sanda 2010-01-02 21:46:11 +00:00
parent 9e5a12b905
commit 81dea0164c
16 changed files with 964 additions and 560 deletions

View File

@ -3,40 +3,35 @@
This is a program to spam LyX with millions of randomly generated key This is a program to spam LyX with millions of randomly generated key
presses, and collect the crash results. presses, and collect the crash results.
Since the code involves spamming random keypresses, I'd recommend Since the code involves spamming random keypresses, I run it under a special
running it in a VM, well away from your main X windows session. user "keytest", well away from my main X windows session.
In short, to use this, run development/keytest/lyx_make.sh To use this software, first configure it by editing the
configuration parameters in shared_functions.sh and shared_variables.sh
then run the following:
It requires the following packages to run ./setup.sh # add keytest user and apt-get required files
xvkbd wmctrl sudo -H -u keytest -e xterm # Create a xterm for running keytest in
the following are also useful: . ./initXvfb # sets up a fake X server for keytest to play in
lyx libqt4-dbg subversion automake ./main.sh
It is run by running ./autolyx in one xterm, and ./test.py in another. Note that this bug finding software is itself quite buggy.
I wrote lyx_make.sh as a easy way of updating lyx and running these two
programs together.
CONTENTS: CONTENTS:
README: this readme file README: this readme file
report.sh: A quick way of generating bug reports and an overview from the logs. report_html.sh: A quick way of generating bug reports and an overview from the logs.
make_screen_shots.sh: a script for making screenshots, if they are missing from output of above.
autolyx: A script to continually restart lyx and collect the bug reports autolyx: A script to continually restart lyx and collect the bug reports
lyx_make.sh: should updates, compiles, and everything needed to generated logs.
maketar.sh: Makes this tar file :) maketar.sh: Makes this tar file :)
test.py: Sends LT100 randomly generated keypresses per second to the LyX window. keytest.py: Sends randomly generated keypresses to the LyX window.
killtest: stop the testing killtest: stop the testing
stock_text: The stock test to add to each bug report. stock_text: The stock test to add to each bug report.
OUTPUTS: OUTPUTS:
autolyx: Outputs out/GDB, a log of all output, including backtraces. autolyx: Outputs out/*.GDB, a log of all output, including backtraces.
test.py: Outputs out/KEYCODES, a list of all keycodes sent to LyX keytest.py: Outputs out/*.KEYCODES, a list of all keycodes sent to LyX
reports.sh: Outputs
out/overview: an overview of all the frequency of each error
out/overview_sort: as above but sorted
out/report_*: A collection of autogenerated bug reports.
AUTHOR: AUTHOR:
Copyright (C) 2009 John McCabe-Dansted, gmatht at gmail dot com. Copyright (C) 2009 John McCabe-Dansted, gmatht at gmail dot com.

View File

@ -0,0 +1,7 @@
#!/bin/bash
#
# This command makes all files in "$ROOT_OUTDIR" writable by keytest.
#
# This command is useful if you run keytest under a seperate user "keytest" of group "keytest"
. ./shared_variables.sh
find $ROOT_OUTDIR | while read f ; do chmod g+rw $f ; chgrp keytest $f ;done

View File

@ -1,495 +1,5 @@
#!/bin/bash #!/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"` DIRNAME0=`dirname "$0"`
OUTDIR="$DIRNAME0/out" . $DIRNAME0/shared_variables.sh
ROOT_OUTDIR="$DIRNAME0/out" . $DIRNAME0/shared_functions.sh
THIS_PID=$$ autolyx_main "$@"
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 $$

View File

@ -1,5 +1,8 @@
#!/bin/bash #!/bin/bash
KT=`dirname $0` KT=`dirname "$0"`
. "$KT/shared_functions.sh"
N=$1 N=$1
shift shift
@ -13,8 +16,11 @@ do
if ! "$@" if ! "$@"
then then
echo TRIES_REQUIRED: $i echo TRIES_REQUIRED: $i
kill_all_children $$
exit 1 exit 1
fi fi
done done
kill_all_children $$
echo DONE $N TIMES echo DONE $N TIMES

26
development/keystest/initXvfb Executable file
View File

@ -0,0 +1,26 @@
if [ -z "$1" ]
then
d=1
else
d=$1
fi
#Xvfb :1 -screen 1 800x600x24 -fbdir /tmp &
#Xvfb :1 -screen 1 800x600x24 -pixdepths "1 8 16 24 32" &
#Xvfb :$d -ac -screen 0 800x600x24 -wr
echo 1
Xvfb :$d -ac -screen 0 800x600x24 -wr &
echo 2
export DISPLAY=:$d
echo 3
icewm&
echo 4
#metacity&
echo 5
while true
do
sleep 300
icewm &
done &
echo 6

View File

@ -137,6 +137,8 @@ class CommandSourceFromFile(CommandSource):
os._exit(0) os._exit(0)
if self.i >= len(self.lines): if self.i >= len(self.lines):
self.loops = self.loops + 1 self.loops = self.loops + 1
if self.loops > 3:
os._exit(0)
self.i = 0 self.i = 0
return 'Loop' return 'Loop'
line = self.lines[self.i] line = self.lines[self.i]
@ -181,18 +183,31 @@ def sendKeystring(keystr, LYX_PID):
while not lyx_sleeping(): while not lyx_sleeping():
time.sleep(0.02) time.sleep(0.02)
print '.', print '.',
print 'Making Screenshot: ' + screenshot_out print 'Making Screenshot: ' + screenshot_out + ' OF ' + infilename
time.sleep(0.2) time.sleep(0.2)
os.system('import -window root '+screenshot_out+str(x.count)+".png") os.system('import -window root '+screenshot_out+str(x.count)+".png")
time.sleep(0.1) time.sleep(0.1)
sys.stdout.flush() sys.stdout.flush()
subprocess.call(["xvkbd", "-xsendevent", "-delay", DELAY, "-text", keystr]) subprocess.call(["xvkbd", "-xsendevent", "-delay", DELAY, "-text", keystr])
def system_retry(num_retry, cmd):
i = 0
rtn = os.system(cmd)
while ( ( i < num_retry ) and ( rtn != 0) ):
i = i + 1
rtn=os.system(cmd)
time.sleep(1)
if ( rtn != 0 ):
print "Command Failed: "+cmd
print " EXITING!\n"
os._exit(1)
def RaiseWindow(): def RaiseWindow():
os.system("echo x-session-manager PID: $X_PID.") os.system("echo x-session-manager PID: $X_PID.")
os.system("echo x-session-manager open files: `lsof -p $X_PID | grep ICE-unix | wc -l`") os.system("echo x-session-manager open files: `lsof -p $X_PID | grep ICE-unix | wc -l`")
os.system("wmctrl -l | ( grep '"+lyx_window_name+"' || ( killall lyx ; sleep 1 ; killall -9 lyx ))") ####os.system("wmctrl -l | ( grep '"+lyx_window_name+"' || ( killall lyx ; sleep 1 ; killall -9 lyx ))")
os.system("wmctrl -R '"+lyx_window_name+"' ;sleep 0.1") #os.system("wmctrl -R '"+lyx_window_name+"' ;sleep 0.1")
system_retry(30, "wmctrl -R '"+lyx_window_name+"'")
lyx_pid = os.environ.get('LYX_PID') lyx_pid = os.environ.get('LYX_PID')
@ -253,7 +268,7 @@ while True:
if os.path.exists('/proc/' + lyx_pid + '/status'): if os.path.exists('/proc/' + lyx_pid + '/status'):
sendKeystring(c[4:], lyx_pid) sendKeystring(c[4:], lyx_pid)
else: else:
os.system('killall lyx; sleep 2 ; killall -9 lyx') ##os.system('killall lyx; sleep 2 ; killall -9 lyx')
print 'No path /proc/' + lyx_pid + '/status, exiting' print 'No path /proc/' + lyx_pid + '/status, exiting'
os._exit(1) os._exit(1)
elif c[0:4] == 'KD: ': elif c[0:4] == 'KD: ':

View File

@ -18,7 +18,7 @@ kill_all_children () {
kill -9 `listall "$*"` kill -9 `listall "$*"`
} }
if [ "$1"="$kill" ] if [ "$1" = "kill" ]
then then
shift shift
kill_all_children "$*" kill_all_children "$*"

9
development/keystest/main.sh Executable file
View File

@ -0,0 +1,9 @@
#PWD=`pwd`
if [ "$USER" != keytest ]
then
echo USER is "$USER", not keytest! Exiting.
exit
fi
#(DISPLAY=:1 sudo -u keytest -H nice -18 ; cd $PWD ; ./autolyx)
./killtest.sh # kill any previous test, so does not interfere
./autolyx

View File

@ -0,0 +1,13 @@
. ./shared_variables.sh
OUT=$ROOT_OUTDIR
for f in `ls $OUT/*/final/*pure`
do
echo file_ $f
if [ ! -e $f.replay ]
then
echo replaying $f for screenshot
#(SCREENSHOT_OUT="auto" ./doNtimes.sh 3 ./reproduce.sh $f ; echo $f ; ./list_all_children.sh kill $$ ) 2>&1 | tee $f.screenshot-log
(SCREENSHOT_OUT="auto" ./doNtimes.sh 9 ./reproduce.sh $f ; echo $f ) 2>&1 | tee $f.screenshot-log
echo replayed $f for screenshot
fi
done

View File

@ -1,31 +1,45 @@
#!/bin/bash #!/bin/bash
#LT=development/keystest #LT=development/keystest
LT=`dirname $0` LT=`dirname $0`
. $LT/shared_variables.sh
GEOM=320x200 GEOM=320x200
QUALITY=85 QUALITY=85
if [ -z "$KEYCODE_DIR" ] if [ -z "$KEYCODE_DIR" ]
then then
KEYCODE_DIR=out KEYCODE_DIR=$ROOT_OUTDIR
fi fi
#convert -normalize -scale $GEOM -quality $QUALITY $f $GEOM/$f #convert -normalize -scale $GEOM -quality $QUALITY $f $GEOM/$f
UNIQUE_LINE=1 UNIQUE_LINE=1
OUT=$LT/out/html4 OUT=$LT/$OUT_NAME/html
URL_OF_OUT=http://gmatht.homelinux.net/xp/$OUT_NAME/html/
mkdir -p $OUT mkdir -p $OUT
rm $OUT/index*.html rm $OUT/index*.html
ls $OUT/*.html ls $OUT/*.html
CPP_HTML_DIR_REL=cpp_html CPP_HTML_DIR_REL=cpp_html
CPP_HTML_DIR=$out/cpp_html CPP_HTML_DIR=$OUT/cpp_html
strings $LT/out/GDB.* > $LT/out/GDBs LYX_VER=`src/lyx -version 2>&1 | head -n1 | sed s/^LyX\ // | sed s/\ .*// | sed s/1svn/0/ | sed s/2svn/1/ | sed s/3svn/2/ | sed s/4svn/3/ | sed s/5svn/4/ | sed s/6svn/5/ | sed s/7svn/6/ | sed s/8svn/7/ | sed s/9svn/8/`
grep "#$UNIQUE_LINE " $LT/out/GDBs > $LT/out/list BOILER_PLATE=`cd src ; svn info 2>&1 | grep Revision`
cat $LT/out/list | sed 's/0x[^ )]*[ )]/.*/g' | sort | uniq | tee $LT/out/listuniq
strings $LT/$OUT_NAME/GDB.* > $LT/$OUT_NAME/GDBs
grep "#$UNIQUE_LINE " $LT/$OUT_NAME/GDBs > $LT/$OUT_NAME/list
cat $LT/$OUT_NAME/list | sed 's/0x[^ )]*[ )]/.*/g' | sort | uniq | tee $LT/$OUT_NAME/listuniq
echo '<html>' >> $OUT/indexreport.html echo '<html>' >> $OUT/indexreport.html
list_keycode_files () {
echo for f in $OUT_NAME/*y/last_crash_sec $OUT_NAME/toreplay/replayed/*y/last_crash_sec
for f in $OUT_NAME/*y/last_crash_sec $OUT_NAME/toreplay/replayed/*y/last_crash_sec $OUT_NAME/toreplay/*y/last_crash_sec $OUT_NAME/toreplay/final/*y/last_crash_sec
do
keycode_file=$(echo $f | sed s/last_crash_sec/$(cat $f).KEYCODEpure/)
echo $keycode_file
done
}
tidy_keycode () { tidy_keycode () {
while read -r k while read -r k
do do
@ -49,9 +63,62 @@ html_keycode() {
} }
trac_keycode() {
echo -n "'''"
cat "$f_base.KEYCODEpure" | tidy_keycode
echo -n "'''"
#echo -n '""'
#echo -n '<font color=gray>'
cat "$f_base.KEYCODEpure+" | tidy_keycode
#echo -n '</font>'
}
line2url() {
echo "$@" | sed 's/&/%26/g' | sed 's/"/%22/g' | sed 's/#/%23/g' | sed 's/;/%3B/g'
}
text2url() {
#echo "$@" |
while read -r L
do
#echo -n `echo "$L" | line2url`'%0A'
echo -n `line2url "$L"`'%0A'
done
}
report_bug_url () {
#http://www.lyx.org/trac/newticket?description=bar%0Abar2&summary=foo%13oo&keywords=crash&version=1.6.5
#http://www.lyx.org/trac/newticket?summary=foo%13oo&description=bar%0Abar2&version=1.6.5&keywords=crash
#ver=`echo $3 | sed s/1svn/0/ | sed s/2svn/1/ | sed s/3svn/2/ | sed s/4svn/3/ | sed s/5svn/4/ | sed s/6svn/5/ | sed s/7svn/6/ | sed s/8svn/7/ | sed s/9svn/8/`
#echo 'http://www.lyx.org/trac/newticket?summary='`line2url "$1"`'&description='`text2url "$2"`'&version='"$LYX_VER"'&keywords=crash'
DESC=`get_description | text2url`
#DESC=`text2url "$DESC"`
if echo $DESC | grep SIGSEGV > /dev/null
then
KEYWORDSTR="&keywords=crash"
else
if echo $DESC | grep SIGABRT > /dev/null
then
KEYWORDSTR="&keywords=assertion"
elif echo $DESC | grep SIGSEGV > /dev/null
then
KEYWORDSTR="crash"
fi
fi
echo 'http://www.lyx.org/trac/newticket?summary='`line2url "$TITLE"`"&description=$DESC&version=$LYX_VER$KEYWORDSTR"
#echo 'http://www.lyx.org/trac/newticket?description='"$1"'&summary=foo%13oo&keywords=crash&version=1.6.
}
search_bug_url () {
#http://www.lyx.org/trac/search?q=Foo%20bar
echo 'http://www.lyx.org/trac/search?q='`line2url "$TITLE"`
}
gdb2html() { gdb2html() {
echo g $g echo g $g'<br/>'
cat $g | sed 's/&/&amp/g' | sed 's/</&lt/g' | while read -r l head $g -n 100 | sed 's/&/\&amp;/g' | sed 's/</\&lt;/g' | sed 's/ /\&nbsp /g' | while read -r l
do do
#c=`echo $l | grep -i -o "at [[:alnum:]./]*:[0-9]*"` #c=`echo $l | grep -i -o "at [[:alnum:]./]*:[0-9]*"`
#We may want to support slashes later, but we'd have to support browsing #We may want to support slashes later, but we'd have to support browsing
@ -79,11 +146,60 @@ do
done | sed 's/^/<br\/>/' done | sed 's/^/<br\/>/'
} }
get_description() {
echo "Keycodes: "
trac_keycode
ii=1
echo
echo To reproduce:
cat "$f_base.KEYCODEpure" "$f_base.KEYCODEpure+" | while read -r L
do
echo "$ii) ... ($L)"
ii=$((ii+1))
done
echo
echo Arch: `arch`
svn_revision $f_base
echo '{{{'
cat $g
echo '}}}'
echo
echo For more info see the "[[$URL_OF_OUT/$HTML_NAME Keytest Report]]"
}
make_cpp_html() {
#This is ugly. At the moment all bug reports in the same set reference the same files, which could lead to confusion if they are from differnt versions of lyx. Do not mix different versions until this is fixed. However we may not want to "fix" this when it may be better to always use a new outdir for each version and just reproduce the old bugs so they don't get lost.
if ! test -e $ROOT_OUTDIR/html/cpp_html
then
(mkdir -p $ROOT_OUTDIR/html/cpp_html/ &&
cd $ROOT_OUTDIR/html/cpp_html/ &&
for f in `f ../../../src/ .cpp$` ; do g=`basename $f`; c2html -n < $f > $g.html ; echo $f ; done)
fi
}
svn_revision() {
#| grep ^Revision | sed s/'Revision: '/r/
echo KEYCODE $1 ... `dirname $1` 1>&2
cat `dirname $1`/last_crash_sec.info.svn | grep ^Revision
echo _KEYCODE $KEYCODE ... 1>&2
}
echo beginning echo beginning
#for file in `find $LT/out/ -anewer $LT/out/html | grep replay/last_crash_sec` make_cpp_html
#for file in `find $LT/$OUT_NAME/ -anewer $LT/$OUT_NAME/html | grep replay/last_crash_sec`
#for file in `find $KEYCODE_DIR | grep save/.*KEYCODEpure` #for file in `find $KEYCODE_DIR | grep save/.*KEYCODEpure`
for file in `find $KEYCODE_DIR -anewer oldfile | grep save/.*KEYCODEpure$` #for file in `find $KEYCODE_DIR -anewer oldfile | grep save/.*KEYCODEpure$ | head -n4`
#for file in `ls $KEYCODE_DIR/*/final/*KEYCODEpure`
#for file in `ls $KEYCODE_DIR/*/final/*/*KEYCODEpure`
list_keycode_files
echo END OF KEYCODE FILES
for file in `list_keycode_files`
do do
echo FILE $file
lcs_file=`echo $file | sed 's/save\/.*//g'`last_crash_sec lcs_file=`echo $file | sed 's/save\/.*//g'`last_crash_sec
echo last_crash_sec file: $lcs_file echo last_crash_sec file: $lcs_file
SEC2=`cat $lcs_file` SEC2=`cat $lcs_file`
@ -99,7 +215,7 @@ do
echo f_base $f_base echo f_base $f_base
NUM_KEYCODES=`wc -l < "$f_base.KEYCODEpure"` NUM_KEYCODES=`wc -l < "$f_base.KEYCODEpure"`
echo NUM_KEYCODES=$NUM_KEYCODES... echo NUM_KEYCODES=$NUM_KEYCODES...
if [ "$NUM_KEYCODES" -lt 80 ] if [ "$NUM_KEYCODES" -lt 10 ]
then then
echo f_base $f_base echo f_base $f_base
f=$f_base.GDB f=$f_base.GDB
@ -113,29 +229,47 @@ do
TITLE="$SIGNAL $IN_AT" TITLE="$SIGNAL $IN_AT"
TITLE_=`echo $TITLE|sed s/[^[:alnum:]]/_/g` TITLE_=`echo $TITLE|sed s/[^[:alnum:]]/_/g`
INDEX="index.html" INDEX="index.html"
HTML_NAME=$SEC.html # name of html report for this bug
echo TITLE $TITLE echo TITLE $TITLE
echo INDEX $INDEX echo INDEX $INDEX
echo NEW $INDEX echo NEW $INDEX
echo '<html>' >> $LT/out/$INDEX echo '<html>' >> $LT/$OUT_NAME/$INDEX
echo -n "<a href=\"$SEC.html\">$TITLE</a> " >> $OUT/indexreport.html (echo -n "<br/><a href=\"$SEC.html\">$TITLE</a> "
html_keycode >> $OUT/indexreport.html html_keycode
if ls $f_base.s*.png echo " [<a href=\"`search_bug_url`\">search</a>] [<a href=\"`report_bug_url`\">report</a>] <a href=\"$SEC.screenshot.html\">screenshots</a>"
then #if ls $f_base.s*.png
echo -n "<a href=\"$SEC.screenshot.html\">screenshots</a>" >> $OUT/indexreport.html #then
fi # echo "<a href=\"$SEC.screenshot.html\">screenshots</a>"
echo -n '<br/> '>> $OUT/indexreport.html #fi
echo >> $OUT/indexreport.html #echo -n '<br/> '
echo -n '<br> '>> $LT/out/$INDEX echo ) >> $OUT/indexreport.html
echo >> $LT/out/$INDEX echo -n '<br> '>> $LT/$OUT_NAME/$INDEX
echo >> $LT/$OUT_NAME/$INDEX
( echo '<html>' ( echo '<html>'
echo "<h1>$TITLE</h1>" echo "<title>$TITLE</title>"
html_keycode html_keycode
echo "<a href=$SEC.KEYCODE>KEYCODES</a> " echo "<br/><a href=$SEC.KEYCODE>KEYCODES</a> "
echo " <a href=$SEC.KEYCODEpure>pure</a> "
echo "<a href=$SEC.GDB>GDB</a>" echo "<a href=$SEC.GDB>GDB</a>"
if ls $f_base.s*.png > /dev/null
then
echo "<a href=\"$SEC.screenshot.html\">screenshots</a>"
else
echo '(no screenshots)'
fi
echo "<br/>"
#echo -n '<br/> '
#echo "<a href=$SEC.GDB.png><img src=$SEC.small.png/></a><br/><br/>" #echo "<a href=$SEC.GDB.png><img src=$SEC.small.png/></a><br/><br/>"
echo "<a href=$SEC.screenshot.html><img src=$SEC.small.png/></a><br/><br/>" #echo "<a href=$SEC.screenshot.html><img src=$SEC.small.png/></a><br/><br/>"
gdb2html gdb2html
(echo ----
svn_revision $f_base
echo arch `arch`
dpkg -l | egrep '(libqt4-dbg|libc6 |libboost-dev )'
lsb_release -a) | sed 's/&/\&amp;/g' | sed 's/</\&lt;/g' | sed 's/ /\&nbsp /g' | sed 's/^/<br\/>/'
) > $OUT/$SEC.html ) > $OUT/$SEC.html
echo '<a href="'"$SEC.html"'">'$SEC'</a><br/>' >> $OUT/$INDEX echo '<a href="'"$SEC.html"'">'$SEC'</a><br/>' >> $OUT/$INDEX
echo '<a href="'"$SEC.html"'">'$SEC'</a><br/>' echo '<a href="'"$SEC.html"'">'$SEC'</a><br/>'
@ -155,6 +289,8 @@ done
mv $OUT/indexreport.html $OUT/indexreport.html.bak mv $OUT/indexreport.html $OUT/indexreport.html.bak
echo "<html>" >> $OUT/indexreport.html echo "<html>" >> $OUT/indexreport.html
echo "<h1>List of bugs found</h1>" >> $OUT/indexreport.html echo "<h1>List of bugs found</h1>" >> $OUT/indexreport.html
echo '<p>Please, do not "report" bugs without searching for them first. Also make sure to fill out the "To reproduce" section before pressing the "Create ticket" button</p>' >> $OUT/indexreport.html
sort -k 2 -t '>' < $OUT/indexreport.html.bak >> $OUT/indexreport.html sort -k 2 -t '>' < $OUT/indexreport.html.bak >> $OUT/indexreport.html
firefox $OUT/indexreport.html firefox $OUT/indexreport.html
#google-chrome $OUT/indexreport.html

View File

@ -0,0 +1,6 @@
#!/bin/bash
KT=`dirname $0`
AND_THEN_QUIT="y" time $KT/autolyx $1
RESULT=$?
echo RESULT_REPRODUCE $RESULT
exit $RESULT

32
development/keystest/setup.sh Executable file
View File

@ -0,0 +1,32 @@
#This won't work on an RPM based distro. Easy to fix though.
sudo apt-get install xclip xvkbd wmctrl xvfb libqt4-dbg icewm #svn pylint
sudo adduser keytest < /dev/null
if ! grep keytest /etc/sudoers
then
echo allowing admin users to switch to keytest user
#echo '%adm ALL =(keytest) NOPASSWD: ALL' >> /etc/sudoers
fi
# cat /mnt/jaunty/etc/cups/printers.conf |grep -o '[^ ]*>$' |grep -v '^<'| sed 's/>$//'
#we should really handle each printer seperately, but this will work if they are similar
if grep AllowUser /etc/cups/printers.conf
then
echo printer: using whitelisting, nothings needs be done.
exit
fi
if grep DenyUser /etc/cups/printers.conf
then
echo There are already denied users. We do not support this yet, exiting
exit
fi
#(cd /etc/cups/ppd/ && ls *.ppd) | sed s/.ppd$// | while read L
cat /etc/cups/printers.conf |grep -o '[^ ]*>$' |grep -v '^<'| sed 's/>$//' | while read L
do
echo $L
echo lpadmin -p $L -u deny:keytest
lpadmin -p $L -u deny:keytest
done

View File

@ -0,0 +1,642 @@
DIRNAME0=`dirname "$0"`
#ROOT_OUTDIR="$DIRNAME0/out"
OUTDIR="$ROOT_OUTDIR"
#OUTDIR="$DIRNAME0/out"
THIS_PID=$$
SRC_DIR=lyx/src
EXE_TO_TEST=$SRC_DIR/lyx
#kill(){
# echo kill
#}
#killall (){
# echo killall
#}
mkdirp () {
mkdir -p "$1"
chmod g+w "$1"
}
kill_all_children() {
kill `$DIRNAME0/list_all_children.sh $1`
sleep 0.1
kill -9 `$DIRNAME0/list_all_children.sh $1`
}
#BORED_AFTER_SECS=7200 #If we have spent more than 3600 secs (an hour) replaying a file, without learning anything new, go and start looking for more bugs instead
if [ -z $BORED_AFTER_SECS ]
then
BORED_AFTER_SECS=3600 #If we have spent more than 3600 secs (an hour) replaying a file, without learning anything new, go and start looking for more bugs instead
fi
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 `$DIRNAME0/list_all_children.sh $1`
# sleep 0.1
# kill -9 `$DIRNAME0/list_all_children.sh $1`
#}
#. $DIRNAME0/shared_functions.sh
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
mkdirp $OUTDIR/$SEC.doc
cp -a lib/doc/$f $OUTDIR/$SEC.doc/
fi
done
}
extras_prepare () {
return
mkdirp 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 ERROR too many PIDs 1>&2 ; ps x ; 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
echo autolyx: PIDs "$PID" 1>&2
ps x 1>&2
echo -----
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 () {
#Spawn a process to kill lyx if it runs too long
if ! touch $GDB
then
echo cannot touch $GDB
full_exit
fi
(sleep 300; echo KILLER ACTIVATIED ;killall gdb lyx ; sleep 1 ; killall -9 gdb lyx)&
KILLER_PID=$!
echo KILLING LYX, before starting new lyx
killall lyx
sleep 1
killall lyx -9
sleep 1
echo Starting GDB
#shell svn info $SRC_DIR/
(echo "
run
bt
#shell kill $CHILD_PID
shell wmctrl -l
#shell sleep 1
#shell kill -9 $CHILD_PID
" ; yes q) | HOME="$NEWHOME" gdb $EXE_TO_TEST 2>&1 | strings| tee $GDB
echo "end run_gdb ($KILLER_PID)"
kill $KILLER_PID
sleep 0.1
kill -9 $KILLER_PID
#### 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 () {
mkdirp $REPLAY_DIR/replayed
mv $f* $REPLAY_DIR/replayed
}
do_queued_replay() {
if test_replayed
then
move_to_replayed
else
#./development/keytest/killtest
killall lyx
sleep 1
echo killall -9 lyx
killall -9 lyx
KEYCODEpure="$f" do_replay
#if test_replayed
#then
move_to_replayed
#fi
fi
}
do_queued_replays() {
REPLAY_DIR=$OUTDIR/toreplay
echo doing queued_replays
echo replays `ls $REPLAY_DIR/*KEYCODEpure`
for f in `ls $REPLAY_DIR/*KEYCODEpure`
do
do_queued_replay
done
echo done queued_replays
(
REPLAY_DIR=$OUTDIR/toreproduce
export BORED_AFTER_SECS=0
echo doing queued_reproduce
echo reproduce`ls $REPLAY_DIR/*KEYCODEpure`
for f in `ls $REPLAY_DIR/*KEYCODEpure`
do
do_queued_replay
done
echo done queued_reproduce
)
}
#get_pid() {
# ps a | grep $1 | grep -v grep | sed 's/^ *//g'| sed 's/ .*$//'
#}
get_version_info() {
(cd $SRC_DIR ; svn info) 2>&1 |tee "$1".svn
$EXE_TO_TEST -version 2>&1 "$1".version
}
do_one_test() {
GDB=$OUTDIR/$SEC.GDB
KEYCODE=$OUTDIR/$SEC.KEYCODE
KEYCODEpure=$OUTDIR/$SEC.KEYCODEpure
NEWHOME=~/kt.dir/$SEC.dir
mkdirp $NEWHOME
NEWHOME=`cd $NEWHOME; pwd`
echo NEWHOME $NEWHOME
mkdirp "$NEWHOME"
cp -rv $DIRNAME0/.lyx "$NEWHOME"/
echo killall -9 lyx latex pdflatex
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 "$EXE_TO_TEST$" `
echo LYXPID "$LYX_PID" || full_exit
sleep 0.1
i=$(($i+1))
done
echo `ps a | grep $EXE_TO_TEST`
echo -- 2
echo `ps a | grep $EXE_TO_TEST | grep -v grep`
echo -- 3
echo `ps a | grep $EXE_TO_TEST | 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
echo BEGIN KEYTEST KEYTEST_OUTFILE="$KEYCODEpure" nice -19 python $DIRNAME0/keytest.py
KEYTEST_OUTFILE="$KEYCODEpure" nice -19 python $DIRNAME0/keytest.py | tee $KEYCODE
#echo "$!" > $NEWHOME/keytest_py.pid
echo END_KEYTEST
fi
echo NO_KEYTEST
echo killall lyx
killall lyx
sleep 0.1
kill -9 "$LYX_PID"
killall -9 lyx #sometimes LyX really doesn't want to die causing the script to freeze
#killall lyx #sometimes LyX really doesn't want to die causing the script to freeze
sleep 1
#kill -9 "$LYX_PID" #sometimes LyX really doesn't want to die causing the script to freeze
#sleep 1
#killall -9 lyx
) &
CHILD_PID="$!"
ls $EXE_TO_TEST ; 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:
echo will erase "$NEWHOME"
sleep 2
rm -rf $NEWHOME
if (grep " signal SIG[^TK]" $GDB || grep KILL_FREEZE $KEYCODE)
then
extras_save
mkdirp $OUTDIR/save && (
ln $OUTDIR/$SEC.* $OUTDIR/save ||
cp $OUTDIR/$SEC.* $OUTDIR/save)
LAST_CRASH_SEC=$SEC
echo $LAST_CRASH_SEC > $OUTDIR/last_crash_sec
get_version_info $OUTDIR/last_crash_sec.info
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
if ! test -z "$BAK"
then
echo will erase '$BAK/*'="'$BAK/*'"
sleep 2
rm -rf $BAK/*
mv $OUTDIR/$SEC.* $BAK/
else
echo "BAK is null"
fi
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
}
test_exist () {
if [ ! -e "$1" ]
then
echo "$1" does not exist!
full_exit 1
fi
}
assert () {
if ! "$@"
then
echo "Assertion '$*' Failed!"
full_exit 1
fi
}
#####################################################
# MAIN
#####################################################
#Start basic sanity checks
autolyx_main () {
if [ ! -e "$EXE_TO_TEST" ]
then
echo "$EXE_TO_TEST" does not exist
echo Cannot proceed
exit
fi
assert which xvkbd
assert which wmctrl
if ! wmctrl -l > /dev/null
then
echo autolyx: cannot run wmctrl -l
exit
fi
test_exist "$EXE_TO_TEST"
test_exist "$DIRNAME0/keytest.py"
if ! test -z "`pylint -e $DIRNAME0/keytest.py`"
then
echo "$DIRNAME0/keytest.py" has python errors
exit
fi
ensure_cannot_print
#End basic sanity checks
if [ ! -z "$1" ]
then
REPLAYFILE=$1
fi
if [ ! -z "$REPLAYFILE" ]
then
echo REPLAYMODE
OUTDIR="$REPLAYFILE.replay/"
mkdirp $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"
mkdirp $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 "$TAIL_LINES" -a ! -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
SEC=$LAST_CRASH_SEC #I used SEC in place of LAST_CRASH_SEC. Here is a quick fix.
#make screenshots
if [ `cat $OUTDIR/$SEC.KEYCODEpure | wc -l` -lt 40 ] # If many keycodes, dont bother trying to make screenshots
then
echo "Making screenschot of $OUTDIR/$SEC.KEYCODEpure"
test -e $OUTDIR/$SEC.KEYCODEpure || echo "DOES NOT EXIST: $OUTDIR/$SEC.KEYCODEpure"
(SCREENSHOT_OUT="auto" ./doNtimes.sh 9 ./reproduce.sh $OUTDIR/$SEC.KEYCODEpure ; echo $f )
fi
mkdirp $OUTDIR/final
mkdirp $OUTDIR/final_cp
#chmod g+w $OUTDIR/final
ln $OUTDIR/$SEC* $OUTDIR/final || cp $OUTDIR/$SEC* $OUTDIR/final
cp $OUTDIR/$SEC* $OUTDIR/final_cp/
cp -rv $OUTDIR/$SEC.replay $OUTDIR/final_cp/
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 $$
}

View File

@ -0,0 +1,3 @@
DIRNAME0=`dirname "$0"`
OUT_NAME=out.2
ROOT_OUTDIR="$DIRNAME0/$OUT_NAME"

3
development/keystest/view:1 Executable file
View File

@ -0,0 +1,3 @@
(DISPLAY=:1 import -window root /tmp/:1.png)
#gwenview /tmp/:1.png
eog /tmp/:1.png

View File

@ -1,26 +1,27 @@
. ./shared_variables.sh
OUT="$ROOT_OUTDIR"
NOW_SEC=`date +%s` NOW_SEC=`date +%s`
echo NOW_SEC $NOW_SEC echo NOW_SEC $NOW_SEC
echo recently modified files: echo recently modified files:
LATEST_FILE=`ls out/* -td -1 | grep -v log | head -n1` LATEST_FILE=`ls $ROOT_OUTDIR/* -td -1 | grep -v log | head -n1`
echo $LATEST_FILE | ( echo $LATEST_FILE | (
grep replay > /dev/null || ( grep replay > /dev/null || (
ls out/* -lotd | head ls $ROOT_OUTDIR/* -lotd | head -n6
) )
) )
ls out/* -tdo -1 | grep replay |head -n4 ls $ROOT_OUTDIR/* -tdo -1 | grep replay |head -n4
LATEST_FILE=`ls out/* -td -1 | grep replay | head -n1` LATEST_FILE=`ls $ROOT_OUTDIR/* -td -1 | grep replay | head -n1`
if [ $LATEST_FILE = "out/toreplay" ] if [ $LATEST_FILE = "$ROOT_OUTDIR/toreplay" ]
then then
#echo foo #echo foo
LATEST_FILE=`ls out/toreplay/* -td -1 | grep replay | head -n1` LATEST_FILE=`ls $ROOT_OUTDIR/toreplay/* -td -1 | grep replay | head -n1`
fi fi
if [ $LATEST_FILE = "out/toreplay/replayed" ] if [ $LATEST_FILE = "$ROOT_OUTDIR/toreplay/replayed" ]
then then
echo foo echo foo
LATEST_FILE=`ls out/toreplay/replayed/* -td -1 | grep replay | head -n1` LATEST_FILE=`ls $ROOT_OUTDIR/toreplay/replayed/* -td -1 | grep replay | head -n1`
else else
echo oof echo oof
fi fi
@ -35,14 +36,14 @@ echo $LATEST_FILE | (
echo $SEC $(($NOW_SEC-$SEC)) echo $SEC $(($NOW_SEC-$SEC))
ls -l $LATEST_FILE/$SEC.KEYCODEpure | head -n4 ls -l $LATEST_FILE/$SEC.KEYCODEpure | head -n4
echo `cat $LATEST_FILE/$SEC.KEYCODEpure | sed s/KK:\//g` echo `cat $LATEST_FILE/$SEC.KEYCODEpure | sed s/KK:\//g`
cat $LATEST_FILE/$SEC.GDB | grep "signal SIG" -A 15 cat $LATEST_FILE/$SEC.GDB | grep "signal SIG" -A 10
else else
ls $LATEST_FILE -lot | head ls $LATEST_FILE -lot | head
cat `echo $LATEST_FILE | sed s/KEYCODEpure.replay/GDB/` | grep "signal SIG" -A 29 cat `echo $LATEST_FILE | sed s/KEYCODEpure.replay/GDB/` | grep "signal SIG" -A 19
fi fi
cat $LATEST_FILE/log | grep Bore | tail -n2 cat $LATEST_FILE/log | grep Bore | tail -n2
) || ( ) || (
ls out/* -lotd | head ls $ROOT_OUTDIR/* -lotd | head
) )
) )
@ -51,11 +52,11 @@ grep -F "autolyx:
Trace Trace
reproduced reproduced
X_PID X_PID
x-session" out/log | grep -v kill | grep -v Terminated | tail -n 9 x-session" $ROOT_OUTDIR/log | grep -v kill | grep -v Terminated | tail -n 9
#exit #exit
echo autolyx crashes --------- echo autolyx crashes ---------
grep autolyx: out/log | grep -v kill | grep -v Terminated #-A 5 grep autolyx: $ROOT_OUTDIR/log | grep -v kill | grep -v Terminated #-A 5
echo python crashes --------- echo python crashes ---------
grep -i -a Trace out/log -A 7 | tail -n8 grep -i -a Trace $ROOT_OUTDIR/log -A 7 | tail -n8
#echo misc ---- #echo misc ----
#grep reproduced out/log | tail -n5 #grep reproduced $ROOT_OUTDIR/log | tail -n5