]> git.lyx.org Git - features.git/commitdiff
Next contribution to key tests from John McCabe-Dansted.
authorPavel Sanda <sanda@lyx.org>
Fri, 10 Jul 2009 15:52:43 +0000 (15:52 +0000)
committerPavel Sanda <sanda@lyx.org>
Fri, 10 Jul 2009 15:52:43 +0000 (15:52 +0000)
http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg152761.html

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@30451 a592a061-630c-0410-9148-cb99ea01b6c8

development/keystest/TODO [new file with mode: 0644]
development/keystest/autolyx
development/keystest/find_in_finals [new file with mode: 0644]
development/keystest/keytest.py [new file with mode: 0644]
development/keystest/lyx_make.sh
development/keystest/replay.sh [deleted file]
development/keystest/report_html.sh
development/keystest/test.py [deleted file]
development/keystest/watch_keytest.sh [new file with mode: 0644]

diff --git a/development/keystest/TODO b/development/keystest/TODO
new file mode 100644 (file)
index 0000000..3551e6d
--- /dev/null
@@ -0,0 +1,12 @@
+HTML out with links.
+Try to get KEYCODES to be repeatible and useable (DONE)
+semi protect home dir for repeatibility.
+Support mouse clicks.
+Do not spend hours reproducing a bug that has already been reproduced. (DONE)
+Support other failure modes (e.g. freezes and Python tracebacks)
+Tally of failures vs successes
+If come across different bug when trying to reproduce another, reproduce *both* bugs
+Add report as to how easy bug is to reproduce
+Try e.g. electric fence
+Automatically update from svn every 24 hours, recheck if bugs have been fixed.
+Make it easy to use Xvfb instead of VM.
index cf666a37d976b6a00baff21e0023762f1797c5e2..228fd12b1254c12d9c9d228db0563b99d47aaafc 100755 (executable)
 
 DIRNAME0=`dirname "$0"`
 OUTDIR="$DIRNAME0/out"
+ROOT_OUTDIR="$DIRNAME0/out"
+THIS_PID=$$
+
+
+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
+
+#############################
+# This section of code is LyX Specific
+#############################
+
+if [ ! -e lib/doc.orig ]
+then
+       mv lib/doc lib/doc.orig
+fi
+
+ensure_cannot_print () {
+lpq && ( 
+       echo We can print, this is bad!
+       echo use lpadmin to stop keytest from destroying a forest.
+       full_exit
+       sleep 999999 ; read
+)
+}
+
+extras_save () {
+ 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 () {
+       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"
+}
+
+full_exit() {
+       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_PIS
+       echo We really should not get this far
+       exit
+}
+
+###########################
+
+get_pid () {
+       echo getting pidof "$1" 1>&2
+       PID=`ps a"$2" | 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`
+       if [ "$nPIDs" != "1" ]
+       then 
+               echo autolyx: Wrong number of PIDs "$nPIDs" 1>&2
+       fi
+       echo "$PID"
+}
+
+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" 
+}
+
+do_queued_replays() {
+for f in `ls development/keytest/out/toreplay/*KEYCODEpure`
+do
+       if [ ! -e "$f.replay/last_crash_sec" ]
+       then
+               #./development/keytest/killtest
+               killall lyx
+               sleep 1
+               killall -9 lyx
+               KEYCODEpure="$f" do_replay
+       fi
+done
+}
+
+
+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
 (
+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
+               CONFIRM_FILE=`calc_confirm_file`
+               echo Reproducible > "$CONFIRM_FILE"
+               
+               
+               full_exit
+       fi
+ fi
+
   GDB=$OUTDIR/$SEC.GDB
   KEYCODE=$OUTDIR/$SEC.KEYCODE
-  ( sleep 20 && python $DIRNAME0/test.py | tee $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 ~/.lyx "$NEWHOME"/
+  killall -9 lyx
+  ( sleep 25 &&
+     ps a | grep lyx 
+       echo -- 1
+     LYX_PID=""
+     i=0
+     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/ .*$//'`
+            echo LYXPID "$LYX_PID"
+            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
+
+     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`
+         KEYTEST_OUTFILE="$KEYCODEpure" nice -19 python $DIRNAME0/keytest.py | tee $KEYCODE
+     fi
+     killall lyx) &
   CHILD_PID="$!"
   ls src/lyx ; sleep 1
    pwd
-  #sleep 10
   
   #You may want to use the following to simulate SIGFPE
   #(sleep 90 && killall -8 lyx) &
-
+  echo TTL $TAIL_LINES
+  extras_prepare
+  ensure_cannot_print
+  echo Starting GDB
   (echo "
   shell svn info src/
   run
@@ -43,18 +273,55 @@ do
   shell wmctrl -r term -b add,shaded
   shell wmctrl -R lyx 
   shell import -window root '$GDB..png'
- " ; yes q) | gdb src/lyx 2>&1 | strings|  tee $GDB
+ " ; yes q) | HOME="$NEWHOME" gdb src/lyx 2>&1 | strings|  tee $GDB
+  echo END gdb
   kill $CHILD_PID
-  #sleep 2 kill -9 $CHILD_PID
-  grep " signal " $GDB || (
-    rm $OUTDIR/*GDB*.bak
-    rm $OUTDIR/*KEYCODE*.bak
-    mv $KEYCODE $KEYCODE.bak
-    mv $GDB $GDB.bak
-    mv $GDB.png $GDB.png.bak
-    mv $GDB..png $GDB..png.bak
-    #rm $OUTDIR/KEYCODE.$SEC
-    #rm $OUTDIR/GDB.$SEC
-  )
+  sleep 0.3
+  kill -9 $CHILD_PID
+  # Or use "exited normally":
+  if grep " signal SIG[^T]" $GDB 
+  then
+    extras_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
+  else
+    rm -r $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
+    echo TTL2 $TAIL_LINES
+  fi
 done
 ) 2>&1 |tee $OUTDIR/log
diff --git a/development/keystest/find_in_finals b/development/keystest/find_in_finals
new file mode 100644 (file)
index 0000000..0a2ff97
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/sh
+# Searchs for a string in all the final versions 
+
+for f in `find . -name "last_crash_sec"`
+do     
+       SEC=`cat $f`
+       g=`echo $f| sed s/last_crash_sec/$SEC/`
+       grep "$1" $g*
+done
diff --git a/development/keystest/keytest.py b/development/keystest/keytest.py
new file mode 100644 (file)
index 0000000..aacbb47
--- /dev/null
@@ -0,0 +1,178 @@
+#!/usr/bin/env python
+#This script generated hundreds of random keypresses per second,
+#  and sends them to the lyx window
+#It requires xvkbd and wmctrl
+#It generates a log of the KEYCODES it sends as development/keystest/out/KEYCODES
+
+import random
+import os 
+import re
+import sys
+
+print "Beginning keytest.py"
+
+
+class CommandSource:
+       def __init__(self):
+               keycode=["\[Left]",'\[Right]','\[Down]','\[Up]','\[BackSpace]','\[Delete]','\[Escape]']
+               keycode[:0]=keycode
+               keycode[:0]=keycode
+
+               keycode[:0]=['\\']
+
+               for k in range(97, 123):
+                 keycode[:0]=chr(k)
+
+               for k in range(97, 123):
+                 keycode[:0]=["\A"+chr(k)]
+
+               for k in range(97, 123):
+                 keycode[:0]=["\A"+chr(k)]
+
+               for k in range(97, 123):
+                 keycode[:0]=["\C"+chr(k)]
+
+               self.keycode=keycode;
+               self.count=0;
+               self.count_max=1999;
+
+       def getCommand(self):
+               self.count=self.count+1;
+               #if self.count > self.count_max:
+               if self.count%200==0:
+                       #self.count=0
+                       return ("RaiseLyx")
+               elif self.count > self.count_max:
+                       os._exit(0)
+               else:
+                       keystr=""
+                       for k in range(1,2):
+                               keystr=keystr+self.keycode[random.randint(1,len(self.keycode))-1]
+                       return "KK: "+keystr
+
+class CommandSourceFromFile(CommandSource):
+       def __init__(self,filename,p):
+               self.infile=open(filename,'r')
+               self.lines=self.infile.readlines()
+               self.p=p
+               self.i=0
+               self.count=0
+               self.loops=0
+               #Now we start randomly dropping lines, which we hope are redundant
+               #p is the probability that any given line will be removed
+               if (p>0):
+                       #The next couple of lines are to ensure that at least one line is dropped
+                       drop=random.randint(0,len(self.lines)-1)
+                       del self.lines[drop]
+                       p=p-(1/len(self.lines))
+                       j=0
+                       origlines=self.lines
+                       self.lines=[];
+                       for l in origlines:
+                               if random.uniform(0,1) < self.p:
+                                       print "Randomly dropping line "+l+"\n"
+                               else:
+                                       self.lines.append(l)
+                       print "LINES\n"
+                       print self.lines
+                       sys.stdout.flush()
+                       os.system("sleep 2")
+               
+       def getCommand(self):
+               if self.i >= len(self.lines):
+                       if self.count >= 100 or self.loops>1:
+                               os.system("sleep 1")
+                               os._exit(0)
+                       else:
+                               self.loops=self.loops+1
+                               self.i=0
+                               return("Loop")
+               line=self.lines[self.i]
+               print "Line read: <<"+line+">>\n"
+               self.count=self.count+1
+               self.i=self.i+1
+               return(line.rstrip())
+
+def sendKeystring(keystr,LYX_PID):
+       print "sending keystring "+keystr+"\n"
+       if not re.match(".*\w.*", keystr):
+               print ("print ."+keystr+".\n")
+               keystr="a"
+       os.system("while ( test -e /proc/$LYX_PID/status && ! grep 'tate.*[(]sleeping[)]' /proc/$LYX_PID/status); do echo -n . ; sleep 0.02; done")
+       cmd="xvkbd -xsendevent -text '"+keystr+"';sleep 0.03"
+       sys.stdout.flush()
+        os.system(cmd)
+       sys.stdout.flush()
+
+def RaiseWindow():
+       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("wmctrl -l | ( grep '"+lyx_window_name+"' || ( killall lyx ; sleep 1 ; killall -9 lyx ))")
+       os.system("wmctrl -R '"+lyx_window_name+"' ;sleep 0.1")
+       
+                       
+lyx_pid=os.environ.get("LYX_PID")
+print("lyx_pid: "+lyx_pid+"\n");
+infilename=os.environ.get("KEYTEST_INFILE")
+outfilename=os.environ.get("KEYTEST_OUTFILE")
+max_drop=os.environ.get("MAX_DROP")
+lyx_window_name=os.environ.get("LYX_WINDOW_NAME");
+
+file_new_command=os.environ.get("FILE_NEW_COMMAND");
+if file_new_command is None:
+       file_new_command="\Afn"
+
+ResetCommand=os.environ.get("RESET_COMMAND");
+if ResetCommand is None:
+       ResetCommand="\[Escape]\[Escape]\[Escape]\[Escape]"+file_new_command
+       #ResetCommand="\[Escape]\[Escape]\[Escape]\[Escape]\Cw\Cw\Cw\Cw\Cw\Afn"
+
+if lyx_window_name is None:
+       lyx_window_name="LyX";
+
+print("outfilename: "+outfilename+"\n")
+print("max_drop: "+max_drop+"\n")
+
+if infilename is None:
+       print("infilename is None\n")
+       x=CommandSource()
+       print ("Using x=CommandSource\n");
+else:
+       print("infilename: "+infilename+"\n")
+       probability_we_drop_a_command=random.uniform(0,float(max_drop))
+       print ("probability_we_drop_a_command: ")
+       print '%s'%(probability_we_drop_a_command)
+       print  "\n"
+       x=CommandSourceFromFile(infilename,probability_we_drop_a_command)
+       print ("Using x=CommandSourceFromFile\n");
+
+outfile=open(outfilename,'w')
+
+RaiseWindow()
+sendKeystring("\Afn",lyx_pid)
+write_commands=True;
+
+while True:
+       os.system("echo -n LOADAVG:; cat /proc/loadavg")
+       c=x.getCommand()
+       if (c=="Loop"):
+               outfile.close()
+               outfile=open(outfilename+'+','w')
+               print ("Now Looping")
+       outfile.writelines(c+'\n')
+       outfile.flush()
+       if c=="RaiseLyx":
+               print ("Raising Lyx");
+               RaiseWindow()
+       elif c[0:4]=="KK: ":
+               if os.path.exists("/proc/"+lyx_pid+"/status"):
+                       sendKeystring(c[4:],lyx_pid)
+               else:
+                       os.system("killall lyx; sleep 2 ; killall -9 lyx")
+                       print ("No path /proc/"+lyx_pid+"/status, exiting")
+                       os._exit(1)
+       elif (c=="Loop"):
+               RaiseWindow()
+               sendKeystring(ResetCommand,lyx_pid)
+       else:
+               print ("Unrecognised Command '"+c+"'\n")
index 14637efceee57043c0d2907f206703a585788f34..5e7d84ad9ea539e8eca84db447289a5ff7bcf6d7 100755 (executable)
@@ -11,7 +11,7 @@ if ! [ -d $LT ]; then
 fi
 
 mkdir -p $LT/out
-if which wmctrl xvkbd bash xterm python
+if which wmctrl xvkbd bash xterm python xclip
 then 
 
  if [ a"$1" == a--update ]; then
diff --git a/development/keystest/replay.sh b/development/keystest/replay.sh
deleted file mode 100644 (file)
index f2fa27e..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/bin/bash
-# This script starts LyX, and restarts LyX if it is closed
-# it logs all output, including backtraces to development/keystest/out/GDB
-
-#rename other windows to avoid confusion.
-DIRNAME0=`dirname "$0"`
-OUTDIR="$DIRNAME0/out"
-WAITSECS=20
-INFILE="$1"
-LINES_TO_INCLUDE=8
-
-if [ ! -e "$INFILE" ]
-then
-       echo cannot find "$INFILE"
-       exit
-fi
-
-killall lyx
-
-wmctrl -N __renamed__ -r lyx
-wmctrl -N __renamed__ -r lyx
-wmctrl -N __renamed__ -r lyx
-wmctrl -N __renamed__ -r lyx
-
-while ! grep " signal SIG[^T]" "$INFILE.new_gdb"
-do
-  SEC=`date +%s`
-  echo GDB---------------- >> "$INFILE.new_gdb.bak"
-  cat "$INFILE.new_gdb" >> "$INFILE.new_gdb.bak"
-  echo LINES_TO_INCLUDE $LINES_TO_INCLUDE
-  #cat $NUMLINES
-  tail -n $LINES_TO_INCLUDE < $INFILE > $INFILE.new_key
-  NUMLINES=`wc -l "$INFILE.new_key"`
-  echo NUMLINES $NUMLINES
-  ( i=0
-    echo Waiting $WAITSECS before starting replay
-    sleep $WAITSECS 
-    echo Starting replay
-    wmctrl -R LyX && xvkbd -xsendevent -text '\Afn'
-    cat "$INFILE.new_key" |
-    while read -r l
-    do
-      wmctrl -R LyX && xvkbd -xsendevent -text "$l"
-      #echo -- "$l"
-      i=$(($i+1))
-      echo $i/$NUMLINES
-      sleep 0.1
-    done
-    echo FINISHED REPLAY
-    sleep 4
-    killall lyx
-    sleep 2
-    killall lyx -9
-    echo FINISHED REPLAY and killed lyx
-  ) &
-  CHILD_PID="$!"
-  echo "Starting Lyx"
-  (echo "run
-  bt" ; yes q) | gdb src/lyx 2>&1 | strings|  tee "$INFILE.new_gdb"
-  kill $CHILD_PID
-  sleep 2 kill -9 $CHILD_PID
-  LINES_TO_INCLUDE=$(($LINES_TO_INCLUDE*2))
-  
-done
-echo END
index 62870ed94cde181fa879e3b33a4d6827c50d710b..a1bbf72ce35db626380fd7cb998b8d74da2260ae 100644 (file)
@@ -1,10 +1,13 @@
 #!/bin/bash
 LT=development/keystest
 
-# echo 'grep "#1 " $LT/out/GDB | sed 's/0x[^ )]*[ )]/.*/g'  | sort | uniq' >> report.sh
+GEOM=320x200
+convert -normalize -scale $GEOM -quality $QUALITY $f $GEOM/$f
 
 UNIQUE_LINE=1
 SRC=
+
+
 if [ -e out/log ]
 then   
    LT=.
@@ -19,60 +22,117 @@ do
   fi
 done
 
-OUT=$LT/out
+OUT=$LT/out/html
+mkdir -p $OUT
 rm $OUT/index*.html
-#rm $OUT/indexreport.html
 ls $OUT/*.html
 
+CPP_HTML_DIR_REL=cpp_html
+CPP_HTML_DIR=$out/cpp_html
+
 strings $LT/out/GDB.* > $LT/out/GDBs 
 grep "#$UNIQUE_LINE " $LT/out/GDBs > $LT/out/list
-#cat $LT/out/list | grep -o ' in [[:alnum:]:]* ' | sort | uniq| tee $LT/out/listuniq
-#cat $LT/out/list | grep -o ' in [[:alnum:]:]* ' | sort | uniq| tee $LT/out/listuniq
 cat $LT/out/list | sed 's/0x[^ )]*[ )]/.*/g'  | sort | uniq | tee $LT/out/listuniq
 
-NUM_REPORTS=`wc -l < $LT/out/list`
-echo NUM_REPORTS $NUM_REPORTS
+echo '<html>' >> $OUT/indexreport.html
 
-echo > $LT/out/overview
+tidy_keycode () {
+while  read -r k
+do
+       if [ "$k" = Raiselyx ] 
+       then
+               echo -n '\[!Raiselyx]'
+       elif  [ "$k" = Loop ] 
+       then
+               echo -n '\[!Loop]'
+       else
+               echo -n "$k" | sed s/^KK:\ //
+       fi
+done
+}
 
-echo '<html>' >> $OUT/indexreport.html
+html_keycode() {
+         cat "$f_base.KEYCODEpure" | tidy_keycode 
+         echo -n '<font color=gray>'
+         cat "$f_base.KEYCODEpure+" | tidy_keycode 
+         echo -n '</font><br/>'
+}
 
-#cat $LT/out/listuniq | while read l 
-for f in $LT/out/*GDB
+gdb2html() {
+cat $g | sed 's/&/&amp/g' | sed 's/</&lt/g'  | while read -r l
 do
+       c=`echo $l | grep -i -o "at [[:alnum:].]*:[0-9]*"`
+       if [ -z "$c" ]
+       then
+               echo -- "$l" | sed s/--//
+       else
+               cpp=`echo "$c" | sed s/at\ // | sed s/:.*//g`
+               lineno=`echo "$c" | sed s/.*://g`
+               echo $cpp,$lineno 1>&2
+               #if [ -e "$CPP_HTML_DIR/$cpp.html" ]
+               if true
+               then
+                       echo "$l" | sed "s/$c/<a href=$CPP_HTML_DIR_REL\/$cpp.html\#line$lineno>$c<\/a>/"
+               else
+                       echo "$l"
+               fi
+       fi
+done | sed 's/^/<br\/>/'
+}
+
+for file in `find $LT/out/ | grep replay/last_crash_sec`
+do
+ echo last_crash_sec file: $file
+ SEC=`cat $file`
+ echo SEC $SEC
+ f_base=`echo $file | sed s/last_crash_sec/$SEC/g`
+ NUM_KEYCODES=`wc -l < "$f_base.KEYCODEpure"`
+ echo NUM_KEYCODES=$NUM_KEYCODES...
+ if [ "$NUM_KEYCODES" -lt 80 ]  
+ then
+  echo f_base $f_base
+  f=$f_base.GDB
   echo $f
   g=$f.short
-  if egrep '([Ii][Nn] .*[:[:alnum:]][:][0-9]*[^0-9]|#0 | signal SIG)' -A9999  <$f >$g
+  #if egrep '([Ii][Nn] .*[:[:alnum:]][:][0-9]*[^0-9]|#0 | signal SIG[^T])' -A9999  <$f >$g
+  egrep '([Ii][Nn] .*[:[:alnum:]][:][0-9]*[^0-9]|#0 | signal SIG[^T])' -A9999  <$f >$g
+  if true
   then
-       #egrep '(([Ii][Nn]|at) .*[:[:alnum:]][:][0-9]*[^0-9]|#0 | signal SIG)' -A9999  <$f
-       SEC=`echo $f | sed s/[^[:digit:]]//g`
-       #IN_AT=`egrep -o '([Ii][Nn]|at) ([:lower:]* )[:_[:alnum:]]*(::[:_[:alnum:]]*|:[0-9]*)' <$f | head -n 1  `
-       IN_AT=`egrep -o '([Ii][Nn]|at) ([:lower:]* )?[:_[:alnum:]]*(::[:_[:alnum:]]*|:[0-9]*)' <$f | head -n 1  `
+       IN_AT=`egrep -o '([Ii][Nn]|at) ([:lower:]* )?[:_[:alnum:]]*(::[:_[:alnum:]]*|:[0-9]*)' <$f | grep -v lyx_exit | grep -v [Aa]ssert | head -n 1  `
        SIGNAL=`grep -o ' signal SIG[[:alnum:]_]*[, ]' <$g | sed s/[^[:upper:]]//g | head -n 1`
        TITLE="$SIGNAL $IN_AT"
        TITLE_=`echo $TITLE|sed s/[^[:alnum:]]/_/g`
-       INDEX="index_$TITLE_.html"
+       INDEX="index.html"
        echo TITLE $TITLE
        echo INDEX $INDEX
-       if [ ! -e  $LT/out/$INDEX ]
-       then    
-               echo NEW $INDEX
-               echo '<html>' >> $LT/out/$INDEX
-               echo -n '<a href="'"$INDEX"'">'"$TITLE</a>" >> $OUT/indexreport.html
-               echo '[<a href="'"$SEC.html"'">'1'</a>]<br/>' >> $OUT/indexreport.html
-       else
-               echo exists $INDEX
-       fi
+       echo NEW $INDEX
+       echo '<html>' >> $LT/out/$INDEX
+       echo -n "<a href=\"$SEC.html\">$TITLE</a> " >> $OUT/indexreport.html
+       html_keycode >> $OUT/indexreport.html
+       echo >> $OUT/indexreport.html
        ( echo '<html>'
          echo "<h1>$TITLE</h1>"
-         echo "<img src=$SEC.GDB.png>$TITLE</img>"
-#        head -n 20 $g | txt2html -pi | sed 's/^/<br\/>/' | sed 's/<br\/>$//g'
-         #head -n 20 $g | txt2html -pi | sed 's/^#/#<br\/>/' 
-#        cat $g | txt2html -pi | sed 's/^#/#<br\/>/' 
-         cat $g | sed 's/&/&amp/g' | sed 's/</&lt/g' | sed 's/^/<br\/>/'
+         html_keycode
+         echo "<a href=$SEC.KEYCODE>KEYCODES</a> "
+         echo "<a href=$SEC.GDB>GDB</a><br/>"
+         echo "<a href=$SEC.GDB.png><img src=$SEC.small.png/></a><br/><br/>"
+         gdb2html
        ) > $OUT/$SEC.html
        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/>'
+       if [ ! -e $OUT/$SEC.small.png ]
+       then  
+               convert -normalize -scale $GEOM $f.png $OUT/$SEC.small.png -quality 85
+       fi
+       chmod a+r $f $f.png $f_base.KEYCODE $f_base.html $OUT/indexreport.html
+       ln $f $f.png $f_base.KEYCODE $f_base.html $OUT/
   fi
+ fi
 done
+mv $OUT/indexreport.html $OUT/indexreport.html.bak
+echo "<html>" >> $OUT/indexreport.html
+echo "<h1>List of bugs found</h1>" >> $OUT/indexreport.html
+sort -k 2 -t '>' < $OUT/indexreport.html.bak >> $OUT/indexreport.html
+
+$OUT/
 exit
diff --git a/development/keystest/test.py b/development/keystest/test.py
deleted file mode 100755 (executable)
index 6c695de..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/env python
-#This script generated hundreds of random keypresses per second,
-#  and sends them to the lyx window
-#It requires xvkbd and wmctrl
-#It generates a log of the KEYCODES it sends as development/keystest/out/KEYCODES
-
-import random
-import os 
-
-keycode=["\[Left]",'\[Right]','\[Down]','\[Up]','\[BackSpace]','\[Delete]','\[Escape]']
-keycode[:0]=keycode
-keycode[:0]=keycode
-
-keycode[:0]=['\\']
-
-for k in range(97, 123):
-  keycode[:0]=chr(k)
-
-for k in range(97, 123):
-  keycode[:0]=["\A"+chr(k)]
-
-for k in range(97, 123):
-  keycode[:0]=["\A"+chr(k)]
-
-for k in range(97, 123):
-  keycode[:0]=["\C"+chr(k)]
-
-
-print (keycode[1])
-print(keycode)
-print (random.randint(1,len(keycode)))
-for k in range(97, 123):
-  print (keycode[random.randint(1,len(keycode))-1])
-
-#Start a new file. We could also open a random Help file.
-#os.system("wmctrl -R LyX && xvkbd -xsendevent -text '\Afn';sleep 1")
-keystr="'\Afn'"
-os.system("wmctrl -R LyX && xvkbd -xsendevent -text '"+keystr+"';sleep 1")
-os.system("echo '"+keystr+"'")
-
-while True:
-  keystr=""
-  for k in range(1,80):
-       keystr=keystr+keycode[random.randint(1,len(keycode))-1]
-  #output keystr before using, to make sure it is output before we are killed
-  os.system("echo '"+keystr+"'")
-  os.system("wmctrl -R LyX && xvkbd -xsendevent -text '"+keystr+"';sleep 1")
diff --git a/development/keystest/watch_keytest.sh b/development/keystest/watch_keytest.sh
new file mode 100644 (file)
index 0000000..4b1501e
--- /dev/null
@@ -0,0 +1,47 @@
+
+NOW_SEC=`date +%s`
+echo NOW_SEC $NOW_SEC 
+echo recently modified files:
+LATEST_FILE=`ls out/* -td -1 | grep -v log  | head -n1`
+echo $LATEST_FILE | (
+ grep replay > /dev/null || (
+       ls out/* -lotd | head
+ )
+)
+ls out/* -tdo -1 | grep replay  
+
+LATEST_FILE=`ls out/* -td -1 | grep replay  | head -n1`
+echo  LATEST_FILE $LATEST_FILE 
+echo $LATEST_FILE | (
+ grep replay > /dev/null && (
+  if [ -e $LATEST_FILE/last_crash_sec ]
+  then
+       ls $LATEST_FILE/*re -lotd | head
+       SEC=`cat $LATEST_FILE/last_crash_sec`
+       echo $SEC $(($NOW_SEC-$SEC))
+       ls -l $LATEST_FILE/$SEC.KEYCODEpure
+       echo `cat $LATEST_FILE/$SEC.KEYCODEpure | sed s/KK:\//g`
+       cat $LATEST_FILE/$SEC.GDB | grep "signal SIG" -A 15
+  else
+       ls $LATEST_FILE -lot | head
+       cat `echo $LATEST_FILE | sed s/KEYCODEpure.replay/GDB/` | grep "signal SIG" -A 9
+  fi
+       cat $LATEST_FILE/log | grep Bore | tail -n2
+ ) || (
+       ls out/* -lotd | head
+ )
+)
+
+
+grep -F "autolyx:
+Trace
+reproduced
+X_PID
+x-session" out/log | grep -v kill | grep -v Terminated | tail -n 9
+exit
+echo autolyx crashes ---------
+grep autolyx: out/log | grep -v kill | grep -v Terminated #-A 5
+echo python crashes ---------
+grep -i Trace out/log -A 5
+echo misc ----
+grep reproduced out/log | tail -n5