1 7 34 35 package com.sun.tools.example.debug.bdi; 36 37 import com.sun.jdi.*; 38 import com.sun.jdi.event.*; 39 import com.sun.jdi.request.*; 40 import com.sun.jdi.connect.*; 41 import com.sun.tools.example.debug.expr.ExpressionParser; 42 import com.sun.tools.example.debug.expr.ParseException; 43 44 import java.io.*; 45 import java.util.*; 46 47 import com.sun.tools.example.debug.event.*; 48 49 import javax.swing.SwingUtilities ; 50 51 55 public class ExecutionManager { 56 57 private Session session; 58 59 62 int traceMode = VirtualMachine.TRACE_NONE; 63 64 66 68 Vector sessionListeners = new Vector(); 69 70 public void addSessionListener(SessionListener listener) { 71 sessionListeners.add(listener); 72 } 73 74 public void removeSessionListener(SessionListener listener) { 75 sessionListeners.remove(listener); 76 } 77 78 80 Vector specListeners = new Vector(); 81 82 public void addSpecListener(SpecListener cl) { 83 specListeners.add(cl); 84 } 85 86 public void removeSpecListener(SpecListener cl) { 87 specListeners.remove(cl); 88 } 89 90 92 Vector jdiListeners = new Vector(); 93 94 97 public void addJDIListener(JDIListener jl) { 98 jdiListeners.add(jl); 99 } 100 101 104 public void addJDIListener(int index, JDIListener jl) { 105 jdiListeners.add(index, jl); 106 } 107 108 111 public void removeJDIListener(JDIListener jl) { 112 jdiListeners.remove(jl); 113 } 114 115 117 private Vector appEchoListeners = new Vector(); 118 119 public void addApplicationEchoListener(OutputListener l) { 120 appEchoListeners.addElement(l); 121 } 122 123 public void removeApplicationEchoListener(OutputListener l) { 124 appEchoListeners.removeElement(l); 125 } 126 127 129 private Vector appOutputListeners = new Vector(); 130 131 public void addApplicationOutputListener(OutputListener l) { 132 appOutputListeners.addElement(l); 133 } 134 135 public void removeApplicationOutputListener(OutputListener l) { 136 appOutputListeners.removeElement(l); 137 } 138 139 141 private Vector appErrorListeners = new Vector(); 142 143 public void addApplicationErrorListener(OutputListener l) { 144 appErrorListeners.addElement(l); 145 } 146 147 public void removeApplicationErrorListener(OutputListener l) { 148 appErrorListeners.removeElement(l); 149 } 150 151 153 private Vector diagnosticsListeners = new Vector(); 154 155 public void addDiagnosticsListener(OutputListener l) { 156 diagnosticsListeners.addElement(l); 157 } 158 159 public void removeDiagnosticsListener(OutputListener l) { 160 diagnosticsListeners.removeElement(l); 161 } 162 163 165 public VirtualMachine vm() { 167 return session == null ? null : session.vm; 168 } 169 170 void ensureActiveSession() throws NoSessionException { 171 if (session == null) throw new NoSessionException(); 172 } 173 174 public EventRequestManager eventRequestManager() { 175 return vm() == null ? null : vm().eventRequestManager(); 176 } 177 178 181 public int getTraceMode(int mode) { 182 return traceMode; 183 } 184 185 188 public void setTraceMode(int mode) { 189 traceMode = mode; 190 if (session != null) { 191 session.setTraceMode(mode); 192 } 193 } 194 195 198 public boolean isInterrupted() { 199 return session.interrupted; 201 } 202 203 208 public List allClasses() throws NoSessionException { 209 ensureActiveSession(); 210 return vm().allClasses(); 211 } 212 213 223 public List findClassesByName(String name) throws NoSessionException { 224 ensureActiveSession(); 225 return vm().classesByName(name); 226 } 227 228 237 public List findClassesMatchingPattern(String pattern) 238 throws NoSessionException { 239 ensureActiveSession(); 240 List result = new ArrayList(); if (pattern.startsWith("*.")) { 242 pattern = pattern.substring(1); 244 List classes = vm().allClasses(); 245 Iterator iter = classes.iterator(); 246 while (iter.hasNext()) { 247 ReferenceType type = ((ReferenceType)iter.next()); 248 if (type.name().endsWith(pattern)) { 249 result.add(type); 250 } 251 } 252 return result; 253 } else { 254 return vm().classesByName(pattern); 256 } 257 } 258 259 265 266 public List allThreads() throws NoSessionException { 267 ensureActiveSession(); 268 return vm().allThreads(); 269 } 270 271 277 278 public List topLevelThreadGroups() throws NoSessionException { 279 ensureActiveSession(); 280 return vm().topLevelThreadGroups(); 281 } 282 283 286 287 public ThreadGroupReference systemThreadGroup() 288 throws NoSessionException { 289 ensureActiveSession(); 290 return (ThreadGroupReference)vm().topLevelThreadGroups().get(0); 291 } 292 293 296 297 public Value evaluate(final StackFrame f, String expr) 298 throws ParseException, 299 InvocationException, 300 InvalidTypeException, 301 ClassNotLoadedException, 302 NoSessionException, 303 IncompatibleThreadStateException { 304 ExpressionParser.GetFrame frameGetter = null; 305 ensureActiveSession(); 306 if (f != null) { 307 frameGetter = new ExpressionParser.GetFrame() { 308 public StackFrame get() { 309 return f; 310 } 311 }; 312 } 313 return ExpressionParser.evaluate(expr, vm(), frameGetter); 314 } 315 316 317 320 321 public void run(boolean suspended, 322 String vmArgs, 323 String className, 324 String args) throws VMLaunchFailureException { 325 326 endSession(); 327 328 if (suspended) { 331 List argList = new ArrayList(1); 333 argList.add("java.lang.String[]"); 334 createMethodBreakpoint(className, "main", argList); 335 } 336 337 String cmdLine = className + " " + args; 338 339 startSession(new ChildSession(this, vmArgs, cmdLine, 340 appInput, appOutput, appError, 341 diagnostics)); 342 } 343 344 347 public void attach(String portName) throws VMLaunchFailureException { 348 endSession(); 349 350 355 360 VirtualMachineManager mgr = Bootstrap.virtualMachineManager(); 361 List connectors = mgr.attachingConnectors(); 362 AttachingConnector connector = (AttachingConnector)connectors.get(0); 363 Map arguments = connector.defaultArguments(); 364 ((Connector.Argument)arguments.get("port")).setValue(portName); 365 366 Session newSession = internalAttach(connector, arguments); 367 if (newSession != null) { 368 startSession(newSession); 369 } 370 } 371 372 private Session internalAttach(AttachingConnector connector, 373 Map arguments) { 374 try { 375 VirtualMachine vm = connector.attach(arguments); 376 return new Session(vm, this, diagnostics); 377 } catch (IOException ioe) { 378 diagnostics.putString("\n Unable to attach to target VM: " + 379 ioe.getMessage()); 380 } catch (IllegalConnectorArgumentsException icae) { 381 diagnostics.putString("\n Invalid connector arguments: " + 382 icae.getMessage()); 383 } 384 return null; 385 } 386 387 private Session internalListen(ListeningConnector connector, 388 Map arguments) { 389 try { 390 VirtualMachine vm = connector.accept(arguments); 391 return new Session(vm, this, diagnostics); 392 } catch (IOException ioe) { 393 diagnostics.putString( 394 "\n Unable to accept connection to target VM: " + 395 ioe.getMessage()); 396 } catch (IllegalConnectorArgumentsException icae) { 397 diagnostics.putString("\n Invalid connector arguments: " + 398 icae.getMessage()); 399 } 400 return null; 401 } 402 403 407 public boolean explictStart(Connector connector, Map arguments) 408 throws VMLaunchFailureException { 409 Session newSession = null; 410 411 endSession(); 412 413 if (connector instanceof LaunchingConnector) { 414 newSession = new ChildSession(this, (LaunchingConnector)connector, 416 arguments, 417 appInput, appOutput, appError, 418 diagnostics); 419 } else if (connector instanceof AttachingConnector) { 420 newSession = internalAttach((AttachingConnector)connector, 421 arguments); 422 } else if (connector instanceof ListeningConnector) { 423 newSession = internalListen((ListeningConnector)connector, 424 arguments); 425 } else { 426 diagnostics.putString("\n Unknown connector: " + connector); 427 } 428 if (newSession != null) { 429 startSession(newSession); 430 } 431 return newSession != null; 432 } 433 434 437 public void detach() throws NoSessionException { 438 ensureActiveSession(); 439 endSession(); 440 } 441 442 private void startSession(Session s) throws VMLaunchFailureException { 443 if (!s.attach()) { 444 throw new VMLaunchFailureException(); 445 } 446 session = s; 447 EventRequestManager em = vm().eventRequestManager(); 448 ClassPrepareRequest classPrepareRequest = em.createClassPrepareRequest(); 449 classPrepareRequest.setSuspendPolicy(EventRequest.SUSPEND_ALL); 454 classPrepareRequest.enable(); 455 ClassUnloadRequest classUnloadRequest = em.createClassUnloadRequest(); 456 classUnloadRequest.setSuspendPolicy(EventRequest.SUSPEND_NONE); 457 classUnloadRequest.enable(); 458 ThreadStartRequest threadStartRequest = em.createThreadStartRequest(); 459 threadStartRequest.setSuspendPolicy(EventRequest.SUSPEND_NONE); 460 threadStartRequest.enable(); 461 ThreadDeathRequest threadDeathRequest = em.createThreadDeathRequest(); 462 threadDeathRequest.setSuspendPolicy(EventRequest.SUSPEND_NONE); 463 threadDeathRequest.enable(); 464 ExceptionRequest exceptionRequest = 465 em.createExceptionRequest(null, false, true); 466 exceptionRequest.setSuspendPolicy(EventRequest.SUSPEND_ALL); 467 exceptionRequest.enable(); 468 validateThreadInfo(); 469 session.interrupted = true; 470 notifySessionStart(); 471 } 472 473 void endSession() { 474 if (session != null) { 475 session.detach(); 476 session = null; 477 invalidateThreadInfo(); 478 notifySessionDeath(); 479 } 480 } 481 482 485 486 public void interrupt() throws NoSessionException { 487 ensureActiveSession(); 488 vm().suspend(); 489 validateThreadInfo(); 491 session.interrupted = true; 492 notifyInterrupted(); 493 } 494 495 498 499 public void go() throws NoSessionException, VMNotInterruptedException { 500 ensureActiveSession(); 501 invalidateThreadInfo(); 502 session.interrupted = false; 503 notifyContinued(); 504 vm().resume(); 505 } 506 507 510 void clearPreviousStep(ThreadReference thread) { 511 515 EventRequestManager mgr = vm().eventRequestManager(); 516 List requests = mgr.stepRequests(); 517 Iterator iter = requests.iterator(); 518 while (iter.hasNext()) { 519 StepRequest request = (StepRequest)iter.next(); 520 if (request.thread().equals(thread)) { 521 mgr.deleteEventRequest(request); 522 break; 523 } 524 } 525 } 526 527 private void generalStep(ThreadReference thread, int size, int depth) 528 throws NoSessionException { 529 ensureActiveSession(); 530 invalidateThreadInfo(); 531 session.interrupted = false; 532 notifyContinued(); 533 534 clearPreviousStep(thread); 535 EventRequestManager reqMgr = vm().eventRequestManager(); 536 StepRequest request = reqMgr.createStepRequest(thread, 537 size, depth); 538 request.addCountFilter(1); 540 request.enable(); 541 vm().resume(); 542 } 543 544 public void stepIntoInstruction(ThreadReference thread) 545 throws NoSessionException { 546 generalStep(thread, StepRequest.STEP_MIN, StepRequest.STEP_INTO); 547 } 548 549 public void stepOverInstruction(ThreadReference thread) 550 throws NoSessionException { 551 generalStep(thread, StepRequest.STEP_MIN, StepRequest.STEP_OVER); 552 } 553 554 public void stepIntoLine(ThreadReference thread) 555 throws NoSessionException, 556 AbsentInformationException { 557 generalStep(thread, StepRequest.STEP_LINE, StepRequest.STEP_INTO); 558 } 559 560 public void stepOverLine(ThreadReference thread) 561 throws NoSessionException, 562 AbsentInformationException { 563 generalStep(thread, StepRequest.STEP_LINE, StepRequest.STEP_OVER); 564 } 565 566 public void stepOut(ThreadReference thread) 567 throws NoSessionException { 568 generalStep(thread, StepRequest.STEP_MIN, StepRequest.STEP_OUT); 569 } 570 571 574 575 public void suspendThread(ThreadReference thread) throws NoSessionException { 576 ensureActiveSession(); 577 thread.suspend(); 578 } 579 580 public void resumeThread(ThreadReference thread) throws NoSessionException { 581 ensureActiveSession(); 582 thread.resume(); 583 } 584 585 public void stopThread(ThreadReference thread) throws NoSessionException { 586 ensureActiveSession(); 587 } 590 591 594 595 private List threadInfoList = new LinkedList(); 596 private HashMap threadInfoMap = new HashMap(); 598 599 public ThreadInfo threadInfo(ThreadReference thread) { 600 if (session == null || thread == null) { 601 return null; 602 } 603 ThreadInfo info = (ThreadInfo)threadInfoMap.get(thread); 604 if (info == null) { 605 info = new ThreadInfo(thread); 608 if (session.interrupted) { 609 info.validate(); 610 } 611 threadInfoList.add(info); 612 threadInfoMap.put(thread, info); 613 } 614 return info; 615 } 616 617 void validateThreadInfo() { 618 session.interrupted = true; 619 Iterator iter = threadInfoList.iterator(); 620 while (iter.hasNext()) { 621 ((ThreadInfo)iter.next()).validate(); 622 } 623 } 624 625 private void invalidateThreadInfo() { 626 if (session != null) { 627 session.interrupted = false; 628 Iterator iter = threadInfoList.iterator(); 629 while (iter.hasNext()) { 630 ((ThreadInfo)iter.next()).invalidate(); 631 } 632 } 633 } 634 635 void removeThreadInfo(ThreadReference thread) { 636 ThreadInfo info = (ThreadInfo)threadInfoMap.get(thread); 637 if (info != null) { 638 info.invalidate(); 639 threadInfoMap.remove(thread); 640 threadInfoList.remove(info); 641 } 642 } 643 644 647 648 private void notifyInterrupted() { 649 Vector l = (Vector)sessionListeners.clone(); 650 EventObject evt = new EventObject(this); 651 for (int i = 0; i < l.size(); i++) { 652 ((SessionListener)l.elementAt(i)).sessionInterrupt(evt); 653 } 654 } 655 656 private void notifyContinued() { 657 Vector l = (Vector)sessionListeners.clone(); 658 EventObject evt = new EventObject(this); 659 for (int i = 0; i < l.size(); i++) { 660 ((SessionListener)l.elementAt(i)).sessionContinue(evt); 661 } 662 } 663 664 private void notifySessionStart() { 665 Vector l = (Vector)sessionListeners.clone(); 666 EventObject evt = new EventObject(this); 667 for (int i = 0; i < l.size(); i++) { 668 ((SessionListener)l.elementAt(i)).sessionStart(evt); 669 } 670 } 671 672 private void notifySessionDeath() { 673 680 } 681 682 687 688 private Object inputLock = new Object (); 689 private LinkedList inputBuffer = new LinkedList(); 690 691 private void resetInputBuffer() { 692 synchronized (inputLock) { 693 inputBuffer = new LinkedList(); 694 } 695 } 696 697 public void sendLineToApplication(String line) { 698 synchronized (inputLock) { 699 inputBuffer.addFirst(line); 700 inputLock.notifyAll(); 701 } 702 } 703 704 private InputListener appInput = new InputListener() { 705 public String getLine() { 706 String line = null; 708 while (line == null) { 709 synchronized (inputLock) { 710 try { 711 while (inputBuffer.size() < 1) { 712 inputLock.wait(); 713 } 714 line = (String )inputBuffer.removeLast(); 715 } catch (InterruptedException e) {} 716 } 717 } 718 final String input = line; 723 SwingUtilities.invokeLater(new Runnable () { 724 public void run() { 725 echoInputLine(input); 726 } 727 }); 728 return line; 729 } 730 }; 731 732 private static String newline = System.getProperty("line.separator"); 733 734 private void echoInputLine(String line) { 735 Vector l = (Vector)appEchoListeners.clone(); 736 for (int i = 0; i < l.size(); i++) { 737 OutputListener ol = (OutputListener)l.elementAt(i); 738 ol.putString(line); 739 ol.putString(newline); 740 } 741 } 742 743 private OutputListener appOutput = new OutputListener() { 744 public void putString(String string) { 745 Vector l = (Vector)appOutputListeners.clone(); 746 for (int i = 0; i < l.size(); i++) { 747 ((OutputListener)l.elementAt(i)).putString(string); 748 } 749 } 750 }; 751 752 private OutputListener appError = new OutputListener() { 753 public void putString(String string) { 754 Vector l = (Vector)appErrorListeners.clone(); 755 for (int i = 0; i < l.size(); i++) { 756 ((OutputListener)l.elementAt(i)).putString(string); 757 } 758 } 759 }; 760 761 private OutputListener diagnostics = new OutputListener() { 762 public void putString(String string) { 763 Vector l = (Vector)diagnosticsListeners.clone(); 764 for (int i = 0; i < l.size(); i++) { 765 ((OutputListener)l.elementAt(i)).putString(string); 766 } 767 } 768 }; 769 770 772 private EventRequestSpecList specList = new EventRequestSpecList(this); 773 774 public BreakpointSpec 775 createSourceLineBreakpoint(String sourceName, int line) { 776 return specList.createSourceLineBreakpoint(sourceName, line); 777 } 778 779 public BreakpointSpec 780 createClassLineBreakpoint(String classPattern, int line) { 781 return specList.createClassLineBreakpoint(classPattern, line); 782 } 783 784 public BreakpointSpec 785 createMethodBreakpoint(String classPattern, 786 String methodId, List methodArgs) { 787 return specList.createMethodBreakpoint(classPattern, 788 methodId, methodArgs); 789 } 790 791 public ExceptionSpec 792 createExceptionIntercept(String classPattern, 793 boolean notifyCaught, 794 boolean notifyUncaught) { 795 return specList.createExceptionIntercept(classPattern, 796 notifyCaught, 797 notifyUncaught); 798 } 799 800 public AccessWatchpointSpec 801 createAccessWatchpoint(String classPattern, String fieldId) { 802 return specList.createAccessWatchpoint(classPattern, fieldId); 803 } 804 805 public ModificationWatchpointSpec 806 createModificationWatchpoint(String classPattern, String fieldId) { 807 return specList.createModificationWatchpoint(classPattern, 808 fieldId); 809 } 810 811 public void delete(EventRequestSpec spec) { 812 specList.delete(spec); 813 } 814 815 void resolve(ReferenceType refType) { 816 specList.resolve(refType); 817 } 818 819 public void install(EventRequestSpec spec) { 820 specList.install(spec, vm()); 821 } 822 823 public List eventRequestSpecs() { 824 return specList.eventRequestSpecs(); 825 } 826 } 827 | Popular Tags |