1 7 34 35 package com.sun.tools.example.debug.tty; 36 37 import com.sun.jdi.*; 38 import com.sun.jdi.connect.Connector; 39 import com.sun.jdi.request.*; 40 import com.sun.tools.example.debug.expr.ExpressionParser; 41 import com.sun.tools.example.debug.expr.ParseException; 42 43 import java.text.*; 44 import java.util.*; 45 import java.io.*; 46 47 class Commands { 48 49 abstract class AsyncExecution { 50 abstract void action(); 51 52 AsyncExecution() { 53 execute(); 54 } 55 56 void execute() { 57 60 final ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo(); 61 final int stackFrame = threadInfo == null? 0 : threadInfo.getCurrentFrameIndex(); 62 Thread thread = new Thread ("asynchronous jdb command") { 63 public void run() { 64 try { 65 action(); 66 } catch (UnsupportedOperationException uoe) { 67 MessageOutput.println("Operation is not supported on the target VM"); 69 } catch (Exception e) { 70 MessageOutput.println("Internal exception during operation:", 71 e.getMessage()); 72 } finally { 73 78 if (threadInfo != null) { 79 ThreadInfo.setCurrentThreadInfo(threadInfo); 80 try { 81 threadInfo.setCurrentFrameIndex(stackFrame); 82 } catch (IncompatibleThreadStateException e) { 83 MessageOutput.println("Current thread isnt suspended."); 84 } catch (ArrayIndexOutOfBoundsException e) { 85 MessageOutput.println("Requested stack frame is no longer active:", 86 new Object []{new Integer (stackFrame)}); 87 } 88 } 89 MessageOutput.printPrompt(); 90 } 91 } 92 }; 93 thread.start(); 94 } 95 } 96 97 Commands() { 98 } 99 100 private Value evaluate(String expr) { 101 Value result = null; 102 ExpressionParser.GetFrame frameGetter = null; 103 try { 104 final ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo(); 105 if ((threadInfo != null) && (threadInfo.getCurrentFrame() != null)) { 106 frameGetter = new ExpressionParser.GetFrame() { 107 public StackFrame get() throws IncompatibleThreadStateException { 108 return threadInfo.getCurrentFrame(); 109 } 110 }; 111 } 112 result = ExpressionParser.evaluate(expr, Env.vm(), frameGetter); 113 } catch (InvocationException ie) { 114 MessageOutput.println("Exception in expression:", 115 ie.exception().referenceType().name()); 116 } catch (Exception ex) { 117 String exMessage = ex.getMessage(); 118 if (exMessage == null) { 119 MessageOutput.printException(exMessage, ex); 120 } else { 121 String s; 122 try { 123 s = MessageOutput.format(exMessage); 124 } catch (MissingResourceException mex) { 125 s = ex.toString(); 126 } 127 MessageOutput.printDirectln(s); } 129 } 130 return result; 131 } 132 133 private String getStringValue() { 134 Value val = null; 135 String valStr = null; 136 try { 137 val = ExpressionParser.getMassagedValue(); 138 valStr = val.toString(); 139 } catch (ParseException e) { 140 String msg = e.getMessage(); 141 if (msg == null) { 142 MessageOutput.printException(msg, e); 143 } else { 144 String s; 145 try { 146 s = MessageOutput.format(msg); 147 } catch (MissingResourceException mex) { 148 s = e.toString(); 149 } 150 MessageOutput.printDirectln(s); 151 } 152 } 153 return valStr; 154 } 155 156 private ThreadInfo doGetThread(String idToken) { 157 ThreadInfo threadInfo = ThreadInfo.getThreadInfo(idToken); 158 if (threadInfo == null) { 159 MessageOutput.println("is not a valid thread id", idToken); 160 } 161 return threadInfo; 162 } 163 164 String typedName(Method method) { 165 StringBuffer buf = new StringBuffer (); 166 buf.append(method.name()); 167 buf.append("("); 168 169 List args = method.argumentTypeNames(); 170 int lastParam = args.size() - 1; 171 for (int ii = 0; ii < lastParam; ii++) { 173 buf.append((String )args.get(ii)); 174 buf.append(", "); 175 } 176 if (lastParam >= 0) { 177 String lastStr = (String )args.get(lastParam); 179 if (method.isVarArgs()) { 180 buf.append(lastStr.substring(0, lastStr.length() - 2)); 182 buf.append("..."); 183 } else { 184 buf.append(lastStr); 185 } 186 } 187 buf.append(")"); 188 return buf.toString(); 189 } 190 191 void commandConnectors(VirtualMachineManager vmm) { 192 Iterator iter = vmm.allConnectors().iterator(); 193 if (iter.hasNext()) { 194 MessageOutput.println("Connectors available"); 195 } 196 while (iter.hasNext()) { 197 Connector cc = (Connector)iter.next(); 198 String transportName = 199 cc.transport() == null ? "null" : cc.transport().name(); 200 MessageOutput.println(); 201 MessageOutput.println("Connector and Transport name", 202 new Object [] {cc.name(), transportName}); 203 MessageOutput.println("Connector description", cc.description()); 204 205 Iterator argIter = cc.defaultArguments().values().iterator(); 206 if (argIter.hasNext()) { 207 while (argIter.hasNext()) { 208 Connector.Argument aa = (Connector.Argument)argIter.next(); 209 MessageOutput.println(); 210 211 boolean requiredArgument = aa.mustSpecify(); 212 if (aa.value() == null || aa.value() == "") { 213 MessageOutput.println(requiredArgument ? 215 "Connector required argument nodefault" : 216 "Connector argument nodefault", aa.name()); 217 } else { 218 MessageOutput.println(requiredArgument ? 219 "Connector required argument default" : 220 "Connector argument default", 221 new Object [] {aa.name(), aa.value()}); 222 } 223 MessageOutput.println("Connector description", aa.description()); 224 225 } 226 } 227 } 228 229 } 230 231 void commandClasses() { 232 List list = Env.vm().allClasses(); 233 234 StringBuffer classList = new StringBuffer (); 235 for (int i = 0 ; i < list.size() ; i++) { 236 ReferenceType refType = (ReferenceType)list.get(i); 237 classList.append(refType.name()); 238 classList.append("\n"); 239 } 240 MessageOutput.print("** classes list **", classList.toString()); 241 } 242 243 void commandClass(StringTokenizer t) { 244 List list = Env.vm().allClasses(); 245 246 if (!t.hasMoreTokens()) { 247 MessageOutput.println("No class specified."); 248 return; 249 } 250 251 String idClass = t.nextToken(); 252 boolean showAll = false; 253 254 if (t.hasMoreTokens()) { 255 if (t.nextToken().toLowerCase().equals("all")) { 256 showAll = true; 257 } else { 258 MessageOutput.println("Invalid option on class command"); 259 return; 260 } 261 } 262 ReferenceType type = Env.getReferenceTypeFromToken(idClass); 263 if (type == null) { 264 MessageOutput.println("is not a valid id or class name", idClass); 265 return; 266 } 267 if (type instanceof ClassType) { 268 ClassType clazz = (ClassType)type; 269 MessageOutput.println("Class:", clazz.name()); 270 271 ClassType superclass = clazz.superclass(); 272 while (superclass != null) { 273 MessageOutput.println("extends:", superclass.name()); 274 superclass = showAll ? superclass.superclass() : null; 275 } 276 277 List interfaces = showAll ? clazz.allInterfaces() 278 : clazz.interfaces(); 279 Iterator iter = interfaces.iterator(); 280 while (iter.hasNext()) { 281 InterfaceType interfaze = (InterfaceType)iter.next(); 282 MessageOutput.println("implements:", interfaze.name()); 283 } 284 285 List subs = clazz.subclasses(); 286 iter = subs.iterator(); 287 while (iter.hasNext()) { 288 ClassType sub = (ClassType)iter.next(); 289 MessageOutput.println("subclass:", sub.name()); 290 } 291 List nested = clazz.nestedTypes(); 292 iter = nested.iterator(); 293 while (iter.hasNext()) { 294 ReferenceType nest = (ReferenceType)iter.next(); 295 MessageOutput.println("nested:", nest.name()); 296 } 297 } else if (type instanceof InterfaceType) { 298 InterfaceType interfaze = (InterfaceType)type; 299 MessageOutput.println("Interface:", interfaze.name()); 300 List supers = interfaze.superinterfaces(); 301 Iterator iter = supers.iterator(); 302 while (iter.hasNext()) { 303 InterfaceType superinterface = (InterfaceType)iter.next(); 304 MessageOutput.println("extends:", superinterface.name()); 305 } 306 List subs = interfaze.subinterfaces(); 307 iter = subs.iterator(); 308 while (iter.hasNext()) { 309 InterfaceType sub = (InterfaceType)iter.next(); 310 MessageOutput.println("subinterface:", sub.name()); 311 } 312 List implementors = interfaze.implementors(); 313 iter = implementors.iterator(); 314 while (iter.hasNext()) { 315 ClassType implementor = (ClassType)iter.next(); 316 MessageOutput.println("implementor:", implementor.name()); 317 } 318 List nested = interfaze.nestedTypes(); 319 iter = nested.iterator(); 320 while (iter.hasNext()) { 321 ReferenceType nest = (ReferenceType)iter.next(); 322 MessageOutput.println("nested:", nest.name()); 323 } 324 } else { ArrayType array = (ArrayType)type; 326 MessageOutput.println("Array:", array.name()); 327 } 328 } 329 330 void commandMethods(StringTokenizer t) { 331 if (!t.hasMoreTokens()) { 332 MessageOutput.println("No class specified."); 333 return; 334 } 335 336 String idClass = t.nextToken(); 337 ReferenceType cls = Env.getReferenceTypeFromToken(idClass); 338 if (cls != null) { 339 List methods = cls.allMethods(); 340 StringBuffer methodsList = new StringBuffer (); 341 for (int i = 0; i < methods.size(); i++) { 342 Method method = (Method)methods.get(i); 343 methodsList.append(method.declaringType().name()); 344 methodsList.append(" "); 345 methodsList.append(typedName(method)); 346 methodsList.append('\n'); 347 } 348 MessageOutput.print("** methods list **", methodsList.toString()); 349 } else { 350 MessageOutput.println("is not a valid id or class name", idClass); 351 } 352 } 353 354 void commandFields(StringTokenizer t) { 355 if (!t.hasMoreTokens()) { 356 MessageOutput.println("No class specified."); 357 return; 358 } 359 360 String idClass = t.nextToken(); 361 ReferenceType cls = Env.getReferenceTypeFromToken(idClass); 362 if (cls != null) { 363 List fields = cls.allFields(); 364 List visible = cls.visibleFields(); 365 StringBuffer fieldsList = new StringBuffer (); 366 for (int i = 0; i < fields.size(); i++) { 367 Field field = (Field)fields.get(i); 368 String s; 369 if (!visible.contains(field)) { 370 s = MessageOutput.format("list field typename and name hidden", 371 new Object [] {field.typeName(), 372 field.name()}); 373 } else if (!field.declaringType().equals(cls)) { 374 s = MessageOutput.format("list field typename and name inherited", 375 new Object [] {field.typeName(), 376 field.name(), 377 field.declaringType().name()}); 378 } else { 379 s = MessageOutput.format("list field typename and name", 380 new Object [] {field.typeName(), 381 field.name()}); 382 } 383 fieldsList.append(s); 384 } 385 MessageOutput.print("** fields list **", fieldsList.toString()); 386 } else { 387 MessageOutput.println("is not a valid id or class name", idClass); 388 } 389 } 390 391 private void printThreadGroup(ThreadGroupReference tg) { 392 ThreadIterator threadIter = new ThreadIterator(tg); 393 394 MessageOutput.println("Thread Group:", tg.name()); 395 int maxIdLength = 0; 396 int maxNameLength = 0; 397 while (threadIter.hasNext()) { 398 ThreadReference thr = (ThreadReference)threadIter.next(); 399 maxIdLength = Math.max(maxIdLength, 400 Env.description(thr).length()); 401 maxNameLength = Math.max(maxNameLength, 402 thr.name().length()); 403 } 404 405 threadIter = new ThreadIterator(tg); 406 while (threadIter.hasNext()) { 407 ThreadReference thr = (ThreadReference)threadIter.next(); 408 if (thr.threadGroup() == null) { 409 continue; 410 } 411 if (!thr.threadGroup().equals(tg)) { 413 tg = thr.threadGroup(); 414 MessageOutput.println("Thread Group:", tg.name()); 415 } 416 417 424 StringBuffer idBuffer = new StringBuffer (Env.description(thr)); 425 for (int i = idBuffer.length(); i < maxIdLength; i++) { 426 idBuffer.append(" "); 427 } 428 StringBuffer nameBuffer = new StringBuffer (thr.name()); 429 for (int i = nameBuffer.length(); i < maxNameLength; i++) { 430 nameBuffer.append(" "); 431 } 432 433 437 String statusFormat; 438 switch (thr.status()) { 439 case ThreadReference.THREAD_STATUS_UNKNOWN: 440 if (thr.isAtBreakpoint()) { 441 statusFormat = "Thread description name unknownStatus BP"; 442 } else { 443 statusFormat = "Thread description name unknownStatus"; 444 } 445 break; 446 case ThreadReference.THREAD_STATUS_ZOMBIE: 447 if (thr.isAtBreakpoint()) { 448 statusFormat = "Thread description name zombieStatus BP"; 449 } else { 450 statusFormat = "Thread description name zombieStatus"; 451 } 452 break; 453 case ThreadReference.THREAD_STATUS_RUNNING: 454 if (thr.isAtBreakpoint()) { 455 statusFormat = "Thread description name runningStatus BP"; 456 } else { 457 statusFormat = "Thread description name runningStatus"; 458 } 459 break; 460 case ThreadReference.THREAD_STATUS_SLEEPING: 461 if (thr.isAtBreakpoint()) { 462 statusFormat = "Thread description name sleepingStatus BP"; 463 } else { 464 statusFormat = "Thread description name sleepingStatus"; 465 } 466 break; 467 case ThreadReference.THREAD_STATUS_MONITOR: 468 if (thr.isAtBreakpoint()) { 469 statusFormat = "Thread description name waitingStatus BP"; 470 } else { 471 statusFormat = "Thread description name waitingStatus"; 472 } 473 break; 474 case ThreadReference.THREAD_STATUS_WAIT: 475 if (thr.isAtBreakpoint()) { 476 statusFormat = "Thread description name condWaitstatus BP"; 477 } else { 478 statusFormat = "Thread description name condWaitstatus"; 479 } 480 break; 481 default: 482 throw new InternalError (MessageOutput.format("Invalid thread status.")); 483 } 484 MessageOutput.println(statusFormat, 485 new Object [] {idBuffer.toString(), 486 nameBuffer.toString()}); 487 } 488 } 489 490 void commandThreads(StringTokenizer t) { 491 if (!t.hasMoreTokens()) { 492 printThreadGroup(ThreadInfo.group()); 493 return; 494 } 495 String name = t.nextToken(); 496 ThreadGroupReference tg = ThreadGroupIterator.find(name); 497 if (tg == null) { 498 MessageOutput.println("is not a valid threadgroup name", name); 499 } else { 500 printThreadGroup(tg); 501 } 502 } 503 504 void commandThreadGroups() { 505 ThreadGroupIterator it = new ThreadGroupIterator(); 506 int cnt = 0; 507 while (it.hasNext()) { 508 ThreadGroupReference tg = it.nextThreadGroup(); 509 ++cnt; 510 MessageOutput.println("thread group number description name", 511 new Object [] { new Integer (cnt), 512 Env.description(tg), 513 tg.name()}); 514 } 515 } 516 517 void commandThread(StringTokenizer t) { 518 if (!t.hasMoreTokens()) { 519 MessageOutput.println("Thread number not specified."); 520 return; 521 } 522 ThreadInfo threadInfo = doGetThread(t.nextToken()); 523 if (threadInfo != null) { 524 ThreadInfo.setCurrentThreadInfo(threadInfo); 525 } 526 } 527 528 void commandThreadGroup(StringTokenizer t) { 529 if (!t.hasMoreTokens()) { 530 MessageOutput.println("Threadgroup name not specified."); 531 return; 532 } 533 String name = t.nextToken(); 534 ThreadGroupReference tg = ThreadGroupIterator.find(name); 535 if (tg == null) { 536 MessageOutput.println("is not a valid threadgroup name", name); 537 } else { 538 ThreadInfo.setThreadGroup(tg); 539 } 540 } 541 542 void commandRun(StringTokenizer t) { 543 551 VMConnection connection = Env.connection(); 552 if (!connection.isLaunch()) { 553 if (!t.hasMoreTokens()) { 554 commandCont(); 555 } else { 556 MessageOutput.println("run <args> command is valid only with launched VMs"); 557 } 558 return; 559 } 560 if (connection.isOpen()) { 561 MessageOutput.println("VM already running. use cont to continue after events."); 562 return; 563 } 564 565 569 String args; 570 if (t.hasMoreTokens()) { 571 args = t.nextToken(""); 572 boolean argsSet = connection.setConnectorArg("main", args); 573 if (!argsSet) { 574 MessageOutput.println("Unable to set main class and arguments"); 575 return; 576 } 577 } else { 578 args = connection.connectorArg("main"); 579 if (args.length() == 0) { 580 MessageOutput.println("Main class and arguments must be specified"); 581 return; 582 } 583 } 584 MessageOutput.println("run", args); 585 586 589 connection.open(); 590 591 } 592 593 void commandLoad(StringTokenizer t) { 594 MessageOutput.println("The load command is no longer supported."); 595 } 596 597 private List allThreads(ThreadGroupReference group) { 598 List list = new ArrayList(); 599 list.addAll(group.threads()); 600 Iterator iter = group.threadGroups().iterator(); 601 while (iter.hasNext()) { 602 ThreadGroupReference child = (ThreadGroupReference)iter.next(); 603 list.addAll(allThreads(child)); 604 } 605 return list; 606 } 607 608 void commandSuspend(StringTokenizer t) { 609 if (!t.hasMoreTokens()) { 610 Env.vm().suspend(); 611 MessageOutput.println("All threads suspended."); 612 } else { 613 while (t.hasMoreTokens()) { 614 ThreadInfo threadInfo = doGetThread(t.nextToken()); 615 if (threadInfo != null) { 616 threadInfo.getThread().suspend(); 617 } 618 } 619 } 620 } 621 622 void commandResume(StringTokenizer t) { 623 if (!t.hasMoreTokens()) { 624 ThreadInfo.invalidateAll(); 625 Env.vm().resume(); 626 MessageOutput.println("All threads resumed."); 627 } else { 628 while (t.hasMoreTokens()) { 629 ThreadInfo threadInfo = doGetThread(t.nextToken()); 630 if (threadInfo != null) { 631 threadInfo.invalidate(); 632 threadInfo.getThread().resume(); 633 } 634 } 635 } 636 } 637 638 void commandCont() { 639 if (ThreadInfo.getCurrentThreadInfo() == null) { 640 MessageOutput.println("Nothing suspended."); 641 return; 642 } 643 ThreadInfo.invalidateAll(); 644 Env.vm().resume(); 645 } 646 647 void clearPreviousStep(ThreadReference thread) { 648 652 EventRequestManager mgr = Env.vm().eventRequestManager(); 653 List requests = mgr.stepRequests(); 654 Iterator iter = requests.iterator(); 655 while (iter.hasNext()) { 656 StepRequest request = (StepRequest)iter.next(); 657 if (request.thread().equals(thread)) { 658 mgr.deleteEventRequest(request); 659 break; 660 } 661 } 662 } 663 666 void commandStep(StringTokenizer t) { 667 ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo(); 668 if (threadInfo == null) { 669 MessageOutput.println("Nothing suspended."); 670 return; 671 } 672 int depth; 673 if (t.hasMoreTokens() && 674 t.nextToken().toLowerCase().equals("up")) { 675 depth = StepRequest.STEP_OUT; 676 } else { 677 depth = StepRequest.STEP_INTO; 678 } 679 680 clearPreviousStep(threadInfo.getThread()); 681 EventRequestManager reqMgr = Env.vm().eventRequestManager(); 682 StepRequest request = reqMgr.createStepRequest(threadInfo.getThread(), 683 StepRequest.STEP_LINE, depth); 684 if (depth == StepRequest.STEP_INTO) { 685 Env.addExcludes(request); 686 } 687 request.addCountFilter(1); 689 request.enable(); 690 ThreadInfo.invalidateAll(); 691 Env.vm().resume(); 692 } 693 694 697 void commandStepi() { 698 ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo(); 699 if (threadInfo == null) { 700 MessageOutput.println("Nothing suspended."); 701 return; 702 } 703 clearPreviousStep(threadInfo.getThread()); 704 EventRequestManager reqMgr = Env.vm().eventRequestManager(); 705 StepRequest request = reqMgr.createStepRequest(threadInfo.getThread(), 706 StepRequest.STEP_MIN, 707 StepRequest.STEP_INTO); 708 Env.addExcludes(request); 709 request.addCountFilter(1); 711 request.enable(); 712 ThreadInfo.invalidateAll(); 713 Env.vm().resume(); 714 } 715 716 void commandNext() { 717 ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo(); 718 if (threadInfo == null) { 719 MessageOutput.println("Nothing suspended."); 720 return; 721 } 722 clearPreviousStep(threadInfo.getThread()); 723 EventRequestManager reqMgr = Env.vm().eventRequestManager(); 724 StepRequest request = reqMgr.createStepRequest(threadInfo.getThread(), 725 StepRequest.STEP_LINE, 726 StepRequest.STEP_OVER); 727 Env.addExcludes(request); 728 request.addCountFilter(1); 730 request.enable(); 731 ThreadInfo.invalidateAll(); 732 Env.vm().resume(); 733 } 734 735 void doKill(ThreadReference thread, StringTokenizer t) { 736 if (!t.hasMoreTokens()) { 737 MessageOutput.println("No exception object specified."); 738 return; 739 } 740 String expr = t.nextToken(""); 741 Value val = evaluate(expr); 742 if ((val != null) && (val instanceof ObjectReference)) { 743 try { 744 thread.stop((ObjectReference)val); 745 MessageOutput.println("killed", thread.toString()); 746 } catch (InvalidTypeException e) { 747 MessageOutput.println("Invalid exception object"); 748 } 749 } else { 750 MessageOutput.println("Expression must evaluate to an object"); 751 } 752 } 753 754 void doKillThread(final ThreadReference threadToKill, 755 final StringTokenizer tokenizer) { 756 new AsyncExecution() { 757 void action() { 758 doKill(threadToKill, tokenizer); 759 } 760 }; 761 } 762 763 void commandKill(StringTokenizer t) { 764 if (!t.hasMoreTokens()) { 765 MessageOutput.println("Usage: kill <thread id> <throwable>"); 766 return; 767 } 768 ThreadInfo threadInfo = doGetThread(t.nextToken()); 769 if (threadInfo != null) { 770 MessageOutput.println("killing thread:", threadInfo.getThread().name()); 771 doKillThread(threadInfo.getThread(), t); 772 return; 773 } 774 } 775 776 void listCaughtExceptions() { 777 boolean noExceptions = true; 778 779 Iterator iter = Env.specList.eventRequestSpecs().iterator(); 781 while (iter.hasNext()) { 782 EventRequestSpec spec = (EventRequestSpec)iter.next(); 783 if (spec instanceof ExceptionSpec) { 784 if (noExceptions) { 785 noExceptions = false; 786 MessageOutput.println("Exceptions caught:"); 787 } 788 MessageOutput.println("tab", spec.toString()); 789 } 790 } 791 if (noExceptions) { 792 MessageOutput.println("No exceptions caught."); 793 } 794 } 795 796 private EventRequestSpec parseExceptionSpec(StringTokenizer t) { 797 String notification = t.nextToken(); 798 boolean notifyCaught = false; 799 boolean notifyUncaught = false; 800 EventRequestSpec spec = null; 801 String classPattern = null; 802 803 if (notification.equals("uncaught")) { 804 notifyCaught = false; 805 notifyUncaught = true; 806 } else if (notification.equals("caught")) { 807 notifyCaught = true; 808 notifyUncaught = false; 809 } else if (notification.equals("all")) { 810 notifyCaught = true; 811 notifyUncaught = true; 812 } else { 813 821 notifyCaught = true; 822 notifyUncaught = true; 823 classPattern = notification; 824 } 825 if (classPattern == null && t.hasMoreTokens()) { 826 classPattern = t.nextToken(); 827 } 828 if ((classPattern != null) && (notifyCaught || notifyUncaught)) { 829 try { 830 spec = Env.specList.createExceptionCatch(classPattern, 831 notifyCaught, 832 notifyUncaught); 833 } catch (ClassNotFoundException exc) { 834 MessageOutput.println("is not a valid class name", classPattern); 835 } 836 } 837 return spec; 838 } 839 840 void commandCatchException(StringTokenizer t) { 841 if (!t.hasMoreTokens()) { 842 listCaughtExceptions(); 843 } else { 844 EventRequestSpec spec = parseExceptionSpec(t); 845 if (spec != null) { 846 resolveNow(spec); 847 } else { 848 MessageOutput.println("Usage: catch exception"); 849 } 850 } 851 } 852 853 void commandIgnoreException(StringTokenizer t) { 854 if (!t.hasMoreTokens()) { 855 listCaughtExceptions(); 856 } else { 857 EventRequestSpec spec = parseExceptionSpec(t); 858 if (Env.specList.delete(spec)) { 859 MessageOutput.println("Removed:", spec.toString()); 860 } else { 861 if (spec != null) { 862 MessageOutput.println("Not found:", spec.toString()); 863 } 864 MessageOutput.println("Usage: ignore exception"); 865 } 866 } 867 } 868 869 void commandUp(StringTokenizer t) { 870 ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo(); 871 if (threadInfo == null) { 872 MessageOutput.println("Current thread not set."); 873 return; 874 } 875 876 int nLevels = 1; 877 if (t.hasMoreTokens()) { 878 String idToken = t.nextToken(); 879 int i; 880 try { 881 NumberFormat nf = NumberFormat.getNumberInstance(); 882 nf.setParseIntegerOnly(true); 883 Number n = nf.parse(idToken); 884 i = n.intValue(); 885 } catch (java.text.ParseException jtpe) { 886 i = 0; 887 } 888 if (i <= 0) { 889 MessageOutput.println("Usage: up [n frames]"); 890 return; 891 } 892 nLevels = i; 893 } 894 895 try { 896 threadInfo.up(nLevels); 897 } catch (IncompatibleThreadStateException e) { 898 MessageOutput.println("Current thread isnt suspended."); 899 } catch (ArrayIndexOutOfBoundsException e) { 900 MessageOutput.println("End of stack."); 901 } 902 } 903 904 void commandDown(StringTokenizer t) { 905 ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo(); 906 if (threadInfo == null) { 907 MessageOutput.println("Current thread not set."); 908 return; 909 } 910 911 int nLevels = 1; 912 if (t.hasMoreTokens()) { 913 String idToken = t.nextToken(); 914 int i; 915 try { 916 NumberFormat nf = NumberFormat.getNumberInstance(); 917 nf.setParseIntegerOnly(true); 918 Number n = nf.parse(idToken); 919 i = n.intValue(); 920 } catch (java.text.ParseException jtpe) { 921 i = 0; 922 } 923 if (i <= 0) { 924 MessageOutput.println("Usage: down [n frames]"); 925 return; 926 } 927 nLevels = i; 928 } 929 930 try { 931 threadInfo.down(nLevels); 932 } catch (IncompatibleThreadStateException e) { 933 MessageOutput.println("Current thread isnt suspended."); 934 } catch (ArrayIndexOutOfBoundsException e) { 935 MessageOutput.println("End of stack."); 936 } 937 } 938 939 private void dumpStack(ThreadInfo threadInfo, boolean showPC) { 940 List stack = null; 941 try { 942 stack = threadInfo.getStack(); 943 } catch (IncompatibleThreadStateException e) { 944 MessageOutput.println("Current thread isnt suspended."); 945 return; 946 } 947 if (stack == null) { 948 MessageOutput.println("Thread is not running (no stack)."); 949 } else { 950 int nFrames = stack.size(); 951 for (int i = threadInfo.getCurrentFrameIndex(); i < nFrames; i++) { 952 StackFrame frame = (StackFrame)stack.get(i); 953 dumpFrame (i, showPC, frame); 954 } 955 } 956 } 957 958 private void dumpFrame (int frameNumber, boolean showPC, StackFrame frame) { 959 Location loc = frame.location(); 960 long pc = -1; 961 if (showPC) { 962 pc = loc.codeIndex(); 963 } 964 Method meth = loc.method(); 965 966 long lineNumber = loc.lineNumber(); 967 String methodInfo = null; 968 if (meth instanceof Method && ((Method)meth).isNative()) { 969 methodInfo = MessageOutput.format("native method"); 970 } else if (lineNumber != -1) { 971 try { 972 methodInfo = loc.sourceName() + 973 MessageOutput.format("line number", 974 new Object [] {new Long (lineNumber)}); 975 } catch (AbsentInformationException e) { 976 methodInfo = MessageOutput.format("unknown"); 977 } 978 } 979 if (pc != -1) { 980 MessageOutput.println("stack frame dump with pc", 981 new Object [] {new Integer (frameNumber + 1), 982 meth.declaringType().name(), 983 meth.name(), 984 methodInfo, 985 new Long (pc)}); 986 } else { 987 MessageOutput.println("stack frame dump", 988 new Object [] {new Integer (frameNumber + 1), 989 meth.declaringType().name(), 990 meth.name(), 991 methodInfo}); 992 } 993 } 994 995 void commandWhere(StringTokenizer t, boolean showPC) { 996 if (!t.hasMoreTokens()) { 997 ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo(); 998 if (threadInfo == null) { 999 MessageOutput.println("No thread specified."); 1000 return; 1001 } 1002 dumpStack(threadInfo, showPC); 1003 } else { 1004 String token = t.nextToken(); 1005 if (token.toLowerCase().equals("all")) { 1006 Iterator iter = ThreadInfo.threads().iterator(); 1007 while (iter.hasNext()) { 1008 ThreadInfo threadInfo = (ThreadInfo)iter.next(); 1009 MessageOutput.println("Thread:", 1010 threadInfo.getThread().name()); 1011 dumpStack(threadInfo, showPC); 1012 } 1013 } else { 1014 ThreadInfo threadInfo = doGetThread(token); 1015 if (threadInfo != null) { 1016 ThreadInfo.setCurrentThreadInfo(threadInfo); 1017 dumpStack(threadInfo, showPC); 1018 } 1019 } 1020 } 1021 } 1022 1023 void commandInterrupt(StringTokenizer t) { 1024 if (!t.hasMoreTokens()) { 1025 ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo(); 1026 if (threadInfo == null) { 1027 MessageOutput.println("No thread specified."); 1028 return; 1029 } 1030 threadInfo.getThread().interrupt(); 1031 } else { 1032 ThreadInfo threadInfo = doGetThread(t.nextToken()); 1033 if (threadInfo != null) { 1034 threadInfo.getThread().interrupt(); 1035 } 1036 } 1037 } 1038 1039 void commandMemory() { 1040 MessageOutput.println("The memory command is no longer supported."); 1041 } 1042 1043 void commandGC() { 1044 MessageOutput.println("The gc command is no longer necessary."); 1045 } 1046 1047 1051 static String locationString(Location loc) { 1052 return MessageOutput.format("locationString", 1053 new Object [] {loc.declaringType().name(), 1054 loc.method().name(), 1055 new Integer (loc.lineNumber()), 1056 new Long (loc.codeIndex())}); 1057 } 1058 1059 void listBreakpoints() { 1060 boolean noBreakpoints = true; 1061 1062 Iterator iter = Env.specList.eventRequestSpecs().iterator(); 1064 while (iter.hasNext()) { 1065 EventRequestSpec spec = (EventRequestSpec)iter.next(); 1066 if (spec instanceof BreakpointSpec) { 1067 if (noBreakpoints) { 1068 noBreakpoints = false; 1069 MessageOutput.println("Breakpoints set:"); 1070 } 1071 MessageOutput.println("tab", spec.toString()); 1072 } 1073 } 1074 if (noBreakpoints) { 1075 MessageOutput.println("No breakpoints set."); 1076 } 1077 } 1078 1079 1080 private void printBreakpointCommandUsage(String atForm, String inForm) { 1081 MessageOutput.println("printbreakpointcommandusage", 1082 new Object [] {atForm, inForm}); 1083 } 1084 1085 protected BreakpointSpec parseBreakpointSpec(StringTokenizer t, 1086 String atForm, String inForm) { 1087 EventRequestSpec breakpoint = null; 1088 try { 1089 String token = t.nextToken(":( \t\n\r"); 1090 1091 String rest; 1094 try { 1095 rest = t.nextToken("").trim(); 1096 } catch (NoSuchElementException e) { 1097 rest = null; 1098 } 1099 1100 if ((rest != null) && rest.startsWith(":")) { 1101 t = new StringTokenizer(rest.substring(1)); 1102 String classId = token; 1103 String lineToken = t.nextToken(); 1104 1105 NumberFormat nf = NumberFormat.getNumberInstance(); 1106 nf.setParseIntegerOnly(true); 1107 Number n = nf.parse(lineToken); 1108 int lineNumber = n.intValue(); 1109 1110 if (t.hasMoreTokens()) { 1111 printBreakpointCommandUsage(atForm, inForm); 1112 return null; 1113 } 1114 try { 1115 breakpoint = Env.specList.createBreakpoint(classId, 1116 lineNumber); 1117 } catch (ClassNotFoundException exc) { 1118 MessageOutput.println("is not a valid class name", classId); 1119 } 1120 } else { 1121 int idot = token.lastIndexOf("."); 1123 if ( (idot <= 0) || 1124 (idot >= token.length() - 1) ) { 1125 printBreakpointCommandUsage(atForm, inForm); 1126 return null; 1127 } 1128 String methodName = token.substring(idot + 1); 1129 String classId = token.substring(0, idot); 1130 List argumentList = null; 1131 if (rest != null) { 1132 if (!rest.startsWith("(") || !rest.endsWith(")")) { 1133 MessageOutput.println("Invalid method specification:", 1134 methodName + rest); 1135 printBreakpointCommandUsage(atForm, inForm); 1136 return null; 1137 } 1138 rest = rest.substring(1, rest.length() - 1); 1140 1141 argumentList = new ArrayList(); 1142 t = new StringTokenizer(rest, ","); 1143 while (t.hasMoreTokens()) { 1144 argumentList.add(t.nextToken()); 1145 } 1146 } 1147 try { 1148 breakpoint = Env.specList.createBreakpoint(classId, 1149 methodName, 1150 argumentList); 1151 } catch (MalformedMemberNameException exc) { 1152 MessageOutput.println("is not a valid method name", methodName); 1153 } catch (ClassNotFoundException exc) { 1154 MessageOutput.println("is not a valid class name", classId); 1155 } 1156 } 1157 } catch (Exception e) { 1158 printBreakpointCommandUsage(atForm, inForm); 1159 return null; 1160 } 1161 return (BreakpointSpec)breakpoint; 1162 } 1163 1164 private void resolveNow(EventRequestSpec spec) { 1165 boolean success = Env.specList.addEagerlyResolve(spec); 1166 if (success && !spec.isResolved()) { 1167 MessageOutput.println("Deferring.", spec.toString()); 1168 } 1169 } 1170 1171 void commandStop(StringTokenizer t) { 1172 Location bploc; 1173 String atIn; 1174 byte suspendPolicy = EventRequest.SUSPEND_ALL; 1175 1176 if (t.hasMoreTokens()) { 1177 atIn = t.nextToken(); 1178 if (atIn.equals("go") && t.hasMoreTokens()) { 1179 suspendPolicy = EventRequest.SUSPEND_NONE; 1180 atIn = t.nextToken(); 1181 } else if (atIn.equals("thread") && t.hasMoreTokens()) { 1182 suspendPolicy = EventRequest.SUSPEND_EVENT_THREAD; 1183 atIn = t.nextToken(); 1184 } 1185 } else { 1186 listBreakpoints(); 1187 return; 1188 } 1189 1190 BreakpointSpec spec = parseBreakpointSpec(t, "stop at", "stop in"); 1191 if (spec != null) { 1192 if (atIn.equals("at") && spec.isMethodBreakpoint()) { 1196 MessageOutput.println("Use stop at to set a breakpoint at a line number"); 1197 printBreakpointCommandUsage("stop at", "stop in"); 1198 return; 1199 } 1200 spec.suspendPolicy = suspendPolicy; 1201 resolveNow(spec); 1202 } 1203 } 1204 1205 void commandClear(StringTokenizer t) { 1206 if (!t.hasMoreTokens()) { 1207 listBreakpoints(); 1208 return; 1209 } 1210 1211 BreakpointSpec spec = parseBreakpointSpec(t, "clear", "clear"); 1212 if (spec != null) { 1213 if (Env.specList.delete(spec)) { 1214 MessageOutput.println("Removed:", spec.toString()); 1215 } else { 1216 MessageOutput.println("Not found:", spec.toString()); 1217 } 1218 } 1219 } 1220 1221 private List parseWatchpointSpec(StringTokenizer t) { 1222 List list = new ArrayList(); 1223 boolean access = false; 1224 boolean modification = false; 1225 int suspendPolicy = EventRequest.SUSPEND_ALL; 1226 1227 String fieldName = t.nextToken(); 1228 if (fieldName.equals("go")) { 1229 suspendPolicy = EventRequest.SUSPEND_NONE; 1230 fieldName = t.nextToken(); 1231 } else if (fieldName.equals("thread")) { 1232 suspendPolicy = EventRequest.SUSPEND_EVENT_THREAD; 1233 fieldName = t.nextToken(); 1234 } 1235 if (fieldName.equals("access")) { 1236 access = true; 1237 fieldName = t.nextToken(); 1238 } else if (fieldName.equals("all")) { 1239 access = true; 1240 modification = true; 1241 fieldName = t.nextToken(); 1242 } else { 1243 modification = true; 1244 } 1245 int dot = fieldName.lastIndexOf('.'); 1246 if (dot < 0) { 1247 MessageOutput.println("Class containing field must be specified."); 1248 return list; 1249 } 1250 String className = fieldName.substring(0, dot); 1251 fieldName = fieldName.substring(dot+1); 1252 1253 try { 1254 EventRequestSpec spec; 1255 if (access) { 1256 spec = Env.specList.createAccessWatchpoint(className, 1257 fieldName); 1258 spec.suspendPolicy = suspendPolicy; 1259 list.add(spec); 1260 } 1261 if (modification) { 1262 spec = Env.specList.createModificationWatchpoint(className, 1263 fieldName); 1264 spec.suspendPolicy = suspendPolicy; 1265 list.add(spec); 1266 } 1267 } catch (MalformedMemberNameException exc) { 1268 MessageOutput.println("is not a valid field name", fieldName); 1269 } catch (ClassNotFoundException exc) { 1270 MessageOutput.println("is not a valid class name", className); 1271 } 1272 return list; 1273 } 1274 1275 void commandWatch(StringTokenizer t) { 1276 if (!t.hasMoreTokens()) { 1277 MessageOutput.println("Field to watch not specified"); 1278 return; 1279 } 1280 1281 Iterator iter = parseWatchpointSpec(t).iterator(); 1282 while (iter.hasNext()) { 1283 resolveNow((WatchpointSpec)iter.next()); 1284 } 1285 } 1286 1287 void commandUnwatch(StringTokenizer t) { 1288 if (!t.hasMoreTokens()) { 1289 MessageOutput.println("Field to unwatch not specified"); 1290 return; 1291 } 1292 1293 Iterator iter = parseWatchpointSpec(t).iterator(); 1294 while (iter.hasNext()) { 1295 WatchpointSpec spec = (WatchpointSpec)iter.next(); 1296 if (Env.specList.delete(spec)) { 1297 MessageOutput.println("Removed:", spec.toString()); 1298 } else { 1299 MessageOutput.println("Not found:", spec.toString()); 1300 } 1301 } 1302 } 1303 1304 void turnOnExitTrace(ThreadInfo threadInfo, int suspendPolicy) { 1305 EventRequestManager erm = Env.vm().eventRequestManager(); 1306 MethodExitRequest exit = erm.createMethodExitRequest(); 1307 if (threadInfo != null) { 1308 exit.addThreadFilter(threadInfo.getThread()); 1309 } 1310 Env.addExcludes(exit); 1311 exit.setSuspendPolicy(suspendPolicy); 1312 exit.enable(); 1313 1314 } 1315 1316 static String methodTraceCommand = null; 1317 1318 void commandTrace(StringTokenizer t) { 1319 String modif; 1320 int suspendPolicy = EventRequest.SUSPEND_ALL; 1321 ThreadInfo threadInfo = null; 1322 String goStr = " "; 1323 1324 1328 if (t.hasMoreTokens()) { 1329 modif = t.nextToken(); 1330 if (modif.equals("go")) { 1331 suspendPolicy = EventRequest.SUSPEND_NONE; 1332 goStr = " go "; 1333 if (t.hasMoreTokens()) { 1334 modif = t.nextToken(); 1335 } 1336 } else if (modif.equals("thread")) { 1337 suspendPolicy = EventRequest.SUSPEND_EVENT_THREAD; 1339 if (t.hasMoreTokens()) { 1340 modif = t.nextToken(); 1341 } 1342 } 1343 1344 if (modif.equals("method")) { 1345 String traceCmd = null; 1346 1347 if (t.hasMoreTokens()) { 1348 String modif1 = t.nextToken(); 1349 if (modif1.equals("exits") || modif1.equals("exit")) { 1350 if (t.hasMoreTokens()) { 1351 threadInfo = doGetThread(t.nextToken()); 1352 } 1353 if (modif1.equals("exit")) { 1354 StackFrame frame; 1355 try { 1356 frame = ThreadInfo.getCurrentThreadInfo().getCurrentFrame(); 1357 } catch (IncompatibleThreadStateException ee) { 1358 MessageOutput.println("Current thread isnt suspended."); 1359 return; 1360 } 1361 Env.setAtExitMethod(frame.location().method()); 1362 traceCmd = MessageOutput.format("trace" + 1363 goStr + "method exit " + 1364 "in effect for", 1365 Env.atExitMethod().toString()); 1366 } else { 1367 traceCmd = MessageOutput.format("trace" + 1368 goStr + "method exits " + 1369 "in effect"); 1370 } 1371 commandUntrace(new StringTokenizer("methods")); 1372 turnOnExitTrace(threadInfo, suspendPolicy); 1373 methodTraceCommand = traceCmd; 1374 return; 1375 } 1376 } else { 1377 MessageOutput.println("Can only trace"); 1378 return; 1379 } 1380 } 1381 if (modif.equals("methods")) { 1382 MethodEntryRequest entry; 1384 EventRequestManager erm = Env.vm().eventRequestManager(); 1385 if (t.hasMoreTokens()) { 1386 threadInfo = doGetThread(t.nextToken()); 1387 } 1388 if (threadInfo != null) { 1389 1405 1406 entry = erm.createMethodEntryRequest(); 1407 entry.addThreadFilter(threadInfo.getThread()); 1408 } else { 1409 commandUntrace(new StringTokenizer("methods")); 1410 entry = erm.createMethodEntryRequest(); 1411 } 1412 Env.addExcludes(entry); 1413 entry.setSuspendPolicy(suspendPolicy); 1414 entry.enable(); 1415 turnOnExitTrace(threadInfo, suspendPolicy); 1416 methodTraceCommand = MessageOutput.format("trace" + goStr + 1417 "methods in effect"); 1418 1419 return; 1420 } 1421 1422 MessageOutput.println("Can only trace"); 1423 return; 1424 } 1425 1426 if (methodTraceCommand != null) { 1428 MessageOutput.printDirectln(methodTraceCommand); 1429 } 1430 1431 } 1433 1434 void commandUntrace(StringTokenizer t) { 1435 1438 String modif = null; 1439 EventRequestManager erm = Env.vm().eventRequestManager(); 1440 if (t.hasMoreTokens()) { 1441 modif = t.nextToken(); 1442 } 1443 if (modif == null || modif.equals("methods")) { 1444 erm.deleteEventRequests(erm.methodEntryRequests()); 1445 erm.deleteEventRequests(erm.methodExitRequests()); 1446 Env.setAtExitMethod(null); 1447 methodTraceCommand = null; 1448 } 1449 } 1450 1451 void commandList(StringTokenizer t) { 1452 StackFrame frame = null; 1453 ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo(); 1454 if (threadInfo == null) { 1455 MessageOutput.println("No thread specified."); 1456 return; 1457 } 1458 try { 1459 frame = threadInfo.getCurrentFrame(); 1460 } catch (IncompatibleThreadStateException e) { 1461 MessageOutput.println("Current thread isnt suspended."); 1462 return; 1463 } 1464 1465 if (frame == null) { 1466 MessageOutput.println("No frames on the current call stack"); 1467 return; 1468 } 1469 1470 Location loc = frame.location(); 1471 if (loc.method().isNative()) { 1472 MessageOutput.println("Current method is native"); 1473 return; 1474 } 1475 1476 String sourceFileName = null; 1477 try { 1478 sourceFileName = loc.sourceName(); 1479 1480 ReferenceType refType = loc.declaringType(); 1481 int lineno = loc.lineNumber(); 1482 1483 if (t.hasMoreTokens()) { 1484 String id = t.nextToken(); 1485 1486 try { 1488 NumberFormat nf = NumberFormat.getNumberInstance(); 1489 nf.setParseIntegerOnly(true); 1490 Number n = nf.parse(id); 1491 lineno = n.intValue(); 1492 } catch (java.text.ParseException jtpe) { 1493 List meths = refType.methodsByName(id); 1495 if (meths == null || meths.size() == 0) { 1496 MessageOutput.println("is not a valid line number or method name for", 1497 new Object [] {id, refType.name()}); 1498 return; 1499 } else if (meths.size() > 1) { 1500 MessageOutput.println("is an ambiguous method name in", 1501 new Object [] {id, refType.name()}); 1502 return; 1503 } 1504 loc = ((Method)meths.get(0)).location(); 1505 lineno = loc.lineNumber(); 1506 } 1507 } 1508 int startLine = Math.max(lineno - 4, 1); 1509 int endLine = startLine + 9; 1510 if (lineno < 0) { 1511 MessageOutput.println("Line number information not available for"); 1512 } else if (Env.sourceLine(loc, lineno) == null) { 1513 MessageOutput.println("is an invalid line number for", 1514 new Object [] {new Integer (lineno), 1515 refType.name()}); 1516 } else { 1517 for (int i = startLine; i <= endLine; i++) { 1518 String sourceLine = Env.sourceLine(loc, i); 1519 if (sourceLine == null) { 1520 break; 1521 } 1522 if (i == lineno) { 1523 MessageOutput.println("source line number current line and line", 1524 new Object [] {new Integer (i), 1525 sourceLine}); 1526 } else { 1527 MessageOutput.println("source line number and line", 1528 new Object [] {new Integer (i), 1529 sourceLine}); 1530 } 1531 } 1532 } 1533 } catch (AbsentInformationException e) { 1534 MessageOutput.println("No source information available for:", loc.toString()); 1535 } catch(FileNotFoundException exc) { 1536 MessageOutput.println("Source file not found:", sourceFileName); 1537 } catch(IOException exc) { 1538 MessageOutput.println("I/O exception occurred:", exc.toString()); 1539 } 1540 } 1541 1542 void commandLines(StringTokenizer t) { if (!t.hasMoreTokens()) { 1544 MessageOutput.println("Specify class and method"); 1545 } else { 1546 String idClass = t.nextToken(); 1547 String idMethod = t.hasMoreTokens() ? t.nextToken() : null; 1548 try { 1549 ReferenceType refType = Env.getReferenceTypeFromToken(idClass); 1550 if (refType != null) { 1551 List lines = null; 1552 if (idMethod == null) { 1553 lines = refType.allLineLocations(); 1554 } else { 1555 List methods = refType.allMethods(); 1556 Iterator iter = methods.iterator(); 1557 while (iter.hasNext()) { 1558 Method method = (Method)iter.next(); 1559 if (method.name().equals(idMethod)) { 1560 lines = method.allLineLocations(); 1561 } 1562 } 1563 if (lines == null) { 1564 MessageOutput.println("is not a valid method name", idMethod); 1565 } 1566 } 1567 Iterator iter = lines.iterator(); 1568 while (iter.hasNext()) { 1569 Location line = (Location)iter.next(); 1570 MessageOutput.printDirectln(line.toString()); } 1572 } else { 1573 MessageOutput.println("is not a valid id or class name", idClass); 1574 } 1575 } catch (AbsentInformationException e) { 1576 MessageOutput.println("Line number information not available for", idClass); 1577 } 1578 } 1579 } 1580 1581 void commandClasspath(StringTokenizer t) { 1582 if (Env.vm() instanceof PathSearchingVirtualMachine) { 1583 PathSearchingVirtualMachine vm = (PathSearchingVirtualMachine)Env.vm(); 1584 MessageOutput.println("base directory:", vm.baseDirectory()); 1585 MessageOutput.println("classpath:", vm.classPath().toString()); 1586 MessageOutput.println("bootclasspath:", vm.bootClassPath().toString()); 1587 } else { 1588 MessageOutput.println("The VM does not use paths"); 1589 } 1590 } 1591 1592 1593 void commandUse(StringTokenizer t) { 1594 if (!t.hasMoreTokens()) { 1595 MessageOutput.printDirectln(Env.getSourcePath()); } else { 1597 1602 Env.setSourcePath(t.nextToken("").trim()); 1603 } 1604 } 1605 1606 1607 private void printVar(LocalVariable var, Value value) { 1608 MessageOutput.println("expr is value", 1609 new Object [] {var.name(), 1610 value == null ? "null" : value.toString()}); 1611 } 1612 1613 1614 void commandLocals() { 1615 StackFrame frame; 1616 ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo(); 1617 if (threadInfo == null) { 1618 MessageOutput.println("No default thread specified:"); 1619 return; 1620 } 1621 try { 1622 frame = threadInfo.getCurrentFrame(); 1623 if (frame == null) { 1624 throw new AbsentInformationException(); 1625 } 1626 List vars = frame.visibleVariables(); 1627 1628 if (vars.size() == 0) { 1629 MessageOutput.println("No local variables"); 1630 return; 1631 } 1632 Map values = frame.getValues(vars); 1633 1634 MessageOutput.println("Method arguments:"); 1635 for (Iterator it = vars.iterator(); it.hasNext(); ) { 1636 LocalVariable var = (LocalVariable)it.next(); 1637 if (var.isArgument()) { 1638 Value val = (Value)values.get(var); 1639 printVar(var, val); 1640 } 1641 } 1642 MessageOutput.println("Local variables:"); 1643 for (Iterator it = vars.iterator(); it.hasNext(); ) { 1644 LocalVariable var = (LocalVariable)it.next(); 1645 if (!var.isArgument()) { 1646 Value val = (Value)values.get(var); 1647 printVar(var, val); 1648 } 1649 } 1650 } catch (AbsentInformationException aie) { 1651 MessageOutput.println("Local variable information not available."); 1652 } catch (IncompatibleThreadStateException exc) { 1653 MessageOutput.println("Current thread isnt suspended."); 1654 } 1655 } 1656 1657 private void dump(ObjectReference obj, ReferenceType refType, 1658 ReferenceType refTypeBase) { 1659 for (Iterator it = refType.fields().iterator(); it.hasNext(); ) { 1660 StringBuffer o = new StringBuffer (); 1661 Field field = (Field)it.next(); 1662 o.append(" "); 1663 if (!refType.equals(refTypeBase)) { 1664 o.append(refType.name()); 1665 o.append("."); 1666 } 1667 o.append(field.name()); 1668 o.append(MessageOutput.format("colon space")); 1669 o.append(obj.getValue(field)); 1670 MessageOutput.printDirectln(o.toString()); } 1672 if (refType instanceof ClassType) { 1673 ClassType sup = ((ClassType)refType).superclass(); 1674 if (sup != null) { 1675 dump(obj, sup, refTypeBase); 1676 } 1677 } else if (refType instanceof InterfaceType) { 1678 List sups = ((InterfaceType)refType).superinterfaces(); 1679 for (Iterator it = sups.iterator(); it.hasNext(); ) { 1680 dump(obj, (ReferenceType)it.next(), refTypeBase); 1681 } 1682 } else { 1683 1684 if (obj instanceof ArrayReference) { 1685 for (Iterator it = ((ArrayReference)obj).getValues().iterator(); 1686 it.hasNext(); ) { 1687 MessageOutput.printDirect(it.next().toString()); if (it.hasNext()) { 1689 MessageOutput.printDirect(", "); } 1691 } 1692 MessageOutput.println(); 1693 } 1694 } 1695 } 1696 1697 1699 void doPrint(StringTokenizer t, boolean dumpObject) { 1700 if (!t.hasMoreTokens()) { 1701 MessageOutput.println("No objects specified."); 1702 return; 1703 } 1704 1705 while (t.hasMoreTokens()) { 1706 String expr = t.nextToken(""); 1707 Value val = evaluate(expr); 1708 if (val == null) { 1709 MessageOutput.println("expr is null", expr.toString()); 1710 } else if (dumpObject && (val instanceof ObjectReference) && 1711 !(val instanceof StringReference)) { 1712 ObjectReference obj = (ObjectReference)val; 1713 ReferenceType refType = obj.referenceType(); 1714 MessageOutput.println("expr is value", 1715 new Object [] {expr.toString(), 1716 MessageOutput.format("grouping begin character")}); 1717 dump(obj, refType, refType); 1718 MessageOutput.println("grouping end character"); 1719 } else { 1720 String strVal = getStringValue(); 1721 if (strVal != null) { 1722 MessageOutput.println("expr is value", new Object [] {expr.toString(), 1723 strVal}); 1724 } 1725 } 1726 } 1727 } 1728 1729 void commandPrint(final StringTokenizer t, final boolean dumpObject) { 1730 new AsyncExecution() { 1731 void action() { 1732 doPrint(t, dumpObject); 1733 } 1734 }; 1735 } 1736 1737 void commandSet(final StringTokenizer t) { 1738 String all = t.nextToken(""); 1739 1740 1743 if (all.indexOf('=') == -1) { 1744 MessageOutput.println("Invalid assignment syntax"); 1745 MessageOutput.printPrompt(); 1746 return; 1747 } 1748 1749 1753 commandPrint(new StringTokenizer(all), false); 1754 } 1755 1756 void doLock(StringTokenizer t) { 1757 if (!t.hasMoreTokens()) { 1758 MessageOutput.println("No object specified."); 1759 return; 1760 } 1761 1762 String expr = t.nextToken(""); 1763 Value val = evaluate(expr); 1764 1765 try { 1766 if ((val != null) && (val instanceof ObjectReference)) { 1767 ObjectReference object = (ObjectReference)val; 1768 String strVal = getStringValue(); 1769 if (strVal != null) { 1770 MessageOutput.println("Monitor information for expr", 1771 new Object [] {expr.trim(), 1772 strVal}); 1773 } 1774 ThreadReference owner = object.owningThread(); 1775 if (owner == null) { 1776 MessageOutput.println("Not owned"); 1777 } else { 1778 MessageOutput.println("Owned by:", 1779 new Object [] {owner.name(), 1780 new Integer (object.entryCount())}); 1781 } 1782 List waiters = object.waitingThreads(); 1783 if (waiters.size() == 0) { 1784 MessageOutput.println("No waiters"); 1785 } else { 1786 Iterator iter = waiters.iterator(); 1787 while (iter.hasNext()) { 1788 ThreadReference waiter = (ThreadReference)iter.next(); 1789 MessageOutput.println("Waiting thread:", waiter.name()); 1790 } 1791 } 1792 } else { 1793 MessageOutput.println("Expression must evaluate to an object"); 1794 } 1795 } catch (IncompatibleThreadStateException e) { 1796 MessageOutput.println("Threads must be suspended"); 1797 } 1798 } 1799 1800 void commandLock(final StringTokenizer t) { 1801 new AsyncExecution() { 1802 void action() { 1803 doLock(t); 1804 } 1805 }; 1806 } 1807 1808 private void printThreadLockInfo(ThreadInfo threadInfo) { 1809 ThreadReference thread = threadInfo.getThread(); 1810 try { 1811 MessageOutput.println("Monitor information for thread", thread.name()); 1812 List owned = thread.ownedMonitors(); 1813 if (owned.size() == 0) { 1814 MessageOutput.println("No monitors owned"); 1815 } else { 1816 Iterator iter = owned.iterator(); 1817 while (iter.hasNext()) { 1818 ObjectReference monitor = (ObjectReference)iter.next(); 1819 MessageOutput.println("Owned monitor:", monitor.toString()); 1820 } 1821 } 1822 ObjectReference waiting = thread.currentContendedMonitor(); 1823 if (waiting == null) { 1824 MessageOutput.println("Not waiting for a monitor"); 1825 } else { 1826 MessageOutput.println("Waiting for monitor:", waiting.toString()); 1827 } 1828 } catch (IncompatibleThreadStateException e) { 1829 MessageOutput.println("Threads must be suspended"); 1830 } 1831 } 1832 1833 void commandThreadlocks(final StringTokenizer t) { 1834 if (!t.hasMoreTokens()) { 1835 ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo(); 1836 if (threadInfo == null) { 1837 MessageOutput.println("Current thread not set."); 1838 } else { 1839 printThreadLockInfo(threadInfo); 1840 } 1841 return; 1842 } 1843 String token = t.nextToken(); 1844 if (token.toLowerCase().equals("all")) { 1845 Iterator iter = ThreadInfo.threads().iterator(); 1846 while (iter.hasNext()) { 1847 ThreadInfo threadInfo = (ThreadInfo)iter.next(); 1848 printThreadLockInfo(threadInfo); 1849 } 1850 } else { 1851 ThreadInfo threadInfo = doGetThread(token); 1852 if (threadInfo != null) { 1853 ThreadInfo.setCurrentThreadInfo(threadInfo); 1854 printThreadLockInfo(threadInfo); 1855 } 1856 } 1857 } 1858 1859 void doDisableGC(StringTokenizer t) { 1860 if (!t.hasMoreTokens()) { 1861 MessageOutput.println("No object specified."); 1862 return; 1863 } 1864 1865 String expr = t.nextToken(""); 1866 Value val = evaluate(expr); 1867 if ((val != null) && (val instanceof ObjectReference)) { 1868 ObjectReference object = (ObjectReference)val; 1869 object.disableCollection(); 1870 String strVal = getStringValue(); 1871 if (strVal != null) { 1872 MessageOutput.println("GC Disabled for", strVal); 1873 } 1874 } else { 1875 MessageOutput.println("Expression must evaluate to an object"); 1876 } 1877 } 1878 1879 void commandDisableGC(final StringTokenizer t) { 1880 new AsyncExecution() { 1881 void action() { 1882 doDisableGC(t); 1883 } 1884 }; 1885 } 1886 1887 void doEnableGC(StringTokenizer t) { 1888 if (!t.hasMoreTokens()) { 1889 MessageOutput.println("No object specified."); 1890 return; 1891 } 1892 1893 String expr = t.nextToken(""); 1894 Value val = evaluate(expr); 1895 if ((val != null) && (val instanceof ObjectReference)) { 1896 ObjectReference object = (ObjectReference)val; 1897 object.enableCollection(); 1898 String strVal = getStringValue(); 1899 if (strVal != null) { 1900 MessageOutput.println("GC Enabled for", strVal); 1901 } 1902 } else { 1903 MessageOutput.println("Expression must evaluate to an object"); 1904 } 1905 } 1906 1907 void commandEnableGC(final StringTokenizer t) { 1908 new AsyncExecution() { 1909 void action() { 1910 doEnableGC(t); 1911 } 1912 }; 1913 } 1914 1915 void doSave(StringTokenizer t) { if (!t.hasMoreTokens()) { 1917 MessageOutput.println("No save index specified."); 1918 return; 1919 } 1920 1921 String key = t.nextToken(); 1922 1923 if (!t.hasMoreTokens()) { 1924 MessageOutput.println("No expression specified."); 1925 return; 1926 } 1927 String expr = t.nextToken(""); 1928 Value val = evaluate(expr); 1929 if (val != null) { 1930 Env.setSavedValue(key, val); 1931 String strVal = getStringValue(); 1932 if (strVal != null) { 1933 MessageOutput.println("saved", strVal); 1934 } 1935 } else { 1936 MessageOutput.println("Expression cannot be void"); 1937 } 1938 } 1939 1940 void commandSave(final StringTokenizer t) { if (!t.hasMoreTokens()) { 1942 Set keys = Env.getSaveKeys(); 1943 Iterator iter = keys.iterator(); 1944 if (!iter.hasNext()) { 1945 MessageOutput.println("No saved values"); 1946 return; 1947 } 1948 while (iter.hasNext()) { 1949 String key = (String )iter.next(); 1950 Value value = Env.getSavedValue(key); 1951 if ((value instanceof ObjectReference) && 1952 ((ObjectReference)value).isCollected()) { 1953 MessageOutput.println("expr is value <collected>", 1954 new Object [] {key, value.toString()}); 1955 } else { 1956 if (value == null){ 1957 MessageOutput.println("expr is null", key); 1958 } else { 1959 MessageOutput.println("expr is value", 1960 new Object [] {key, value.toString()}); 1961 } 1962 } 1963 } 1964 } else { 1965 new AsyncExecution() { 1966 void action() { 1967 doSave(t); 1968 } 1969 }; 1970 } 1971 1972 } 1973 1974 void commandBytecodes(final StringTokenizer t) { if (!t.hasMoreTokens()) { 1976 MessageOutput.println("No class specified."); 1977 return; 1978 } 1979 String className = t.nextToken(); 1980 1981 if (!t.hasMoreTokens()) { 1982 MessageOutput.println("No method specified."); 1983 return; 1984 } 1985 String methodName = t.nextToken(); 1987 1988 List classes = Env.vm().classesByName(className); 1989 if (classes.size() == 0) { 1991 if (className.indexOf('.') < 0) { 1992 MessageOutput.println("not found (try the full name)", className); 1993 } else { 1994 MessageOutput.println("not found", className); 1995 } 1996 return; 1997 } 1998 1999 ReferenceType rt = (ReferenceType)classes.get(0); 2000 if (!(rt instanceof ClassType)) { 2001 MessageOutput.println("not a class", className); 2002 return; 2003 } 2004 2005 byte[] bytecodes = null; 2006 List list = rt.methodsByName(methodName); 2007 Iterator iter = list.iterator(); 2008 while (iter.hasNext()) { 2009 Method method = (Method)iter.next(); 2010 if (!method.isAbstract()) { 2011 bytecodes = method.bytecodes(); 2012 break; 2013 } 2014 } 2015 2016 StringBuffer line = new StringBuffer (80); 2017 line.append("0000: "); 2018 for (int i = 0; i < bytecodes.length; i++) { 2019 if ((i > 0) && (i % 16 == 0)) { 2020 MessageOutput.printDirectln(line.toString()); line.setLength(0); 2022 line.append(String.valueOf(i)); 2023 line.append(": "); 2024 int len = line.length(); 2025 for (int j = 0; j < 6 - len; j++) { 2026 line.insert(0, '0'); 2027 } 2028 } 2029 int val = 0xff & bytecodes[i]; 2030 String str = Integer.toHexString(val); 2031 if (str.length() == 1) { 2032 line.append('0'); 2033 } 2034 line.append(str); 2035 line.append(' '); 2036 } 2037 if (line.length() > 6) { 2038 MessageOutput.printDirectln(line.toString()); } 2040 } 2041 2042 void commandExclude(StringTokenizer t) { 2043 if (!t.hasMoreTokens()) { 2044 MessageOutput.printDirectln(Env.excludesString()); } else { 2046 String rest = t.nextToken(""); 2047 if (rest.equals("none")) { 2048 rest = ""; 2049 } 2050 Env.setExcludes(rest); 2051 } 2052 } 2053 2054 void commandRedefine(StringTokenizer t) { 2055 if (!t.hasMoreTokens()) { 2056 MessageOutput.println("Specify classes to redefine"); 2057 } else { 2058 String className = t.nextToken(); 2059 List classes = Env.vm().classesByName(className); 2060 if (classes.size() == 0) { 2061 MessageOutput.println("No class named", className); 2062 return; 2063 } 2064 if (classes.size() > 1) { 2065 MessageOutput.println("More than one class named", className); 2066 return; 2067 } 2068 Env.setSourcePath(Env.getSourcePath()); 2069 ReferenceType refType = (ReferenceType)classes.get(0); 2070 if (!t.hasMoreTokens()) { 2071 MessageOutput.println("Specify file name for class", className); 2072 return; 2073 } 2074 String fileName = t.nextToken(); 2075 File phyl = new File(fileName); 2076 byte[] bytes = new byte[(int)phyl.length()]; 2077 try { 2078 InputStream in = new FileInputStream(phyl); 2079 in.read(bytes); 2080 in.close(); 2081 } catch (Exception exc) { 2082 MessageOutput.println("Error reading file", 2083 new Object [] {fileName, exc.toString()}); 2084 return; 2085 } 2086 Map map = new HashMap(); 2087 map.put(refType, bytes); 2088 try { 2089 Env.vm().redefineClasses(map); 2090 } catch (Throwable exc) { 2091 MessageOutput.println("Error redefining class to file", 2092 new Object [] {className, 2093 fileName, 2094 exc}); 2095 } 2096 } 2097 } 2098 2099 void commandPopFrames(StringTokenizer t, boolean reenter) { 2100 ThreadInfo threadInfo; 2101 2102 if (t.hasMoreTokens()) { 2103 String token = t.nextToken(); 2104 threadInfo = doGetThread(token); 2105 if (threadInfo == null) { 2106 return; 2107 } 2108 } else { 2109 threadInfo = ThreadInfo.getCurrentThreadInfo(); 2110 if (threadInfo == null) { 2111 MessageOutput.println("No thread specified."); 2112 return; 2113 } 2114 } 2115 2116 try { 2117 StackFrame frame = threadInfo.getCurrentFrame(); 2118 threadInfo.getThread().popFrames(frame); 2119 threadInfo = ThreadInfo.getCurrentThreadInfo(); 2120 ThreadInfo.setCurrentThreadInfo(threadInfo); 2121 if (reenter) { 2122 commandStepi(); 2123 } 2124 } catch (Throwable exc) { 2125 MessageOutput.println("Error popping frame", exc.toString()); 2126 } 2127 } 2128 2129 void commandExtension(StringTokenizer t) { 2130 if (!t.hasMoreTokens()) { 2131 MessageOutput.println("No class specified."); 2132 return; 2133 } 2134 2135 String idClass = t.nextToken(); 2136 ReferenceType cls = Env.getReferenceTypeFromToken(idClass); 2137 String extension = null; 2138 if (cls != null) { 2139 try { 2140 extension = cls.sourceDebugExtension(); 2141 MessageOutput.println("sourcedebugextension", extension); 2142 } catch (AbsentInformationException e) { 2143 MessageOutput.println("No sourcedebugextension specified"); 2144 } 2145 } else { 2146 MessageOutput.println("is not a valid id or class name", idClass); 2147 } 2148 } 2149 2150 void commandVersion(String debuggerName, 2151 VirtualMachineManager vmm) { 2152 MessageOutput.println("minus version", 2153 new Object [] { debuggerName, 2154 new Integer (vmm.majorInterfaceVersion()), 2155 new Integer (vmm.minorInterfaceVersion()), 2156 System.getProperty("java.version")}); 2157 if (Env.connection() != null) { 2158 try { 2159 MessageOutput.printDirectln(Env.vm().description()); } catch (VMNotConnectedException e) { 2161 MessageOutput.println("No VM connected"); 2162 } 2163 } 2164 } 2165} 2166 | Popular Tags |