1 package gov.nasa.jpf.jvm; 20 21 import gov.nasa.jpf.BootstrapXMLTraceHandler; 22 import gov.nasa.jpf.Config; 23 import gov.nasa.jpf.JPF; 24 import gov.nasa.jpf.JPFException; 25 import gov.nasa.jpf.Path; 26 import gov.nasa.jpf.Transition; 27 import gov.nasa.jpf.VM; 28 import gov.nasa.jpf.VMState; 29 import gov.nasa.jpf.VMListener; 30 import gov.nasa.jpf.VMListenerMulticaster; 31 import gov.nasa.jpf.util.CoverageManager; 32 import gov.nasa.jpf.util.Debug; 33 34 import java.io.File ; 35 import java.io.FileReader ; 36 import java.io.FileNotFoundException ; 37 import java.io.PrintWriter ; 38 import java.io.Reader ; 39 import java.io.Writer ; 40 41 import java.util.HashSet ; 42 import java.util.Stack ; 43 import java.util.StringTokenizer ; 44 45 import org.xml.sax.InputSource ; 46 import org.xml.sax.XMLReader ; 47 import org.xml.sax.helpers.XMLReaderFactory ; 48 49 import gov.nasa.jpf.jvm.bytecode.FieldInstruction; 50 import gov.nasa.jpf.jvm.bytecode.Instruction; 51 import gov.nasa.jpf.jvm.choice.IntIntervalGenerator; 52 53 54 58 public class JVM implements VM { 59 60 64 protected static int error_id; 65 66 69 public static HashSet observablePositions; 70 71 74 public static HashSet observableLabels; 75 76 79 public static HashSet observableInvokes; 80 81 84 public static HashSet observableReturns; 85 86 90 protected static JVM jvm; 91 92 static { 93 initStaticFields(); 94 } 95 96 protected SystemState ss; 97 98 105 106 protected Stack stateStoringStack; 107 108 109 protected Stack stateBacktrackStack; 110 111 112 protected Stack backtrackStack; 113 114 protected String mainClassName; 115 protected String [] args; 116 117 protected Path path; 118 protected StringBuffer out; 119 120 126 private int[] ksStoringData; 127 private Object ksBacktrackData; 128 129 130 private boolean ignoreState; 131 132 136 TrailInfo lastTrailInfo; 137 ClassInfo lastClassInfo; 138 ThreadInfo lastThreadInfo; 139 Instruction lastInstruction; 140 Instruction nextInstruction; 141 ElementInfo lastElementInfo; 142 143 144 StateSet stateSet; 145 146 147 VMListener listener; 148 149 Config config; 151 boolean runGc; 153 boolean checkFP; 154 boolean checkFPcompare; 155 boolean atomicLines; 156 boolean treeOutput; 157 boolean pathOutput; 158 boolean indentOutput; 159 160 166 public JVM (Config conf) throws Config.Exception { 167 jvm = this; 170 171 config = conf; 172 173 runGc = config.getBoolean("vm.gc", true); 174 checkFP = config.getBoolean("vm.check_fp", false); 175 checkFPcompare = config.getBoolean("vm.check_fp_compare", true); 176 atomicLines = config.getBoolean("vm.por.atomic_lines", true); 177 treeOutput = config.getBoolean("vm.tree_output", true); 178 pathOutput = config.getBoolean("vm.path_output", false); 179 indentOutput = config.getBoolean("vm.indent_output",false); 180 181 initSubsystems(config); 182 initFields(config); 183 } 184 185 public void initFields (Config config) throws Config.Exception { 186 ClassInfo ci; 187 188 Scheduler scheduler = null; 193 194 stateSet = (StateSet) config.getInstance("vm.storage.class", StateSet.class); 196 197 String target = config.getTargetArg(); 198 199 if (target.endsWith(".xml")) { 200 if ((new File (target)).exists()) { 201 Path replay = loadPath(target); 203 mainClassName = replay.getApplication(); 204 scheduler = new PathScheduler(replay); 206 Debug.println( Debug.MESSAGE, "replay path: " + target); 207 } else { 208 Debug.println( Debug.ERROR, "tracefile " + target + " not found, exiting"); 209 JPF.exit(); 210 } 211 } else { 212 mainClassName = target; 213 scheduler = (Scheduler) config.getEssentialInstance("vm.scheduler.class", Scheduler.class); 214 } 215 216 args = config.getTargetArgParameters(); 217 218 stateStoringStack = new Stack (); 219 stateBacktrackStack = new Stack (); 220 backtrackStack = new Stack (); 221 path = new Path(mainClassName); 222 out = null; 223 224 ss = new SystemState(config, scheduler); 225 226 if (config.getBoolean("vm.visible_asserts")) { 228 addObservable("invoke.gov.nasa.jpf.jvm.Verify.assertTrue(Z)V"); 229 } 230 231 addListeners(config); 232 } 233 234 void addListeners (Config config) throws Config.Exception { 235 Object [] listeners = config.getInstances("vm.listener", VMListener.class); 236 if (listeners != null) { 237 for (int i=0; i<listeners.length; i++) { 238 addListener( (VMListener) listeners[i]); 239 } 240 } 241 } 242 243 void initSubsystems (Config config) throws Config.Exception { 244 ClassInfo.init(config); 245 ThreadInfo.init(config); 246 DynamicArea.init(config); 247 StaticArea.init(config); 248 NativePeer.init(config); 249 CoverageManager.init(config); 250 TrailInfo.init(config); 251 Step.init(config); 252 FieldInstruction.init(config); 253 JPF_gov_nasa_jpf_jvm_Verify.init(config); 254 } 255 256 263 static boolean checkModelClassAccess () { 264 ClassInfo ci = ClassInfo.getClassInfo("java.lang.Class"); 265 return (ci.getDeclaredInstanceField("cref") != null); 266 } 267 268 269 279 public boolean initialize () { 280 loadStartupClasses(); 286 287 if (!checkModelClassAccess()) { 288 Debug.println(Debug.ERROR, 289 "error during VM runtime initialization: wrong model classes (check vm.[boot]classpath)"); 290 return false; 291 } 292 293 createMainThread(); 300 301 try { 302 initializeStartupClasses(); 308 309 prepareMain(config); 312 prepareMainClinit(config); 313 } catch (UncaughtException ux) { 314 Debug.println(Debug.ERROR, "error during VM runtime initialization:"); 316 Debug.println(Debug.ERROR, ux); 317 return false; 318 } 319 320 return true; 321 } 322 323 public void addListener (VMListener newListener) { 324 listener = VMListenerMulticaster.add(listener, newListener); 325 } 326 327 public void removeListener (VMListener removeListener) { 328 listener = VMListenerMulticaster.remove(listener,removeListener); 329 } 330 331 void notifyInstructionExecuted (ThreadInfo ti, Instruction insn, Instruction nextInsn) { 332 lastThreadInfo = ti; 333 lastInstruction = insn; 334 nextInstruction = nextInsn; 335 if (listener != null) { 336 listener.instructionExecuted(this); 337 } 338 nextInstruction = null; 339 lastInstruction = null; 340 lastThreadInfo = null; 341 } 342 343 void notifyThreadStarted (ThreadInfo ti) { 344 lastThreadInfo = ti; 345 if (listener != null) { 346 listener.threadStarted(this); 347 } 348 lastThreadInfo = null; 349 } 350 351 void notifyThreadTerminated (ThreadInfo ti) { 352 lastThreadInfo = ti; 353 if (listener != null) { 354 listener.threadTerminated(this); 355 } 356 lastThreadInfo = null; 357 } 358 359 void notifyClassLoaded (ClassInfo ci) { 360 lastClassInfo = ci; 361 if (listener != null) { 362 listener.classLoaded(this); 363 } 364 lastClassInfo = null; 365 } 366 367 void notifyObjectCreated (ThreadInfo ti, ElementInfo ei) { 368 lastThreadInfo = ti; 369 lastElementInfo = ei; 370 if (listener != null) { 371 listener.objectCreated(this); 372 } 373 lastElementInfo = null; 374 lastThreadInfo = null; 375 } 376 377 void notifyObjectReleased (ElementInfo ei) { 378 lastElementInfo = ei; 379 if (listener != null) { 380 listener.objectReleased(this); 381 } 382 lastElementInfo = null; 383 } 384 385 void notifyGCBegin () { 386 if (listener != null) { 387 listener.gcBegin(this); 388 } 389 } 390 391 void notifyGCEnd () { 392 if (listener != null) { 393 listener.gcEnd(this); 394 } 395 } 396 397 void notifyExceptionThrown (ThreadInfo ti, ElementInfo ei) { 398 lastThreadInfo = ti; 399 lastElementInfo = ei; 400 if (listener != null) { 401 listener.exceptionThrown(this); 402 } 403 lastElementInfo = null; 404 lastThreadInfo = null; 405 } 406 407 public int getThreadNumber () { 409 if (lastThreadInfo != null) { 410 return lastThreadInfo.getIndex(); 411 } else { 412 return -1; 413 } 414 } 415 416 public String getThreadName () { 418 ThreadInfo ti = ss.getRunningThread(); 419 420 return ti.getName(); 421 } 422 423 Instruction getInstruction () { 425 ThreadInfo ti = ss.getRunningThread(); 426 return ti.getPC(); 427 } 428 429 430 public int getAbstractionNonDeterministicThreadCount () { 431 int n = 0; 432 int imax = ss.getThreadCount(); 433 434 for (int i = 0; i < imax; i++) { 435 ThreadInfo th = ss.getThreadInfo(i); 436 437 if (th.isAbstractionNonDeterministic()) { 438 n++; 439 } 440 } 441 442 return n; 443 } 444 445 public int getAliveThreadCount () { 446 int n = 0; 447 int imax = ss.getThreadCount(); 448 449 for (int i = 0; i < imax; i++) { 450 ThreadInfo th = ss.getThreadInfo(i); 451 452 if (th.isAlive()) { 453 n++; 454 } 455 } 456 457 return n; 458 } 459 460 public ExceptionInfo getPendingException () { 461 return ThreadInfo.current.getPendingException(); 462 } 463 464 public boolean isBoringState () { 465 return ss.getBoring(); 466 } 467 468 public Reference getClassReference (String name) { 469 if (ClassInfo.exists(name)) { 470 return ss.ks.sa.get(name); 471 } 472 473 return null; 474 } 475 476 public boolean hasPendingException () { 477 return (ThreadInfo.current.pendingException != null); 478 } 479 480 public boolean isDeadlocked () { 481 int length = ss.getThreadCount(); 482 boolean result = false; 483 484 for (int i = 0; i < length; i++) { 485 ThreadInfo th = (ThreadInfo) ss.getThreadInfo(i); 486 487 if (th.isRunnable()) { 489 return false; 490 } 491 492 if (th.countStackFrames() != 0) { 495 result = true; 496 } 497 } 498 499 return result; 500 } 501 502 public boolean isEndState () { 503 return ss.isEndState(); 506 } 507 508 public Exception getException () { 509 return ss.getUncaughtException(); 510 } 511 512 public boolean isInterestingState () { 513 return ss.getInteresting(); 514 } 515 516 public Step getLastStep () { 517 TrailInfo trail = ss.trail(); 518 if (trail != null) { 519 return trail.getLastStep(); 520 } 521 522 return null; 523 } 524 525 public Transition getLastTransition () { 526 if (path.length() == 0) { 527 return null; 528 } 529 return path.get(path.length() - 1); 530 } 531 532 537 public ClassInfo getLastClassInfo () { 538 return lastClassInfo; 539 } 540 541 546 public ThreadInfo getLastThreadInfo () { 547 return lastThreadInfo; 548 } 549 550 555 public Instruction getLastInstruction () { 556 return lastInstruction; 557 } 558 559 564 public Instruction getNextInstruction () { 565 return nextInstruction; 566 } 567 568 573 public ElementInfo getLastElementInfo () { 574 return lastElementInfo; 575 } 576 577 581 public ClassInfo getClassInfo () { 582 return lastClassInfo; 583 } 584 585 public String getMainClassName () { 586 return mainClassName; 587 } 588 589 public String [] getArgs () { 590 return args; 591 } 592 593 public void setPath (Path p) { 594 } 595 596 public Path getPath () { 597 return (Path) path.clone(); 598 } 599 600 public int getPathLength () { 601 return path.length(); 602 } 603 604 public Reference getReference (String name) { 605 StringTokenizer st = new StringTokenizer (name, "."); 607 StringBuffer sb = new StringBuffer (); 608 Reference r = null; 609 610 while (st.hasMoreTokens()) { 611 sb.append(st.nextToken()); 612 613 if ((r = getClassReference(sb.toString())) != null) { 614 break; 615 } 616 617 sb.append('.'); 618 } 619 620 if (r == null) { 621 throw new JPFException("invalid argument: " + name); 622 } 623 624 while (st.hasMoreTokens()) { 626 r = r.getObjectField(st.nextToken(), sb.toString()); 627 } 628 629 return r; 630 } 631 632 public VMState getRestorableForwardState () { 633 JVMState state = new JVMState(); 634 state.makeForwardRestorable(); 635 636 return state; 637 } 638 639 public int getRunnableThreadCount () { 640 return ss.getRunnableThreadCount(); 641 } 642 643 public boolean checkFP () { 644 return checkFP; 645 } 646 647 public boolean checkNaN (double r) { 648 if (checkFP) { 649 return !(Double.isNaN(r) || Double.isInfinite(r)); 650 } else { 651 return true; 652 } 653 } 654 655 public boolean checkNaN (float r) { 656 if (checkFP) { 657 return !(Float.isNaN(r) || Float.isInfinite(r)); 658 } else { 659 return true; 660 } 661 } 662 663 public boolean checkNaNcompare (float r1, float r2) { 664 if (checkFPcompare) { 665 return !(Float.isNaN(r1) || Float.isNaN(r2) || 666 (Float.isInfinite(r1) && Float.isInfinite(r2) && (r1 == r2))); 667 } else { 668 return true; 669 } 670 } 671 672 public boolean checkNaNcompare (double r1, double r2) { 673 if (checkFPcompare) { 674 return !(Double.isNaN(r1) || Double.isNaN(r2) || 675 (Double.isInfinite(r1) && Double.isInfinite(r2) && (r1 == r2))); 676 } else { 677 return true; 678 } 679 } 680 681 684 public VMState getState () { 685 return (new JVMState()); 686 } 687 688 691 public SystemState getSystemState () { 692 return ss; 693 } 694 695 public KernelState getKernelState () { 696 return ss.ks; 697 } 698 699 702 public ChoiceGenerator getChoiceGenerator () { 703 return ss.getChoiceGenerator(); 704 } 705 706 708 protected final Class [] cgArgTypes = { Config.class, String .class }; 710 protected Object [] cgArgs = { null, null }; 712 713 public BooleanChoiceGenerator createBooleanChoiceGenerator () { 715 BooleanChoiceGenerator gen = new BooleanChoiceGenerator(config, "boolean"); 716 gen.advance(this); ss.setChoiceGenerator(gen); 718 return gen; 719 } 720 721 public IntChoiceGenerator createIntChoiceGenerator (int min, int max) { 722 IntIntervalGenerator gen = new IntIntervalGenerator(min,max); 723 gen.advance(this); ss.setChoiceGenerator(gen); 725 return gen; 726 } 727 728 public ChoiceGenerator createChoiceGenerator (String id) { 730 ChoiceGenerator gen = null; 731 732 cgArgs[0] = config; 733 cgArgs[1] = id; 735 try { 736 String key = id + ".class"; 737 gen = (ChoiceGenerator)config.getEssentialInstance(key, ChoiceGenerator.class, 738 cgArgTypes, cgArgs); 739 gen.advance(this); ss.setChoiceGenerator(gen); 741 } catch (Config.Exception cex) { 742 throw new JPFException(cex); 744 } 745 746 return gen; 747 } 748 749 750 public boolean isTerminated () { 751 return ss.ks.isTerminated(); 752 } 753 754 public void print (String s) { 755 if (treeOutput) { 756 System.out.print(s); 757 } 758 759 if (pathOutput) { 760 appendOutput(s); 761 } 762 } 763 764 public void println (String s) { 765 if (treeOutput) { 766 if (indentOutput){ 767 StringBuffer indent = new StringBuffer (); 768 int i; 769 for (i = 0;i<=path.length();i++) { 770 indent.append("|" + i); 771 } 772 System.out.println(indent + "|" +s); 773 } 774 else { 775 System.out.println(s); 776 } 777 } 778 779 if (pathOutput) { 780 appendOutput(s); 781 appendOutput('\n'); 782 } 783 } 784 785 public void print (boolean b) { 786 if (treeOutput) { 787 System.out.print(b); 788 } 789 790 if (pathOutput) { 791 appendOutput(Boolean.toString(b)); 792 } 793 } 794 795 public void print (char c) { 796 if (treeOutput) { 797 System.out.print(c); 798 } 799 800 if (pathOutput) { 801 appendOutput(c); 802 } 803 } 804 805 public void print (int i) { 806 if (treeOutput) { 807 System.out.print(i); 808 } 809 810 if (pathOutput) { 811 appendOutput(Integer.toString(i)); 812 } 813 } 814 815 public void print (long l) { 816 if (treeOutput) { 817 System.out.print(l); 818 } 819 820 if (pathOutput) { 821 appendOutput(Long.toString(l)); 822 } 823 } 824 825 public void print (double d) { 826 if (treeOutput) { 827 System.out.print(d); 828 } 829 830 if (pathOutput) { 831 appendOutput(Double.toString(d)); 832 } 833 } 834 835 public void print (float f) { 836 if (treeOutput) { 837 System.out.print(f); 838 } 839 840 if (pathOutput) { 841 appendOutput(Float.toString(f)); 842 } 843 } 844 845 public void println () { 846 if (treeOutput) { 847 System.out.println(); 848 } 849 850 if (pathOutput) { 851 appendOutput('\n'); 852 } 853 } 854 855 856 void appendOutput (String s) { 857 if (out == null) { 858 out = new StringBuffer (); 859 } 860 out.append(s); 861 } 862 863 void appendOutput (char c) { 864 if (out == null) { 865 out = new StringBuffer (); 866 } 867 out.append(c); 868 } 869 870 873 public void printResults (PrintWriter pw) { 874 if (config.getBoolean("vm.report.printStacks")) { 875 pw.println("------------------------------------ thread stacks"); 876 printStackTraces(pw); 877 pw.println("------------------------------------ end thread stacks"); 878 } 879 } 880 881 public void printStackTraces (PrintWriter pw) { 882 int imax = ss.getThreadCount(); 883 884 for (int i = 0; i < imax; i++) { 885 ThreadInfo ti = ss.getThreadInfo(i); 886 String [] cs = ti.getCallStack(); 887 888 if (cs.length > 0) { 889 pw.print("Thread: "); 890 pw.println(ti.getName()); 891 for (int j=cs.length-1; j >= 0; j--) { 892 pw.println(cs[j]); 893 } 894 pw.println(); 895 } 896 } 897 } 898 899 void backtrackKernelState () { 900 ksStoringData = (int[]) stateStoringStack.pop(); 901 ksBacktrackData = stateBacktrackStack.pop(); 902 903 ss.ks.backtrackTo(new ArrayOffset(ksStoringData), ksBacktrackData); 904 } 905 906 void backtrackSystemState () { 907 ss.backtrackTo(null, backtrackStack.pop()); 908 } 909 910 917 public boolean backtrack () { 918 if (!backtrackStack.isEmpty()) { 919 backtrackKernelState(); 921 922 backtrackSystemState(); 924 925 path.removeLast(); 927 lastTrailInfo = (TrailInfo) path.getLast(); 928 929 return ((ss.getId() != StateSet.UNKNOWN_ID) || (stateSet == null)); 930 } else { 931 return false; 932 } 933 } 934 935 private void cacheKernelState () { 936 ksStoringData = ss.ks.getStoringData(); 937 ksBacktrackData = ss.ks.getBacktrackData(); 938 } 939 940 private void resetKernelStateCache () { 941 ksStoringData = null; 942 ksBacktrackData = null; 943 } 944 945 private boolean tryAgain () { 946 backtrackKernelState(); 947 ss.scheduleNext(this); 948 949 return forward(); 951 } 952 953 958 void updatePath () { 959 Transition t = ss.trail(); 960 961 964 if ((out != null) && (out.length() > 0)) { 966 t.setOutput( out.toString()); 967 out.setLength(0); 968 } 969 970 path.add(t); 971 } 972 973 982 public boolean forward () { 983 boolean isNewState = true; 984 ignoreState = false; 985 986 try { 987 pushKernelState(); 991 992 lastTrailInfo = (TrailInfo) path.getLast(); 994 995 if (ss.nextSuccessor(this)) { 998 if (runGc && !hasPendingException()) { 1005 ss.gcIfNeeded(); 1006 } 1007 1008 ss.scheduleNext(this); 1010 1011 ss.checkNext(this); 1013 1014 pushSystemState(); 1018 1019 updatePath(); 1020 1021 ss.prepareNext(this); 1023 1024 } else { popKernelState(); 1026 return false; 1027 } 1028 1029 } catch (BlockedAtomicException e) { return tryAgain(); 1031 } catch (IgnoreIfException e) { return tryAgain(); 1033 } catch (UncaughtException e) { 1036 updatePath(); return true; 1039 } catch (RuntimeException e) { 1040 throw new JPFException(e); 1041 } 1042 1043 if (stateSet != null) { 1044 int id = stateSet.add(ss); 1045 ss.setId(id); 1046 isNewState = stateSet.isNewState(id); 1047 } 1048 1049 cacheKernelState(); 1056 return true; 1057 } 1058 1059 1064 public Path loadPath (String fname) { 1065 try { 1066 Reader r = new FileReader (fname); 1067 1068 XMLReader parser = XMLReaderFactory.createXMLReader( 1069 "org.apache.xerces.parsers.SAXParser"); 1070 BootstrapXMLTraceHandler handler = new BootstrapXMLTraceHandler(); 1071 parser.setContentHandler(handler); 1072 parser.parse(new InputSource (r)); 1073 1074 return handler.getPath(); 1075 } catch (FileNotFoundException e) { 1076 throw new JPFException(fname + ": file not found"); 1077 } catch (Throwable x) { 1078 throw new JPFException("cannot load path " + fname + " : " + x); 1079 } 1080 } 1081 1082 public void popKernelState () { 1083 stateStoringStack.pop(); 1084 stateBacktrackStack.pop(); 1085 } 1086 1087 public void printStatus () { 1088 Debug.println(Debug.ERROR, "Current status of the virtual machine:"); 1089 printCurrentStackTrace(); 1090 1091 Debug.println(Debug.ERROR, "Current execution path:"); 1093 Debug.println(Debug.ERROR, getPath()); 1094 } 1096 1097 1100 public void printCurrentStackTrace () { 1101 ThreadInfo th = ss.getRunningThread(); 1102 1103 if (th != null) { 1104 th.printStackTrace(); 1105 } 1106 } 1107 1108 1111 public void pushKernelState () { 1112 int[] ksSD; 1113 1114 if (ksStoringData == null) { 1116 ksSD = ss.ks.getStoringData(); 1117 } else { 1118 ksSD = ksStoringData; 1119 } 1120 1121 stateStoringStack.push(ksSD); 1122 1123 Object ksBD; 1124 1125 if (ksBacktrackData == null) { 1126 ksBD = ss.ks.getBacktrackData(); 1127 } else { 1128 ksBD = ksBacktrackData; 1129 } 1130 1131 stateBacktrackStack.push(ksBD); 1132 } 1133 1134 1137 public void pushSystemState () { 1138 Object ssBD = ss.getBacktrackData(); 1139 backtrackStack.push(ssBD); 1140 } 1141 1142 public void restoreState (VMState st) { 1143 if (st instanceof JVMState) { 1144 JVMState state = (JVMState) st; 1145 1146 if (state.path == null) { 1147 throw new JPFException("tried to restore partial VMState: " + st); 1148 } 1149 1150 1154 stateStoringStack = (state.stateStoringStack != null) ? 1159 (Stack )state.stateStoringStack.clone() : new Stack (); 1160 stateBacktrackStack = (state.stateBacktrackStack != null) ? 1161 (Stack )state.stateBacktrackStack.clone() : new Stack (); 1162 backtrackStack = (state.backtrackStack != null) ? 1163 (Stack )state.backtrackStack.clone() : new Stack (); 1164 1165 1169 ksStoringData = state.ksStoringData; 1170 ksBacktrackData = state.ksBacktrackData; 1171 1172 ss.ks.backtrackTo(new ArrayOffset(ksStoringData), ksBacktrackData); 1173 ss.backtrackTo(null, state.ssBacktrackData); 1174 1175 path = (Path)state.path.clone(); 1176 } else { 1177 throw new JPFException("tried to restore illegal VMState: " + st); 1178 } 1179 } 1180 1181 public void rewind () { 1182 ss.sch.initialize(); 1183 } 1184 1185 public void savePath (Path path, Writer w) { 1186 PrintWriter out = new PrintWriter (w); 1187 int length = path.length(); 1188 1189 TrailInfo.toXML(out, path); 1190 } 1191 1192 1197 public void setIgnoreState (boolean b) { 1198 ignoreState = b; 1199 } 1200 1201 1206 public boolean isNewState() { 1207 if (stateSet != null) { 1208 if (ignoreState){ 1209 return false; 1210 } else { 1211 return stateSet.isNewState(ss.getId()); 1212 } 1213 } else { 1214 return true; 1215 } 1216 } 1217 1218 1223 public int getStateId() { 1224 return ss.getId(); 1225 } 1226 1227 public void addObservable (String observable) { 1229 if (observable.startsWith("invoke.")) { 1230 synchronized (observableInvokes) { 1231 observableInvokes.add(observable.substring(7)); 1232 } 1233 } else if (observable.startsWith("return.")) { 1234 synchronized (observableReturns) { 1235 observableReturns.add(observable.substring(7)); 1236 } 1237 } else if (observable.startsWith("position.")) { 1238 synchronized (observablePositions) { 1239 observablePositions.add(observable.substring(9)); 1240 } 1241 } else if (observable.startsWith("label.")) { 1242 synchronized (observableLabels) { 1243 observableLabels.add(observable.substring(6)); 1244 } 1245 } else { 1246 Debug.println(Debug.ERROR, "Unknown observable: " + observable); 1247 } 1248 } 1249 1250 1254 protected ThreadInfo createMainThread () { 1255 ElementInfo ei; 1256 DynamicArea da = ss.ks.da; 1257 1258 int grpObjref = da.newObject(ClassInfo.getClassInfo("java.lang.ThreadGroup"), 1260 null); 1261 1262 int grpName = da.newString("main", null); 1264 ei = da.get(grpObjref); 1265 ei.setReferenceField("name", grpName); 1266 ei.setIntField("maxPriority", java.lang.Thread.MAX_PRIORITY); 1267 1268 int tObjref = da.newObject(ClassInfo.getClassInfo("java.lang.Thread"), null); 1269 1270 ei = da.get(tObjref); 1271 ei.setReferenceField("group", grpObjref); 1272 ei.setReferenceField("name", da.newString("main", null)); 1273 ei.setIntField("priority", Thread.NORM_PRIORITY); 1274 1275 ThreadInfo ti = new ThreadInfo( this, tObjref); 1279 ti.setPriority(java.lang.Thread.NORM_PRIORITY); 1280 ti.setName("main"); 1281 ti.setStatus(ThreadInfo.RUNNING); 1282 ss.ks.addThread(ti); 1284 return ti; 1285 } 1286 1287 public ThreadInfo createThread (int objRef) { 1288 ThreadInfo ti = new ThreadInfo( this, objRef); 1289 ss.ks.addThread(ti); return ti; 1291 } 1292 1293 void prepareMainClinit(Config config) { 1294 StaticArea sa = getStaticArea(); 1295 ClassInfo ci = ClassInfo.getClassInfo(mainClassName); 1296 1297 while (!sa.containsClass(ci.getName())) { 1300 sa.newUninitializedClass(ci); 1302 1303 MethodInfo mi = ci.getMethod("<clinit>()", false); 1304 ThreadInfo ti = ss.getThreadInfo(0); 1305 1306 if (mi != null) { 1307 StackFrame frame = null; 1308 if (mi.isMJI()) { 1310 mi = mi.createNativeCallStub(); 1311 frame = new StackFrame(mi, true, null); 1312 frame.push(ci.getClassObjectRef(), true); 1313 } else { 1314 frame = new StackFrame(mi, true, null); 1315 } 1316 1317 if (config.getBoolean("vm.atomic_init")) { 1318 mi.setAtomic(true); 1319 } 1320 1321 ti.pushFrame(frame); 1322 } 1323 1324 ci = ci.getSuperClass(); 1325 } 1326 } 1327 1328 void prepareMain (Config config) { 1329 DynamicArea da = ss.ks.da; 1330 ClassInfo ci = ClassInfo.getClassInfo(mainClassName); 1331 MethodInfo mi = ci.getMethod("main([Ljava/lang/String;)", false); 1332 ThreadInfo ti = ss.getThreadInfo(0); 1333 1334 if (mi == null) { 1335 throw new JPFException("no main() method in " + ci.getName()); 1336 } 1337 1338 ti.pushFrame(new StackFrame(mi, false, null)); 1339 ti.setStatus(ThreadInfo.RUNNING); 1340 1341 int argsObjref = da.newArray("Ljava/lang/String;", args.length, null); 1342 ElementInfo argsElement = ss.ks.da.get(argsObjref); 1343 1344 for (int i = 0; i < args.length; i++) { 1345 int stringObjref = da.newString(args[i], null); 1346 argsElement.setElement(i, stringObjref); 1347 } 1348 ti.setLocalVariable(0, argsObjref, true); 1349 } 1350 1351 protected void loadStartupClasses () { 1352 String [] classes = { 1353 "java.lang.Object", 1354 "java.lang.Class", 1355 "java.lang.String", 1356 "java.lang.ThreadGroup", 1357 "java.lang.Thread", 1358 "java.io.PrintStream", 1359 "java.lang.System", 1360 "gov.nasa.jpf.jvm.Verify", 1361 "byte", "[B", 1362 "char", "[C", 1363 "int", "[I", 1364 "long", "[J" 1365 }; 1366 1367 for (int i=0; i<classes.length; i++) { 1368 ClassInfo ci = ClassInfo.getClassInfo(classes[i]); 1369 ss.ks.sa.newStartupClass(ci); 1370 } 1371 } 1372 1373 protected void initializeStartupClasses () { 1374 ss.ks.sa.initializeClasses(); 1375 } 1376 1377 protected void loadClass (ClassInfo ci) { 1378 StaticArea sa = getStaticArea(); 1379 if (!sa.containsClass(ci.getName())) { 1380 sa.newClass(ci); 1381 } 1382 } 1383 1384 static JVM getVM () { 1385 return jvm; 1387 } 1388 1389 1392 static void initStaticFields () { 1393 error_id = 0; 1394 observableInvokes = new HashSet (); 1395 observableLabels = new HashSet (); 1396 observablePositions = new HashSet (); 1397 observableReturns = new HashSet (); 1398 } 1399 1400 1403 public DynamicArea getDynamicArea () { 1404 return ss.ks.da; 1405 } 1406 1407 1410 StaticArea getStaticArea () { 1411 return ss.ks.sa; 1412 } 1413 1414 boolean finalizeObject (ElementInfo ei) { 1415 MethodInfo fin = ei.getClassInfo().getFinalizer(); 1416 1417 if (fin != null) { 1418 ThreadInfo ti = ss.getRunningThread(); 1420 1421 if (ti.countStackFrames() <= 0) { 1427 return false; 1428 } 1429 1430 ti.push(ei.getThisReference(), true); 1431 ti.executeMethod(fin); 1432 } 1433 1434 return true; 1435 } 1436 1437 1438 1444 class JVMState implements VMState { 1445 1446 1451 int[] ksStoringData; 1452 Object ksBacktrackData; 1453 Object ssBacktrackData; 1454 1455 1456 TrailInfo lastTrailInfo; 1457 1458 1463 Path path; 1464 1465 Stack backtrackStack; 1466 Stack stateBacktrackStack; 1467 Stack stateStoringStack; 1468 1469 JVMState () { 1470 ksStoringData = JVM.this.ksStoringData; 1471 ksBacktrackData = JVM.this.ksBacktrackData; 1472 1473 1474 ssBacktrackData = ss.getBacktrackData(); 1478 1479 lastTrailInfo = JVM.this.lastTrailInfo; 1480 } 1481 1482 public Transition getLastTransition () { 1483 return lastTrailInfo; 1484 } 1485 1486 public Path getPath () { 1492 if (path == null) { 1493 path = JVM.this.getPath(); 1494 } 1495 1496 return path; 1497 } 1498 1499 public int getThread () { 1500 return lastTrailInfo.getThread(); 1501 } 1502 1503 1507 public void makeForwardRestorable () { 1508 path = JVM.this.getPath(); 1509 } 1510 1511 public boolean isForwardRestorable() { 1512 return (path != null); 1513 } 1514 1515 1519 public void makeRestorable () { 1520 path = JVM.this.getPath(); 1521 stateBacktrackStack = (Stack )JVM.this.stateBacktrackStack.clone(); 1522 stateStoringStack = (Stack )JVM.this.stateStoringStack.clone(); 1523 backtrackStack = (Stack )JVM.this.backtrackStack.clone(); 1524 } 1525 1526 public boolean isRestorable () { 1527 return (stateBacktrackStack != null); 1528 } 1529 } 1530} 1531 1532 1533 1534 1535 | Popular Tags |