Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

VirtualMachine.java

00001 package gov.nasa.arc.ase.jpf.jvm;
00002 
00003 import gov.nasa.arc.ase.jpf.Engine;
00004 import gov.nasa.arc.ase.jpf.ErrorTrailInterface;
00005 import gov.nasa.arc.ase.jpf.InternalErrorException;
00006 import gov.nasa.arc.ase.jpf.JPF;
00007 import gov.nasa.arc.ase.jpf.JPFErrorException;
00008 import gov.nasa.arc.ase.jpf.Path;
00009 import gov.nasa.arc.ase.jpf.Status;
00010 import gov.nasa.arc.ase.jpf.TransitionResult;
00011 import gov.nasa.arc.ase.jpf.iStore;
00012 import gov.nasa.arc.ase.jpf.iScheduler;
00013 import gov.nasa.arc.ase.jpf.iSystemState;
00014 import gov.nasa.arc.ase.jpf.iThreadInfo;
00015 import gov.nasa.arc.ase.jpf.iTrailInfo;
00016 import gov.nasa.arc.ase.jpf.iVirtualMachine;
00017 import gov.nasa.arc.ase.jpf.jvm.reflection.Reflection;
00018 import gov.nasa.arc.ase.util.Comma;
00019 import gov.nasa.arc.ase.util.Counter;
00020 import gov.nasa.arc.ase.util.Debug;
00021 import gov.nasa.arc.ase.util.Right;
00022 import java.io.BufferedReader;
00023 import java.io.FileOutputStream;
00024 import java.io.FileReader;
00025 import java.io.IOException;
00026 import java.io.InputStreamReader;
00027 import java.io.LineNumberReader;
00028 import java.io.OutputStreamWriter;
00029 import java.io.PrintStream;
00030 import java.io.PrintWriter;
00031 import java.lang.reflect.InvocationTargetException;
00032 import java.lang.reflect.Method;
00033 import java.util.Stack;
00034 import java.util.StringTokenizer;
00035 import java.util.Vector;
00036 //#ifdef BANDERA
00037 import edu.ksu.cis.bandera.jjjc.decompiler.FilenameLinePair;
00038 //#endif BANDERA
00039 //#ifdef DISTRIBUTED || PARALLEL
00040 
00041 //#endif DISTRIBUTED || PARALLEL
00042 //#ifdef JDK11
00043 
00044 //#else JDK11
00045 import java.util.LinkedList;
00046 //#endif JDK11
00047 //#ifdef BUCHI
00048 import gov.nasa.arc.ase.jpf.BuchiSet;
00049 //#ifdef JDK11
00050 
00051 //#else JDK11
00052 import java.util.HashSet;
00053 //#endif JDK11
00054 //#endif BUCHI
00055 //#ifdef JDK11
00056 
00057 //#endif JDK11
00058 
00059 /**
00060  * This class represents the virtual machine. The virtual machine is able to
00061  * move backward and forward one step at a time.
00062  */
00063 public class VirtualMachine implements iVirtualMachine {
00064   /**
00065    * The state of the system.
00066    */
00067   private SystemState ss;
00068 
00069   /**
00070    * State storing information stack.
00071    */
00072   private Stack stateStoringStack;
00073 
00074   /**
00075    * State backtrack information stack.
00076    */
00077   private Stack stateBacktrackStack;
00078 
00079   /**
00080    * Backtrack stack.
00081    */
00082   private Stack backtrackStack;
00083 
00084   /**
00085    * Used to print the max stack depth reached message only once.
00086    */
00087   private boolean maxDepthReached;
00088 
00089   /**
00090    * The name of the main class.
00091    */
00092   private String classname;
00093 
00094   /**
00095    * The arguments to the main class.
00096    */
00097   private String[] args;
00098 
00099   /**
00100    * The path to the error.
00101    */
00102   private JVMPath errorPath;
00103 
00104   /**
00105    * The current position in the error path.
00106    */
00107   private int posInErrorPath;
00108 
00109   /**
00110    * Set to true during path execution.
00111    */
00112   private boolean executingPath;
00113 
00114   /**
00115    * Path to the current position.
00116    */
00117   private LinkedList path;
00118 
00119 //#ifdef BUCHI
00120 
00121   /**
00122    * Set to true at the initial state. Used to simulate
00123    * a transition into the initial state itself.
00124    */
00125   private boolean initialState;
00126 
00127   /**
00128    * Contains the list of the positions which are observable.
00129    */
00130   public static HashSet observablePositions = new HashSet();
00131 
00132   /**
00133    * Contains the list of the labels which are observable.
00134    */
00135   public static HashSet observableLabels = new HashSet();
00136 
00137   /**
00138    * Contains the list of invoke instructions which are observable.
00139    */
00140   public static HashSet observableInvokes = new HashSet();
00141 
00142   /**
00143    * Contains the list of methods whose return instruction are observable.
00144    */
00145   public static HashSet observableReturns = new HashSet();
00146 
00147 //#endif BUCHI
00148 
00149 
00150   /**
00151    * A way to access the options specific to the JVM
00152    * without using a cast.
00153    */
00154   public static JVMOptions options;
00155 
00156   /**
00157    * Thread local version of the system state.
00158    */
00159 //#ifdef BANDERA
00160   private static SystemState xss;
00161 //#else BANDERA
00162 //#ifdef JDK11
00163 
00164 //#else JDK11
00165 
00166 //#endif JDK11
00167 //#endif BANDERA
00168 
00169   /**
00170    * Set of packages where to look for partition
00171    * classes. The first entry is null and it is
00172    * set as the package the main class is defined
00173    * in at run time.
00174    */
00175   private static String[] partitionPath = {
00176     null,
00177     "gov.nasa.arc.ase.jpf.partition",
00178     "gov.nasa.arc.ase.jpf.jvm.partition",
00179   };
00180 
00181   private static BufferedReader br = new BufferedReader(
00182       new InputStreamReader(System.in));
00183 
00184   /**
00185    * Creates a new Virtual Machine.
00186    */  
00187   public VirtualMachine() {
00188   }  
00189   /**
00190    * Moves one step backward.
00191    */
00192   public boolean Backtrack() {
00193     // cannot backtrack if the stack is empty
00194     if(stateStoringStack.empty())
00195       return false;
00196 
00197     // Removes the state from the stack.
00198     Engine.getJPF().store.offStack(ss);
00199 
00200     // restore the state and the system
00201     popState();
00202     popSystem();
00203 
00204 //    System.err.println("Backtrack done");
00205 //    ss.ks.log();
00206 
00207     return true;
00208   }  
00209   public boolean BuchiBacktrack() {
00210     return Backtrack();
00211   }  
00212   public boolean BuchiEvaluate(Method method) {
00213     Object[] args = new Object[1];
00214     args[0] = ss;
00215 
00216     try {
00217       return ((Boolean)method.invoke(null, args)).booleanValue();
00218     } catch(InvocationTargetException e) {
00219       e.printStackTrace();
00220       throw new JPFErrorException("Internal exeception in " + method.getDeclaringClass().getName());
00221     } catch(IllegalAccessException e) {
00222       throw new JPFErrorException("Illegal access to " + method.getDeclaringClass().getName());
00223     }
00224   }  
00225   public boolean BuchiEvaluate(Method method, Object[] arg) {
00226     Object[] args = new Object[arg.length+1];
00227 
00228     args[0] = ss;
00229     for(int i = 0; i < arg.length; i++) {
00230       if(arg[i] instanceof ReferenceWrapper) {
00231     args[i+1] = getReference(arg[i].toString());
00232       } else
00233     args[i+1] = arg[i];
00234     }
00235 
00236     try {
00237       return ((Boolean)method.invoke(null, args)).booleanValue();
00238     } catch(InvocationTargetException e) {
00239       e.printStackTrace();
00240       throw new JPFErrorException("Internal exeception in " + method.getDeclaringClass().getName());
00241     } catch(IllegalAccessException e) {
00242       throw new JPFErrorException("Illegal access to " + method.getDeclaringClass().getName());
00243     }
00244   }  
00245 //#ifdef BUCHI
00246   public int BuchiForward() {
00247     boolean sys_move;
00248     int sd = options.search_depth;
00249 
00250     if(sd != -1
00251     && stateStoringStack.size() >= sd) {
00252       if(!maxDepthReached) {
00253     maxDepthReached = true;
00254     Debug.println(Debug.WARNING, "Max search depth reached");
00255       }
00256 
00257       return TransitionResult.END;
00258     }
00259 
00260     JPF jpf = Engine.getJPF();
00261     Status status = jpf.status;
00262 
00263     if(status.maxStackDepth < path.size())
00264       status.maxStackDepth = path.size();
00265 
00266     pushState();
00267 
00268     if(initialState) {
00269       initialState = false;
00270     } else
00271       if(!ss.nextSuccessor()) {
00272     removeState();
00273 
00274     return TransitionResult.END;
00275       }
00276 
00277     ss.sch.next();
00278     pushSystem();
00279     ss.sch.initialize(ss);
00280 
00281 //#ifdef MARK_N_SWEEP
00282 
00283     if(options.garbage_collection && ss.GCNeeded) {
00284       ss.ks.gc();
00285       ss.GCNeeded = false;
00286     }
00287 
00288 //#endif MARK_N_SWEEP
00289 
00290     if(ss.violatedAssertion || ss.uncaughtException) {
00291       return TransitionResult.NEW | TransitionResult.ERROR;
00292     } else {
00293       return TransitionResult.NEW;
00294     }
00295   }  
00296   public BuchiSet BuchiGet() {
00297     return Engine.getJPF().store.BuchiGet(ss);
00298   }  
00299   public void BuchiInitSch() {
00300     ss.sch.initialize(ss);
00301   }  
00302   public void BuchiObservable(String observable) {
00303     if(observable.startsWith("invoke.")) {
00304       synchronized(observableInvokes) {
00305     observableInvokes.add(observable.substring(7));
00306       }
00307     } else if(observable.startsWith("return.")) {
00308       synchronized(observableReturns) {
00309     observableReturns.add(observable.substring(7));
00310       }
00311     } else if(observable.startsWith("position.")) {
00312       synchronized(observablePositions) {
00313     observablePositions.add(observable.substring(9));
00314       }
00315     } else if(observable.startsWith("label.")) {
00316       synchronized(observableLabels) {
00317     observableLabels.add(observable.substring(6));
00318       }
00319     } else
00320       Debug.println(Debug.ERROR, "Unknown observable: " + observable);
00321   }  
00322   public void BuchiSetState(int buchi_state) {
00323     ((TrailInfo)path.getLast()).setBuchiState(buchi_state);
00324   }  
00325   /**
00326    * Creates a path to the current state.
00327    */
00328   public Path buildPath() {
00329     int s = path.size();
00330 
00331     JVMPath p  = new JVMPath(s);
00332 
00333     for(int index = 0; index < s; index++)
00334       p.set(index, ((TrailInfo)path.get(index)).getEntry());
00335 
00336     return p;
00337   }  
00338   /**
00339    * Moves backward in the error path.
00340    */
00341   public FilenameLinePair ErrorBackward() {
00342     Backtrack();
00343 
00344     posInErrorPath--;
00345 
00346     JVMPathEntry e = errorPath.get(posInErrorPath);
00347 
00348     return new FilenameLinePair(e.file, e.line);
00349   }  
00350   /**
00351    * Moves forward in the simulation.
00352    */
00353   public FilenameLinePair ErrorForward() {
00354     if (posInErrorPath >= errorPath.size())
00355       return null;
00356 
00357     JVMPathEntry e = errorPath.get(posInErrorPath);
00358 
00359     Forward();
00360 
00361     posInErrorPath++;
00362 
00363     if (posInErrorPath >= errorPath.size())
00364       return null;
00365 
00366     e = errorPath.get(posInErrorPath);
00367 
00368     return new FilenameLinePair(e.file, e.line);
00369   }  
00370   /**
00371    * Initializes error simulation.
00372    */
00373   public FilenameLinePair ErrorInit() {
00374     reinit();
00375 
00376     posInErrorPath = 0;
00377 
00378     ss.sch = new PathScheduler(ss, errorPath);
00379 
00380     JVMPathEntry e = errorPath.get(posInErrorPath);
00381 
00382     return new FilenameLinePair(e.file, e.line);
00383   }  
00384   /**
00385    * Length of the erro path.
00386    */
00387   public int ErrorPathLength() {
00388     return errorPath.size();
00389   }  
00390   public boolean executePath(Path p) {
00391     // first_max_stack_reached we need to backtrack to the initial state
00392     int backtrack = p.upCount();
00393     for(int i = 0; i < backtrack; i++)
00394       Backtrack();
00395 
00396     // now we have to execute all the steps in the p
00397     executingPath = true;
00398 
00399     ss.sch = new PathScheduler(ss, (JVMPath)p);
00400 
00401     for(int i = 0; i < p.size(); i++)
00402       Forward();
00403 
00404     executingPath = false;
00405     ss.newScheduler();
00406 
00407     int result = Engine.getJPF().store.put(this);
00408 
00409     return result == iStore.NEW;
00410   }  
00411   public boolean executePath(Path p, Object state) {
00412     // first_max_stack_reached we need to backtrack to the initial state
00413     int backtrack = p.upCount();
00414     for(int i = 0; i < backtrack; i++)
00415       Backtrack();
00416 
00417     // now we have to execute all the steps in the p
00418     executingPath = true;
00419 
00420     ss.sch = new PathScheduler(ss, (JVMPath)p);
00421 
00422     for(int i = 0; i < p.size(); i++)
00423       Forward();
00424 
00425     executingPath = false;
00426     ss.newScheduler();
00427 
00428     int result = Engine.getJPF().store.put(this);
00429 
00430     return result == iStore.NEW;
00431   }  
00432   /**
00433    * Moves one step forward.
00434    */
00435   public int Forward() {
00436     int sd = options.search_depth;
00437 
00438     // checks if the limited depth has been reached.
00439     if(sd != -1
00440     && stateStoringStack.size() >= sd) {
00441       if(!maxDepthReached) {
00442     maxDepthReached = true;
00443     Debug.println(Debug.WARNING, "Max search depth reached");
00444       }
00445 
00446       return TransitionResult.END;
00447     }
00448 
00449     JPF jpf = Engine.getJPF();
00450     Status status = jpf.status;
00451 
00452     if(status.maxStackDepth < path.size())
00453       status.maxStackDepth = path.size();
00454 
00455 //#ifdef STACK_STATS
00456 
00457 //#endif STACK_STATS
00458     
00459 
00460     // saves the current state.
00461     pushState();
00462 
00463     // generated next successor.
00464     if(!ss.nextSuccessor()) {
00465       // saves the backtrack information
00466       removeState();
00467 
00468       // if there is no successors we can be in an exit state,
00469       // in a deadlock, or there are not more executable threads.
00470       return TransitionResult.END;
00471     } else {
00472 //#ifdef MARK_N_SWEEP
00473 
00474       // runs the garbage collector if necessary
00475       if (options.garbage_collection && ss.GCNeeded) {
00476     ss.ks.gc();
00477     ss.GCNeeded = false;
00478       }
00479       
00480 //#endif MARK_N_SWEEP
00481       
00482       // moves the scheduler to the next position
00483       ss.sch.next();
00484 
00485       if(!executingPath && Engine.options.po_reduction) {
00486     int result = jpf.store.check(ss);
00487 
00488     // in stack check proviso
00489     if(ss.sch instanceof POScheduler) {
00490       if(result == iStore.ONSTACK)
00491         ((POScheduler)ss.sch).failedProviso();
00492     }
00493       }
00494       
00495       // saves the backtrack information
00496       pushSystem();
00497 
00498       // clears the scheduler for the new state
00499       ss.sch.initialize(ss);
00500       
00501       if(ss.ks.isIntermediate()) jpf.status.intermediateTransitions++;
00502 
00503       if(ss.violatedAssertion || ss.uncaughtException) {
00504     if(options.no_storing || executingPath || ss.ks.isIntermediate() || jpf.store.put(this) == iStore.NEW)
00505       return TransitionResult.NEW | TransitionResult.ERROR;
00506     else
00507       return TransitionResult.OLD | TransitionResult.ERROR;
00508       } else {
00509     if(options.no_storing || executingPath || ss.ks.isIntermediate() || jpf.store.put(this) == iStore.NEW) {
00510       return TransitionResult.NEW;
00511     }
00512     else
00513       return TransitionResult.OLD;
00514       }
00515     }
00516   }  
00517   public Reference getClassReference(String name) {
00518     if(ClassInfo.exists(name))
00519       return ss.ks.sa.get(name);
00520 
00521     return null;
00522   }  
00523   public String getErrorMessage() {
00524     if(ss.violatedAssertion) return "Assertion violated";
00525     if(ss.uncaughtException) return "Uncaught exception: " + ss.exceptionName;
00526 
00527     return "No error found";
00528   }  
00529   /**
00530    * Create a new error trace.
00531    */
00532   public ErrorTrailInterface getErrorTrail() {
00533     Vector v = new Vector();
00534 
00535     v.addElement("========================");
00536     v.addElement(" *** Path to error: ***");
00537     v.addElement("========================");
00538     
00539     int length = path.size();
00540 
00541     v.addElement("Steps to error: " + length);
00542 
00543     for(int index = 0; index < length; index++)
00544       try {
00545     v.addElement("Step #" + index + " " +
00546         ((TrailInfo)path.get(index)).toString());
00547       } catch(NullPointerException e) {
00548     v.addElement("Step #" + index);
00549       }
00550 
00551     ErrorTrail e = new ErrorTrail(v.size());
00552 
00553     for(int index = 0; index < v.size(); index++)
00554       e.add((String)v.elementAt(index));
00555 
00556     return e;
00557   }  
00558   /**
00559    * Read the error trail and returns a path that can be simulated.
00560    */
00561   public Path getErrorTrail_from_file() {
00562     JVMPath path = null;
00563     String filename = classname + ".error.path";
00564 
00565     try {
00566       LineNumberReader in = new LineNumberReader(
00567       new FileReader(filename));
00568 
00569       StringTokenizer t;
00570       String ln = in.readLine();
00571       if(ln != null) {
00572     t = new StringTokenizer(ln, " :\t\r\n");
00573 
00574     // Size
00575     t.nextToken();
00576     int size = Integer.parseInt(t.nextToken());
00577 
00578     path = new JVMPath(size);
00579 
00580     for(int index = 0; index < size; index++) {
00581       ln = in.readLine();
00582       t = new StringTokenizer(ln, " :\t\r\n");
00583 
00584       // Thread #
00585       t.nextToken();
00586       int thread = Integer.parseInt(t.nextToken());
00587 
00588       // Line #
00589       t.nextToken();
00590       int line = Integer.parseInt(t.nextToken());
00591 
00592       // Class name
00593       t.nextToken();
00594       String classname = t.nextToken();
00595 
00596       // Random #
00597       t.nextToken();
00598       int random = Integer.parseInt(t.nextToken());
00599 
00600       path.set(index, new JVMPathEntry(line, classname, thread, random));
00601     }
00602       }
00603       in.close();
00604     } catch (Exception e) {
00605       throw new JPFErrorException("error reading " + filename);
00606     }
00607 
00608     return path;
00609   }  
00610   public Path getErrorTrail_to_file() {
00611     int length = path.size();
00612 
00613     try {
00614       PrintWriter out = new PrintWriter(
00615       new OutputStreamWriter(
00616         new  FileOutputStream(classname + ".error.path")));
00617 
00618       out.println("Size:" + length);
00619 
00620       for(int i = 0; i < length; i++) {
00621     TrailInfo ti = (TrailInfo)path.get(i);
00622 
00623 
00624     out.println("Thread:" + ti.getThread() + "\t Line:" + ti.getStep(0).line +
00625         "\t Class:" + ti.getStep(0).classname + "\t Random:" + ti.getRandom());
00626       }
00627 
00628       out.close();
00629     } catch (IOException e) {
00630     }
00631 
00632     return getErrorTrail1();
00633   }  
00634   /**
00635    * Returns an error trail.
00636    */
00637   public Path getErrorTrail1() {
00638     int length = path.size();
00639 
00640     errorPath = new JVMPath(length);
00641 
00642     for(int i = 0; i < length; i++) {
00643       TrailInfo ti = (TrailInfo)path.get(i);
00644       errorPath.set(i, ti.getEntry());
00645     }
00646 
00647     return errorPath;
00648   }  
00649   public Path getPath(byte[] p) {
00650     return new JVMPath(p);
00651   }  
00652   public Reference getReference(String name) {
00653     // first of all I have to get to a class
00654     StringTokenizer st = new StringTokenizer(name,  ".");
00655     StringBuffer sb = new StringBuffer();
00656     Reference r = null;
00657 
00658     while(st.hasMoreTokens()) {
00659       sb.append(st.nextToken());
00660       if((r = getClassReference(sb.toString())) != null)
00661     break;
00662       sb.append('.');
00663     }
00664 
00665     if(r == null)
00666       throw new JPFErrorException("invalid argument: " + name);
00667 
00668     // now walk thought the fields
00669     while(st.hasMoreTokens()) {
00670       r = r.getObjectField(st.nextToken());
00671     }
00672 
00673     return r;
00674   }  
00675   /**
00676    * Gets the thread local system state.
00677    */
00678   public static SystemState getSS() {
00679 //#ifdef BANDERA
00680     return xss;
00681 //#else BANDERA
00682 
00683 //#endif BANDERA
00684   }  
00685   public Object getState() {
00686     return ss.clone();
00687   }  
00688   /**
00689    * Gets the system state.
00690    */
00691   public iSystemState getSystemState() {
00692     return ss;
00693   }  
00694   /**
00695    * Initialize the virtual machine. Creates the main thread, passes
00696    * the arguments to the main function and store the initial state.
00697    *
00698    * @param arguments the argument strings
00699    */ 
00700   public void init(String[] arguments) {
00701     if(arguments.length == 0)
00702       throw new JPFErrorException("missing class name");
00703 
00704     classname = arguments[0];
00705     args = new String[arguments.length-1];
00706     System.arraycopy(arguments, 1, args, 0, args.length);
00707     stateStoringStack = new Stack();
00708     stateBacktrackStack = new Stack();
00709     backtrackStack = new Stack();
00710     setSS(ss = new SystemState(this));
00711     maxDepthReached = false;
00712     errorPath = null;
00713     posInErrorPath = 0;
00714     executingPath = false;
00715     path = new LinkedList();
00716 
00717     // load the class information for the main class
00718     ClassInfo ci = ClassInfo.getClassInfo(classname);
00719 
00720     //create static fields and monitor for the class
00721     //also initializes class??
00722     ss.ks.sa.newClass(ci);
00723 
00724     // create the thread for the main class
00725     try {
00726     ci.createMainThread(ss, args);
00727     } catch(RuntimeException e) {
00728       ss.ks.jvmError(e, ss.getRunningThread());
00729     }
00730     
00731     // initializes the classes loaded, including main class
00732     // for which there was already an attempt for initializatio
00733     // above, that was probably not required
00734     ss.ks.sa.initializeClasses();
00735 
00736     // this method is empty, to be used later I guess?
00737     Engine.getJPF().initialized();
00738 
00739 //#ifdef BUCHI
00740 
00741     if(options.buchi == null)
00742 
00743 //#endif BUCHI
00744 
00745       // store the initial state in the hashtable
00746       Engine.getJPF().store.initial(this);
00747 
00748 //#ifdef BUCHI
00749 
00750     else
00751       initialState = true;
00752 
00753 //#endif BUCHI
00754   }  
00755   public boolean isDeadlocked() {
00756     int length = ss.getThreadCount();
00757     boolean result = false;
00758 
00759     for(int i = 0; i < length; i++) {
00760       ThreadInfo th = (ThreadInfo)ss.getThreadInfo(i);
00761       if(th.isRunnable())
00762     return false;
00763       if(th.countStackFrames() != 0)
00764     result = true;
00765     }
00766 
00767     return result;
00768   }  
00769   public boolean isTerminated() {
00770     return ss.ks.isTerminated();
00771   }  
00772   /**
00773    * Returns the identifier of the next thread to be executed.
00774    */
00775   public int nextThreadToExecute() {
00776     if (posInErrorPath >= errorPath.size())
00777       return -1;
00778     
00779     JVMPathEntry e = errorPath.get(posInErrorPath);
00780 
00781     return e.thread;
00782   }  
00783 //#ifdef HEURISTIC
00784 //#ifdef HEURISTIC_DEBUG
00785 
00786 
00787 
00788 //#endif HEURISTIC_DEBUG
00789 
00790 
00791 
00792 
00793 
00794 
00795 
00796 
00797 
00798 
00799 
00800 
00801 
00802 
00803 
00804 
00805 
00806 
00807 
00808 
00809 
00810 
00811 
00812 
00813 
00814 
00815 
00816 
00817 
00818 
00819 
00820 
00821 
00822 
00823 
00824 
00825 
00826 
00827 
00828 
00829 
00830 //#endif HEURISTIC
00831 
00832   /**
00833    * Restore the state and backtracking information.
00834    */
00835   public void popState() {
00836     int[] storing = (int[])stateStoringStack.pop();
00837     ss.ks.backtrackTo(new ArrayOffset(storing),
00838     stateBacktrackStack.pop());
00839   }  
00840   public void popSystem() {
00841     ss.backtrackTo(null, backtrackStack.pop());
00842     path.removeLast();
00843   }  
00844   /**
00845    * Returns the identified of the thread that just executed.
00846    */
00847   public int previousThreadToExecute() {
00848     if (posInErrorPath < 1)
00849       return -1;
00850 
00851     JVMPathEntry e = errorPath.get(posInErrorPath-1);
00852 
00853     return e.thread;
00854   }  
00855 //#endif BANDERA
00856 
00857   /**
00858    * Prints the current stack trace.
00859    */
00860   public void printStackTrace() {
00861     ss.getRunningThread().printStackTrace();
00862   }  
00863   /**
00864    * Saves the state of the system.
00865    */
00866   public void pushState() {
00867     stateStoringStack.push(ss.ks.getStoringData());
00868     stateBacktrackStack.push(ss.ks.getBacktrackData());
00869   }  
00870   /**
00871    * Saves the backtracking information.
00872    */
00873   public void pushSystem() {
00874     backtrackStack.push(ss.getBacktrackData());
00875     path.addLast(ss.ti);
00876     ss.ti = null;
00877   }  
00878   /**
00879    * Reinitializes the virtual machine.
00880    */
00881   public void reinit() {
00882 //#ifdef RACE
00883 
00884 //#endif RACE
00885 //#ifdef !NO_STATIC_SYMMETRY
00886     StaticMap.reset();
00887 //#endif !NO_STATIC_SYMMETRY
00888 //#ifdef !NO_DYNAMIC_SYMMETRY
00889     DynamicMap.reset();
00890 //#endif !NO_DYNAMIC_SYMMETRY
00891 
00892     stateStoringStack = new Stack();
00893     stateBacktrackStack = new Stack();
00894     backtrackStack = new Stack();
00895     setSS(ss = new SystemState(this));
00896     maxDepthReached = false;
00897     posInErrorPath = 0;
00898     executingPath = false;
00899     path = new LinkedList();
00900 
00901     ClassInfo ci = ClassInfo.getClassInfo(classname);
00902     ss.ks.sa.newClass(ci);
00903     ci.createMainThread(ss, args);
00904     ss.ks.sa.initializeClasses();
00905 
00906 //#ifdef BUCHI
00907 
00908     if(options.buchi == null)
00909 
00910 //#endif BUCHI
00911 
00912       Engine.getJPF().store.initial(this);
00913 
00914 //#ifdef BUCHI
00915 
00916     else
00917       initialState = true;
00918 
00919 //#endif BUCHI
00920   }  
00921   public void removeState() {
00922     stateStoringStack.pop();
00923     stateBacktrackStack.pop();
00924   }  
00925 //#endif BUCHI
00926 
00927 //#ifdef DISTRIBUTED || PARALLEL
00928 
00929 
00930 
00931 
00932 
00933 
00934 
00935 
00936 
00937 
00938 
00939 
00940 
00941 
00942 
00943 
00944 
00945 
00946 
00947 
00948 
00949 
00950 
00951 
00952 
00953 
00954 
00955 
00956 
00957 
00958 
00959 
00960 
00961 
00962 
00963 
00964 
00965 
00966 
00967 
00968 
00969 
00970 
00971 
00972 
00973 
00974 
00975 
00976 
00977 
00978 
00979 
00980 
00981 
00982 
00983 
00984 
00985 
00986 
00987 
00988 
00989 
00990 
00991 
00992 
00993 
00994 
00995 
00996 
00997 
00998 
00999 
01000 
01001 
01002 
01003 
01004 
01005 
01006 
01007 
01008 
01009 
01010 
01011 
01012 
01013 
01014 //#endif DISTRIBUTED || PARALLEL
01015 
01016   /**
01017    * Sets the thread local system state.
01018    */
01019   private static void setSS(SystemState ss) {
01020 //#ifdef BANDERA
01021     xss = ss;
01022 //#else BANDERA
01023 
01024 //#endif BANDERA
01025   }  
01026   /**
01027    * Restores the  machine to a state from the heuristic queue.
01028    */
01029   public void setState(Object state) {
01030     ss = (SystemState)((SystemState)state).clone();
01031     ss.vm = this;
01032     setSS(ss);
01033   }  
01034   /**
01035    * Prints and saves the error trace.
01036    */
01037   public void ShowErrorTrail() {
01038     ErrorTrailInterface et = getErrorTrail();
01039 
01040     et.print();
01041 
01042     try{
01043       et.print(new PrintStream(new FileOutputStream("error.trail")));
01044     } catch (IOException e) {
01045     }
01046   }  
01047 //#ifdef BANDERA
01048   /**
01049    * Prints the content of an error trail.
01050    */
01051   public void ShowErrorTrail(Path path) {
01052     reinit();
01053 
01054     for(int i = 0; i < errorPath.size()-1; i++) {
01055       FilenameLinePair pair = ErrorForward();
01056       Debug.println(Debug.WARNING, pair.getFilename() + " " + pair.getLine());
01057     }
01058   }  
01059   public iScheduler xForward(iScheduler sch) {
01060     JPF jpf = Engine.getJPF();
01061     Status status = jpf.status;
01062 
01063     if(sch != null)
01064       ss.sch = (Scheduler)sch;
01065     else
01066       ss.sch.initialize(ss);
01067 
01068     if(!ss.nextSuccessor())
01069       return null;
01070 
01071 //#ifdef MARK_N_SWEEP
01072     if (options.garbage_collection && ss.GCNeeded) {
01073       ss.ks.gc();
01074       ss.GCNeeded = false;
01075     }
01076 //#endif MARK_N_SWEEP
01077 
01078     ss.sch.next();
01079 
01080     sch = (iScheduler)ss.sch.clone();
01081 
01082     ss.sch.initialize(ss);
01083       
01084     return sch;
01085   }  
01086 }

Generated at Thu Feb 7 06:59:15 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001