00001 package edu.ksu.cis.bandera.bui.counterexample;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 import java.io.*;
00036 import ca.mcgill.sable.soot.jimple.*;
00037 import edu.ksu.cis.bandera.jext.*;
00038 import ca.mcgill.sable.soot.*;
00039 import edu.ksu.cis.bandera.jjjc.decompiler.*;
00040 import edu.ksu.cis.bandera.annotation.*;
00041 import javax.swing.*;
00042 import javax.swing.tree.*;
00043 import gov.nasa.arc.ase.jpf.*;
00044 import gov.nasa.arc.ase.jpf.jvm.*;
00045 import edu.ksu.cis.bandera.jjjc.*;
00046 import gov.nasa.arc.ase.jpf.jvm.examine.*;
00047 import java.util.*;
00048 import java.lang.reflect.Method;
00049 import edu.ksu.cis.bandera.abstraction.*;
00050 import edu.ksu.cis.bandera.abstraction.typeinference.*;
00051 public class JPFTraceManager implements TraceManager {
00052 private iVirtualMachine vm;
00053 private TypeTable typeTable;
00054 private AnnotationManager am = CompilationManager.getAnnotationManager();
00055 private Hashtable compiledClasses = CompilationManager.getCompiledClasses();
00056 private SootClassManager scm = CompilationManager.getSootClassManager();
00057 private Annotation a;
00058 private Vector threadAnnotations = new Vector();
00059 private Vector threadTreeModels = new Vector();
00060 private gov.nasa.arc.ase.jpf.jvm.examine.State state;
00061 private Hashtable valueNodeValueTable;
00062 private edu.ksu.cis.bandera.annotation.Annotation lastAnn;
00063
00064
00065
00066 public JPFTraceManager(iVirtualMachine vm, TypeTable typeTable) {
00067 this.vm = vm;
00068 this.typeTable = typeTable;
00069 reset();
00070 }
00071
00072
00073
00074 public void back() {
00075 FilenameLinePair flp = vm.ErrorBackward();
00076 int tid = vm.nextThreadToExecute();
00077 try {
00078 a = am.getAnnotation(flp);
00079 } catch (Exception e) {
00080 a = null;
00081 }
00082 System.out.println(flp + ": " + a);
00083 state.newState();
00084 threadAnnotations.setSize(state.numOfThreads());
00085 threadTreeModels.setSize(state.numOfThreads());
00086 threadAnnotations.setElementAt(a, tid);
00087 }
00088
00089
00090
00091 public void cleanup() {
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 }
00105
00106
00107
00108 private boolean deleteDirectory(File dir) {
00109 File[] files = dir.listFiles();
00110 for (int i = 0; i < files.length; i++) {
00111 if (files[i].isDirectory()) {
00112 if (!deleteDirectory(files[i])) return false;
00113 }
00114 if (!files[i].delete()) return false;
00115 }
00116 return true;
00117 }
00118
00119
00120
00121 public void forward() {
00122 lastAnn = a;
00123 FilenameLinePair flp = vm.ErrorForward();
00124 int tid = vm.nextThreadToExecute();
00125 try {
00126 a = am.getAnnotation(flp);
00127 } catch (Exception e) {
00128 a = null;
00129 }
00130 System.out.println(flp + ": " + a);
00131 state.newState();
00132 threadAnnotations.setSize(state.numOfThreads());
00133 threadTreeModels.setSize(state.numOfThreads());
00134 if (tid != -1)
00135 threadAnnotations.setElementAt(a, tid);
00136 }
00137
00138
00139
00140
00141
00142
00143 private String getAbstractToken(Object type, int value) {
00144 String className = type.getClass().getName();
00145 String methodName = "getToken";
00146 try {
00147 Class cls = Class.forName(className);
00148 Method mtd = cls.getMethod(methodName, new Class[] {int.class});
00149 return (String) mtd.invoke(null, new Object[] {new Integer(value)});
00150 } catch (Exception e) {
00151 return "" + value;
00152 }
00153 }
00154
00155
00156
00157 public edu.ksu.cis.bandera.annotation.Annotation getAnnotation() {
00158 return a;
00159 }
00160
00161
00162
00163
00164
00165 public Annotation getAnnotation(int threadID) {
00166 return (Annotation) threadAnnotations.elementAt(threadID);
00167 }
00168
00169
00170
00171
00172 public int getNumOfSteps() {
00173 return vm.ErrorPathLength();
00174 }
00175
00176
00177
00178
00179 public Vector getThreadTreeModels() {
00180 return threadTreeModels;
00181 }
00182
00183
00184
00185
00186
00187
00188 public String getValueText(DefaultTreeModel model, DefaultMutableTreeNode node) {
00189 if (!(node.getUserObject() instanceof ValueNode)) return "";
00190
00191 ValueNode vn = (ValueNode) node.getUserObject();
00192 Object iv = valueNodeValueTable.get(vn);
00193 if (iv == null) return "null";
00194 if ("null".equals("" + iv)) return "null";
00195 if ((iv instanceof ArrayValue) && (node.getChildCount() == 0)) {
00196 ArrayValue v = (ArrayValue) iv;
00197 int size = v.getSize();
00198 for (int i = 0; i < size; i++) {
00199 ValueNode vNode = new ValueNode(v, i);
00200 model.insertNodeInto(new DefaultMutableTreeNode(vNode), node, node.getChildCount());
00201 valueNodeValueTable.put(vNode, v.getElementValue(i));
00202 }
00203 } else if ((iv instanceof ObjectValue) && (node.getChildCount() == 0)) {
00204 ObjectValue v = (ObjectValue) iv;
00205 SootClass sc = scm.getClass(v.getTypeName());
00206 for (ca.mcgill.sable.util.Iterator i = sc.getFields().iterator(); i.hasNext();) {
00207 SootField sf = (SootField) i.next();
00208 ValueNode vNode = new ValueNode(sf);
00209 model.insertNodeInto(new DefaultMutableTreeNode(vNode), node, node.getChildCount());
00210 valueNodeValueTable.put(vNode, v.getFieldValue(sf.getName()));
00211 }
00212 }
00213
00214 return iv.toString();
00215 }
00216
00217
00218
00219 public javax.swing.tree.TreeModel getVariableTreeModel() {
00220 valueNodeValueTable = new Hashtable();
00221
00222 DefaultMutableTreeNode root = new DefaultMutableTreeNode("Store");
00223
00224 for (Enumeration e = compiledClasses.elements(); e.hasMoreElements();) {
00225 SootClass sc = (SootClass) e.nextElement();
00226 if (!state.isLoaded(sc.getName())) continue;
00227 for (ca.mcgill.sable.util.Iterator i = sc.getFields().iterator(); i.hasNext();) {
00228 SootField sf = (SootField) i.next();
00229 if (Modifier.isStatic(sf.getModifiers())) {
00230 ValueNode vn = new ValueNode(sf);
00231 Object o = state.getStaticFieldValue(sf.getDeclaringClass().getName(), sf.getName());
00232 Object t = typeTable.get(sf);
00233 if ((t != null) && (t instanceof IntegralAbstraction) && !(t instanceof ConcreteIntegralAbstraction)) {
00234 if (o instanceof IntValue) {
00235 o = getAbstractToken(typeTable.get(sf), ((IntValue) o).getValue());
00236 } else if (o instanceof ShortValue) {
00237 o = getAbstractToken(typeTable.get(sf), ((ShortValue) o).getValue());
00238 }
00239 }
00240 valueNodeValueTable.put(vn, o);
00241 root.add(new DefaultMutableTreeNode(vn));
00242 }
00243 }
00244 }
00245
00246 Jimple jimple = Jimple.v();
00247
00248 for (int i = 0; i < threadAnnotations.size(); i++) {
00249 threadTreeModels.setElementAt(null, i);
00250 if (!state.isActive(i)) continue;
00251 Annotation a = (Annotation) threadAnnotations.elementAt(i);
00252 if (a == null) continue;
00253 Annotation ta = am.getMethodAnnotationContainingAnnotation(a);
00254 if ((a instanceof MethodDeclarationAnnotation)
00255 || (a instanceof ConstructorDeclarationAnnotation)
00256 || (a instanceof FieldDeclarationAnnotation)
00257 || (a instanceof ClassDeclarationAnnotation))
00258 ta = a;
00259 Hashtable locals = a.getDeclaredLocalVariables();
00260 SootMethod sm;
00261 if (ta instanceof MethodDeclarationAnnotation) {
00262 sm = ((MethodDeclarationAnnotation) ta).getSootMethod();
00263 Hashtable parameters = ((MethodDeclarationAnnotation) ta).getParameterLocals();
00264 for (Enumeration e = parameters.keys(); e.hasMoreElements();) {
00265 Object key = e.nextElement();
00266 locals.put(key, parameters.get(key));
00267 }
00268 } else if (ta instanceof ConstructorDeclarationAnnotation) {
00269 sm = ((ConstructorDeclarationAnnotation) ta).getSootMethod();
00270 Hashtable parameters = ((ConstructorDeclarationAnnotation) ta).getParameterLocals();
00271 for (Enumeration e = parameters.keys(); e.hasMoreElements();) {
00272 Object key = e.nextElement();
00273 locals.put(key, parameters.get(key));
00274 }
00275 } else {
00276 DefaultMutableTreeNode node = new DefaultMutableTreeNode("Thread<no information available>, ID: " + i);
00277 root.add(node);
00278 threadTreeModels.setElementAt(new DefaultTreeModel(node), i);
00279 continue;
00280 }
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 iMethodState ms = state.getMethodState(i);
00292 DefaultMutableTreeNode mNode = new DefaultMutableTreeNode(new ValueNode(sm, i));
00293 if (!Modifier.isStatic(sm.getModifiers())) {
00294 ValueNode vn = new ValueNode(((JimpleBody) sm.getBody(jimple)).getLocal("JJJCTEMP$0"));
00295 mNode.add(new DefaultMutableTreeNode(vn));
00296 valueNodeValueTable.put(vn, ms.getLocalValue("this"));
00297 }
00298 for (Enumeration e = locals.elements(); e.hasMoreElements();) {
00299 Local lcl = (Local) e.nextElement();
00300 try {
00301 ValueNode vn = new ValueNode(lcl);
00302 mNode.add(new DefaultMutableTreeNode(vn));
00303 Object o = ms.getLocalValue(lcl.getName());
00304 Object t = typeTable.get(lcl);
00305 if ((t != null) && (t instanceof IntegralAbstraction) && !(t instanceof ConcreteIntegralAbstraction)) {
00306 if (o instanceof IntValue) {
00307 o = getAbstractToken(typeTable.get(lcl), ((IntValue) o).getValue());
00308 } else if (o instanceof ShortValue) {
00309 o = getAbstractToken(typeTable.get(lcl), ((ShortValue) o).getValue());
00310 }
00311 }
00312 valueNodeValueTable.put(vn, o);
00313 } catch (Exception ex) {
00314 ex.printStackTrace();
00315 }
00316 }
00317 root.add(mNode);
00318 threadTreeModels.setElementAt(new DefaultTreeModel(mNode), i);
00319 }
00320
00321 return new DefaultTreeModel(root);
00322 }
00323
00324
00325
00326
00327
00328 public boolean isAlive(int threadID) {
00329 return state.isActive(threadID);
00330 }
00331
00332
00333
00334 public void reset() {
00335 FilenameLinePair flp = vm.ErrorInit();
00336 try {
00337 a = am.getAnnotation(flp);
00338 } catch (Exception e) {
00339 a = null;
00340 }
00341 System.out.println(flp + ": " + a);
00342
00343 if (state == null)
00344 state = new gov.nasa.arc.ase.jpf.jvm.examine.State();
00345 else
00346 state.newState();
00347 threadAnnotations.setSize(state.numOfThreads());
00348 threadTreeModels.setSize(state.numOfThreads());
00349 threadAnnotations.setElementAt(a, 0);
00350 }
00351 }