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

JimpleTrace.java

00001 package edu.ksu.cis.bandera.birc;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Bandera, a Java(TM) analysis and transformation toolkit           *
00005  * Copyright (C) 1998, 1999   James Corbett (corbett@hawaii.edu)     *
00006  * All rights reserved.                                              *
00007  *                                                                   *
00008  * This work was done as a project in the SAnToS Laboratory,         *
00009  * Department of Computing and Information Sciences, Kansas State    *
00010  * University, USA (http://www.cis.ksu.edu/santos).                  *
00011  * It is understood that any modification not identified as such is  *
00012  * not covered by the preceding statement.                           *
00013  *                                                                   *
00014  * This work is free software; you can redistribute it and/or        *
00015  * modify it under the terms of the GNU Library General Public       *
00016  * License as published by the Free Software Foundation; either      *
00017  * version 2 of the License, or (at your option) any later version.  *
00018  *                                                                   *
00019  * This work is distributed in the hope that it will be useful,      *
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *
00022  * Library General Public License for more details.                  *
00023  *                                                                   *
00024  * You should have received a copy of the GNU Library General Public *
00025  * License along with this toolkit; if not, write to the             *
00026  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,      *
00027  * Boston, MA  02111-1307, USA.                                      *
00028  *                                                                   *
00029  * Java is a trademark of Sun Microsystems, Inc.                     *
00030  *                                                                   *
00031  * To submit a bug report, send a comment, or get the latest news on *
00032  * this project and other SAnToS projects, please visit the web-site *
00033  *                http://www.cis.ksu.edu/santos                      *
00034  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00035 import edu.ksu.cis.bandera.bir.BirTrace;
00036 import edu.ksu.cis.bandera.bir.BirState;
00037 import edu.ksu.cis.bandera.bir.TransSystem;
00038 import edu.ksu.cis.bandera.bir.Transformation;
00039 import edu.ksu.cis.bandera.bir.TransVector;
00040 import edu.ksu.cis.bandera.bir.Action;
00041 import edu.ksu.cis.bandera.bir.ActionVector;
00042 
00043 import ca.mcgill.sable.util.*;
00044 import ca.mcgill.sable.soot.*;
00045 import ca.mcgill.sable.soot.jimple.*;
00046 
00047 import java.io.*;
00048 import java.util.*;
00049 
00050 /**
00051  * A JimpleTrace is either a sequence of Jimple Stmt's, possibly followed
00052  * by a Stmt causing a trap (and the name of the trap), an indication
00053  * of an incomplete model check (e.g., due to insufficient memory), an
00054  * indication of a model resource limit violation, or simply
00055  * a token indicating the property was verified.
00056  * <p>
00057  * This class can be used to map the output of a verifier (once
00058  * interpreted as a sequence of transformations) back to a sequence
00059  * of actions in the Jimple.
00060  */
00061 
00062 public class JimpleTrace {
00063 
00064     boolean verified;              // Property verified (no counterexample)
00065     boolean completed;    
00066     boolean limitviolation;
00067         boolean outofmemory;        // verifier out of memory
00068         boolean depthexceeded;        // verifier overran search depth
00069         boolean vectorexceeded;        // verifier overran state width
00070     Stmt [] stmts;                 // Stmts of counterexample
00071     String trapName;               // Name of trap (or null)
00072     Stmt trapStmt;                 // Stmt causing trap
00073     TransSystem system; 
00074     BirTrace birTrace;             // BIR trace from which constructed
00075     Hashtable threadOfStmt = new Hashtable();     // Maps Stmt -> threadName
00076 
00077     /**
00078      * Maps Stmt index to state index in trace.
00079      * <p>
00080      * The BIR trace is a sequence of BIR transformations, each of which
00081      * may contain several actions, and not all actions map back to
00082      * Jimple Stmts.  The BIR trace contains a BirState for each action
00083      * index (i.e., a starting BirState, and the BirState after each
00084      * action in the BirTrace).  We must be able to retrieve the
00085      * BirState for a given Jimple Stmt in the trace.
00086      * <p>
00087      * The stateIndex array maintains this mapping.  The element
00088      * stateIndex[jimpleStmtNum] gives the index of the BirState
00089      * of the system in the state just *before* the given Jimple
00090      * Stmt is executed.  For example, suppose the BIR trace
00091      * contains actions A1,..,A4, but that only A2 and A4 had
00092      * source statements (call them S1 and S2).  Then
00093      * stateIndex[] would be { 0, 2, 4 }.  So stateIndex[1] = 2
00094      * since the state of the system after the first Stmt (S1)
00095      * is the BirState after the second action (A2) is executed.
00096      */
00097 
00098     int [] stateIndex;
00099 
00100 
00101     /** 
00102      * Build a JimpleTrace from a BIR trace.
00103      */
00104 
00105     public JimpleTrace(BirTrace birTrace) {
00106     this.birTrace = birTrace;
00107     Transformation trapTrans = birTrace.getTrapTrans();
00108     Action trapAction = birTrace.getTrapAction();
00109     system = birTrace.getTransSystem();
00110     verified = birTrace.isVerified();
00111     completed = birTrace.isComplete();
00112     limitviolation = birTrace.isLimitViolation();
00113     outofmemory = birTrace.isOutOfMemory();
00114     depthexceeded = birTrace.isDepthExceeded();
00115     vectorexceeded = birTrace.isVectorExceeded();
00116 
00117     if (limitviolation) trapName = birTrace.getTrapName();
00118 
00119     // If the check was complete and free of limit violations,
00120         // but the property was not verified, map the BIR trace actions to  
00121     // their Jimple Stmt sources to build a Jimple trace
00122     if (completed && !limitviolation && !verified && !outofmemory && !depthexceeded && !vectorexceeded) {
00123         TransVector transVector = birTrace.getTransVector();
00124         Vector steps = new Vector(transVector.size());
00125         stateIndex = new int[birTrace.getNumActions() + 1];
00126         stateIndex[0] = 0;  // Start state always at 0
00127         int actionCount = 0;
00128         // For each transformation 
00129         for (int i = 0; i < transVector.size(); i++) {
00130         Transformation trans = transVector.elementAt(i);
00131         ActionVector actions = trans.getActions();
00132         String threadName = trans.getFromLoc().getThread().getName();
00133         // For each action of the transformation
00134         for(int j = 0; j < actions.size(); j++) {
00135             Action action = actions.elementAt(j);
00136             actionCount++;
00137             // If the action has a source Stmt, add that to
00138             // the Jimple trace, recording the action count there
00139             Object source = system.getSource(action);
00140             if (source != null) {
00141             steps.addElement(source);
00142             threadOfStmt.put(source,threadName);
00143             stateIndex[steps.size()] = actionCount;
00144             }
00145             if (trapTrans == trans && trapAction == action)
00146             break;   // stop at action that caused trap
00147         }
00148         }
00149 
00150         // Move the trace Stmts into an array
00151         stmts = new Stmt[steps.size()];
00152         for(int i = 0; i < steps.size(); i++) 
00153         stmts[i] = (Stmt) steps.elementAt(i);
00154 
00155         // If BIR trace ended with trap, set trap info in JimpleTrace
00156         if (birTrace.getTrapName() != null) {
00157         trapName = birTrace.getTrapName();
00158         trapStmt = (Stmt) system.getSource(trapAction);
00159         String threadName = 
00160             birTrace.getTrapTrans().getFromLoc().getThread().getName();
00161         threadOfStmt.put(trapStmt,threadName);
00162         }
00163     }
00164     }
00165     // Untested query interface (unused)
00166     String evalExpr(Expr expr, int stmtIndex) {
00167     ExprExtractor extractor = 
00168         new ExprExtractor(system, null, null, null,
00169                   null, new PredicateSet());
00170     expr.apply(extractor);
00171     edu.ksu.cis.bandera.bir.Expr birExpr = 
00172         (edu.ksu.cis.bandera.bir.Expr) extractor.getResult();
00173     return birTrace.evalExpr(birExpr,stateIndex[stmtIndex]);
00174     }
00175     public JimpleStore getLastStore() {
00176     return getStore(stmts.length);
00177     }
00178     /**
00179      * Get Jimple Stmts executed in the trace.
00180      * <p>
00181      * If a Stmt caused a trap, it will be included as the last
00182      * element of this array.
00183      */
00184     public Stmt [] getStatements() { return stmts; }
00185     /**
00186      * Get the store at a particular statement.
00187      * @param stmtIndex the index of the statement (between 0 and the number of
00188      *  statements in the trace)
00189      * @return the JimpleStore representing the variable values just before
00190      * that Stmt (if there are N statements, the store at statement index N
00191      * represents the final state, after all Stmts).
00192      */
00193     public JimpleStore getStore(int stmtIndex) {
00194     BirState state = birTrace.getState(stateIndex[stmtIndex]);
00195     JimpleStore store = new JimpleStore(state);
00196     return store;
00197     }
00198     public TransSystem getTransSystem() { return system; }
00199     /**
00200      * Get the name of the trap (returns null if no trap occurred in trace).
00201      */
00202     public String getTrapName() { return trapName; }
00203     /**
00204      * Get the Stmt that caused the trap (returns null if no trap in trace).
00205      */
00206     public Stmt getTrapStmt() { return trapStmt; }
00207     /**
00208      * Was the failure due to the checker (e.g., out of memory)?
00209      */
00210 
00211         public boolean isComplete() { return completed; }
00212     /**
00213      * Was the failure due to a checker exceeding its depth bound?
00214      */
00215         public boolean isDepthExceeded() { return depthexceeded; }
00216     /**
00217      * Was the failure due to a model resource limit violation?
00218      */
00219 
00220         public boolean isLimitViolation() { return limitviolation; }
00221     /**
00222      * Was the failure due to checker running out of memory?
00223      */
00224         public boolean isOutOfMemory() { return outofmemory; }
00225     /**
00226      * Was the failure due to a checker exceeding its state vector size?
00227      */
00228         public boolean isVectorExceeded() { return vectorexceeded; }
00229     /**
00230      * Was the property verified (i.e., hold on the model)?
00231      */
00232 
00233     public boolean isVerified() { return verified; }
00234     /**
00235      * Format object in field of given width
00236      */
00237 
00238     static String pad(Object o, int width) {
00239     String padding = "                                                   ";
00240     String item = o.toString();
00241     return item + padding.substring(0,width - item.length());
00242     }
00243     public void print() {
00244     print(new PrintWriter(System.out, true),false);
00245     }
00246     /**
00247      * Print a JimpleTrace.
00248      * @param out PrintWriter to send output to
00249      * @param showVars show variable values (if false, only Stmts are 
00250      * displayed)
00251      */
00252     public void print(PrintWriter out, boolean showVars) {
00253     int threadNameSize = 0;
00254     Enumeration e = threadOfStmt.elements();
00255     while (e.hasMoreElements()) {
00256         int size = ((String)e.nextElement()).length();
00257         if (size > threadNameSize)
00258         threadNameSize = size;
00259     }   
00260     if (verified) 
00261         out.println("NO TRACE");
00262     else {
00263         out.println("TRACE OF VIOLATION");
00264         for (int i = 0; i < stmts.length; i++) {
00265         if (showVars)
00266             getStore(i).print();
00267         out.println(pad(threadOfStmt.get(stmts[i]),threadNameSize)
00268                 + "  " + stmts[i]);
00269         }
00270         if (showVars)
00271         getStore(stmts.length).print();
00272         if (trapName != null)
00273         out.println(pad(threadOfStmt.get(trapStmt),threadNameSize)
00274                 + "  " + trapName + " at " + trapStmt);
00275     }
00276     }
00277 }

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