1 19 20 package org.netbeans.modules.debugger.jpda; 21 22 import com.sun.jdi.AbsentInformationException; 23 import com.sun.jdi.Bootstrap; 24 import com.sun.jdi.IncompatibleThreadStateException; 25 import com.sun.jdi.InvalidStackFrameException; 26 import com.sun.jdi.LocalVariable; 27 import com.sun.jdi.Method; 28 import com.sun.jdi.ObjectReference; 29 import com.sun.jdi.ReferenceType; 30 import com.sun.jdi.StackFrame; 31 import com.sun.jdi.ThreadGroupReference; 32 import com.sun.jdi.ThreadReference; 33 import com.sun.jdi.TypeComponent; 34 import com.sun.jdi.VMDisconnectedException; 35 import com.sun.jdi.Value; 36 import com.sun.jdi.VirtualMachine; 37 import com.sun.jdi.request.EventRequest; 38 import com.sun.jdi.request.EventRequestManager; 39 import com.sun.jdi.request.InvalidRequestStateException; 40 41 import java.beans.PropertyChangeEvent ; 42 import java.beans.PropertyChangeListener ; 43 import java.beans.PropertyChangeSupport ; 44 import java.util.ArrayList ; 45 import java.util.Arrays ; 46 import java.util.Collection ; 47 import java.util.Collections ; 48 import java.util.HashSet ; 49 import java.util.Iterator ; 50 import java.util.List ; 51 import java.util.Set ; 52 import java.lang.reflect.InvocationTargetException ; 53 import java.util.HashMap ; 54 import java.util.Map ; 55 import java.util.logging.Level ; 56 import java.util.logging.Logger ; 57 import org.netbeans.api.debugger.DebuggerEngine; 58 59 import org.netbeans.api.debugger.DebuggerInfo; 60 import org.netbeans.api.debugger.DebuggerManager; 61 import org.netbeans.api.debugger.LazyActionsManagerListener; 62 import org.netbeans.api.debugger.Properties; 63 64 import org.netbeans.api.debugger.jpda.InvalidExpressionException; 65 import org.netbeans.api.debugger.jpda.JPDAClassType; 66 import org.netbeans.api.debugger.jpda.JPDAThreadGroup; 67 import org.netbeans.modules.debugger.jpda.actions.CompoundSmartSteppingListener; 68 import org.netbeans.modules.debugger.jpda.expr.EvaluationException; 69 import org.netbeans.modules.debugger.jpda.models.ObjectTranslation; 70 import org.netbeans.modules.debugger.jpda.util.JPDAUtils; 71 import org.netbeans.spi.debugger.ContextProvider; 72 import org.netbeans.api.debugger.Session; 73 import org.netbeans.api.debugger.jpda.AbstractDICookie; 74 import org.netbeans.api.debugger.jpda.AttachingDICookie; 75 import org.netbeans.api.debugger.jpda.CallStackFrame; 76 import org.netbeans.api.debugger.jpda.DebuggerStartException; 77 import org.netbeans.api.debugger.jpda.JPDABreakpoint; 78 import org.netbeans.api.debugger.jpda.event.JPDABreakpointEvent; 79 import org.netbeans.api.debugger.jpda.JPDADebugger; 80 import org.netbeans.api.debugger.jpda.JPDAThread; 81 import org.netbeans.api.debugger.jpda.SmartSteppingFilter; 82 import org.netbeans.api.debugger.jpda.Variable; 83 import org.netbeans.api.debugger.jpda.JPDAStep; 84 import org.netbeans.modules.debugger.jpda.breakpoints.BreakpointsEngineListener; 85 86 import org.netbeans.modules.debugger.jpda.models.JPDAThreadImpl; 87 import org.netbeans.modules.debugger.jpda.models.LocalsTreeModel; 88 import org.netbeans.modules.debugger.jpda.models.ThreadsTreeModel; 89 import org.netbeans.modules.debugger.jpda.models.CallStackFrameImpl; 90 import org.netbeans.modules.debugger.jpda.util.Operator; 91 import org.netbeans.modules.debugger.jpda.expr.Expression; 92 import org.netbeans.modules.debugger.jpda.expr.EvaluationContext; 93 import org.netbeans.modules.debugger.jpda.expr.ParseException; 94 import org.netbeans.spi.debugger.DebuggerEngineProvider; 95 import org.netbeans.spi.debugger.DelegatingSessionProvider; 96 97 import org.netbeans.spi.viewmodel.TreeModel; 98 import org.netbeans.spi.viewmodel.UnknownTypeException; 99 import org.openide.ErrorManager; 100 101 106 public class JPDADebuggerImpl extends JPDADebugger { 107 108 private static final Logger logger = Logger.getLogger("org.netbeans.modules.debugger.jpda"); 109 110 private static final boolean SINGLE_THREAD_STEPPING = Boolean.getBoolean("netbeans.debugger.singleThreadStepping"); 111 112 113 115 private VirtualMachine virtualMachine = null; 117 private Exception exception; 118 private int state = 0; 119 private Operator operator; 120 private PropertyChangeSupport pcs; 121 private JPDAThreadImpl currentThread; 122 private CallStackFrame currentCallStackFrame; 123 private int suspend = (SINGLE_THREAD_STEPPING) ? SUSPEND_EVENT_THREAD : SUSPEND_ALL; 124 public final Object LOCK = new Object (); 125 private final Object LOCK2 = new Object (); 126 private boolean starting; 127 private JavaEngineProvider javaEngineProvider; 128 private Set <String > languages; 129 private String lastStratumn; 130 private ContextProvider lookupProvider; 131 private ObjectTranslation threadsTranslation; 132 private ObjectTranslation localsTranslation; 133 private ExpressionPool expressionPool; 134 135 private StackFrame altCSF = null; 137 private boolean doContinue = true; 139 141 public JPDADebuggerImpl (ContextProvider lookupProvider) { 142 this.lookupProvider = lookupProvider; 143 pcs = new PropertyChangeSupport (this); 144 List l = lookupProvider.lookup (null, DebuggerEngineProvider.class); 145 int i, k = l.size (); 146 for (i = 0; i < k; i++) 147 if (l.get (i) instanceof JavaEngineProvider) 148 javaEngineProvider = (JavaEngineProvider) l.get (i); 149 if (javaEngineProvider == null) 150 throw new IllegalArgumentException 151 ("JavaEngineProvider have to be used to start JPDADebugger!"); 152 languages = new HashSet <String >(); 153 languages.add ("Java"); 154 threadsTranslation = ObjectTranslation.createThreadTranslation(this); 155 localsTranslation = ObjectTranslation.createLocalsTranslation(this); 156 this.expressionPool = new ExpressionPool(); 157 } 158 159 160 162 171 public int getState () { 172 return state; 173 } 174 175 180 public int getSuspend () { 181 return suspend; 182 } 183 184 189 public void setSuspend (int s) { 190 if (s == suspend) return; 191 int old = suspend; 192 suspend = s; 193 firePropertyChange (PROP_SUSPEND, new Integer (old), new Integer (s)); 194 } 195 196 201 public JPDAThread getCurrentThread () { 202 return currentThread; 203 } 204 205 210 public synchronized CallStackFrame getCurrentCallStackFrame () { 211 if (currentCallStackFrame != null) { 212 try { 213 if (!currentCallStackFrame.getThread().isSuspended()) { 214 currentCallStackFrame = null; 215 } 216 } catch (InvalidStackFrameException isfex) { 217 currentCallStackFrame = null; 218 } 219 } 220 if (currentCallStackFrame == null && currentThread != null) { 221 try { 222 currentCallStackFrame = currentThread.getCallStack(0, 1)[0]; 223 } catch (Exception ex) {} 224 } 225 return currentCallStackFrame; 226 } 227 228 235 public Variable evaluate (String expression) 236 throws InvalidExpressionException { 237 Value v = evaluateIn (expression); 238 return getLocalsTreeModel ().getVariable (v); 239 } 240 241 250 public void waitRunning () throws DebuggerStartException { 251 synchronized (LOCK2) { 252 if (getState () == STATE_DISCONNECTED) { 253 if (exception != null) 254 throw new DebuggerStartException (exception); 255 else 256 return; 257 } 258 if (!starting && state != STATE_STARTING || exception != null) { 259 return ; } 261 try { 262 LOCK2.wait (); 263 } catch (InterruptedException e) { 264 throw new DebuggerStartException (e); 265 } 266 267 if (exception != null) 268 throw new DebuggerStartException (exception); 269 else 270 return; 271 } 272 } 273 274 279 public boolean canPopFrames () { 280 VirtualMachine vm = getVirtualMachine (); 281 if (vm == null) return false; 282 return vm.canPopFrames (); 283 } 284 285 291 public boolean canFixClasses () { 292 VirtualMachine vm = getVirtualMachine (); 293 if (vm == null) return false; 294 return vm.canRedefineClasses (); 295 } 296 297 303 public void fixClasses (Map <String , byte[]> classes) { 304 synchronized (LOCK) { 305 306 Map <ReferenceType, byte[]> map = new HashMap <ReferenceType, byte[]>(); 308 Iterator <String > i = classes.keySet ().iterator (); 309 VirtualMachine vm = getVirtualMachine(); 310 if (vm == null) { 311 return ; } 313 while (i.hasNext ()) { 314 String className = i.next (); 315 List <ReferenceType> classRefs = vm.classesByName (className); 316 int j, jj = classRefs.size (); 317 for (j = 0; j < jj; j++) 318 map.put ( 319 classRefs.get (j), 320 classes.get (className) 321 ); 322 } 323 vm.redefineClasses (map); 324 325 Session s = (Session) 327 lookupProvider.lookupFirst (null, Session.class); 328 DebuggerEngine de = s.getEngineForLanguage ("Java"); 329 BreakpointsEngineListener bel = null; 330 List lazyListeners = de.lookup(null, LazyActionsManagerListener.class); 331 for (int li = 0; li < lazyListeners.size(); li++) { 332 Object service = lazyListeners.get(li); 333 if (service instanceof BreakpointsEngineListener) { 334 bel = (BreakpointsEngineListener) service; 335 break; 336 } 337 } 338 bel.fixBreakpointImpls (); 339 340 JPDAThread t = getCurrentThread (); 342 if (t != null && t.isSuspended()) { 343 CallStackFrame frame = getCurrentCallStackFrame (); 344 345 if (t.getStackDepth () < 2 && frame.isObsolete()) return; 347 try { 348 if (!frame.equals (t.getCallStack (0, 1) [0])) return; 349 } catch (AbsentInformationException ex) { 350 return; 351 } 352 353 if (frame.isObsolete () && ((CallStackFrameImpl) frame).canPop()) { 355 frame.popFrame (); 356 setState (STATE_RUNNING); 357 updateCurrentCallStackFrame (t); 358 setState (STATE_STOPPED); 359 } 360 } 361 362 } 363 } 364 365 private Boolean canBeModified; 366 private Object canBeModifiedLock = new Object (); 367 368 public boolean canBeModified() { 369 VirtualMachine vm = getVirtualMachine (); 370 if (vm == null) return false; 371 synchronized (canBeModifiedLock) { 372 if (canBeModified == null) { 373 try { 374 java.lang.reflect.Method canBeModifiedMethod = 375 com.sun.jdi.VirtualMachine.class.getMethod("canBeModified", new Class [] {}); 376 Object modifiable = canBeModifiedMethod.invoke(vm, new Object [] {}); 377 canBeModified = (Boolean ) modifiable; 378 } catch (NoSuchMethodException nsmex) { 379 canBeModified = Boolean.TRUE; 381 } catch (IllegalAccessException iaex) { 382 canBeModified = Boolean.TRUE; 383 } catch (InvocationTargetException itex) { 384 canBeModified = Boolean.TRUE; 385 } 386 } 387 return canBeModified.booleanValue(); 388 } 389 } 391 392 private SmartSteppingFilter smartSteppingFilter; 393 394 399 public SmartSteppingFilter getSmartSteppingFilter () { 400 if (smartSteppingFilter == null) { 401 smartSteppingFilter = (SmartSteppingFilter) lookupProvider. 402 lookupFirst (null, SmartSteppingFilter.class); 403 smartSteppingFilter.addExclusionPatterns ( 404 (Set ) Properties.getDefault ().getProperties ("debugger"). 405 getProperties ("sources").getProperties ("class_filters"). 406 getCollection ( 407 "enabled", 408 Collections.EMPTY_SET 409 ) 410 ); 411 } 412 return smartSteppingFilter; 413 } 414 415 CompoundSmartSteppingListener compoundSmartSteppingListener; 416 417 private CompoundSmartSteppingListener getCompoundSmartSteppingListener () { 418 if (compoundSmartSteppingListener == null) 419 compoundSmartSteppingListener = (CompoundSmartSteppingListener) lookupProvider. 420 lookupFirst (null, CompoundSmartSteppingListener.class); 421 return compoundSmartSteppingListener; 422 } 423 424 427 boolean stopHere(JPDAThread t) { 428 return getCompoundSmartSteppingListener ().stopHere 429 (lookupProvider, t, getSmartSteppingFilter()); 430 } 431 432 438 public void fireBreakpointEvent ( 439 JPDABreakpoint breakpoint, 440 JPDABreakpointEvent event 441 ) { 442 super.fireBreakpointEvent (breakpoint, event); 443 } 444 445 450 public void addPropertyChangeListener (PropertyChangeListener l) { 451 pcs.addPropertyChangeListener (l); 452 } 453 454 459 public void removePropertyChangeListener (PropertyChangeListener l) { 460 pcs.removePropertyChangeListener (l); 461 } 462 463 468 public void addPropertyChangeListener (String propertyName, PropertyChangeListener l) { 469 pcs.addPropertyChangeListener (propertyName, l); 470 } 471 472 477 public void removePropertyChangeListener (String propertyName, PropertyChangeListener l) { 478 pcs.removePropertyChangeListener (propertyName, l); 479 } 480 481 482 484 public void popFrames (ThreadReference thread, StackFrame frame) { 485 synchronized (LOCK) { 486 JPDAThreadImpl threadImpl = (JPDAThreadImpl) getThread(thread); 487 setState (STATE_RUNNING); 488 try { 489 threadImpl.popFrames(frame); 490 updateCurrentCallStackFrame (threadImpl); 491 } catch (IncompatibleThreadStateException ex) { 492 ErrorManager.getDefault().notify(ex); 493 } finally { 494 setState (STATE_STOPPED); 495 } 496 } 497 } 498 499 public void setException (Exception e) { 500 synchronized (LOCK2) { 501 exception = e; 502 starting = false; 503 LOCK2.notify (); 504 } 505 } 506 507 public void setCurrentThread (JPDAThread thread) { 508 Object oldT = currentThread; 509 currentThread = (JPDAThreadImpl) thread; 510 if (thread != oldT) 511 pcs.firePropertyChange (PROP_CURRENT_THREAD, oldT, currentThread); 512 updateCurrentCallStackFrame (thread); 513 } 514 515 520 private PropertyChangeEvent setCurrentThreadNoFire(JPDAThread thread) { 521 Object oldT = currentThread; 522 currentThread = (JPDAThreadImpl) thread; 523 PropertyChangeEvent evt = null; 524 if (thread != oldT) 525 evt = new PropertyChangeEvent (this, PROP_CURRENT_THREAD, oldT, currentThread); 526 PropertyChangeEvent evt2 = updateCurrentCallStackFrameNoFire(thread); 527 if (evt == null) evt = evt2; 528 else if (evt2 != null) evt.setPropagationId(evt2); 529 return evt; 530 } 531 532 public void setCurrentCallStackFrame (CallStackFrame callStackFrame) { 533 CallStackFrame old = setCurrentCallStackFrameNoFire(callStackFrame); 534 if (old == callStackFrame) return ; 535 pcs.firePropertyChange ( 536 PROP_CURRENT_CALL_STACK_FRAME, 537 old, 538 callStackFrame 539 ); 540 } 541 542 private CallStackFrame setCurrentCallStackFrameNoFire (CallStackFrame callStackFrame) { 543 CallStackFrame old; 544 synchronized (this) { 545 if (callStackFrame == currentCallStackFrame) return callStackFrame; 546 old = currentCallStackFrame; 547 currentCallStackFrame = callStackFrame; 548 } 549 return old; 550 } 551 552 555 public Value evaluateIn (String expression) throws InvalidExpressionException { 556 Expression expr = null; 557 try { 558 expr = Expression.parse (expression, Expression.LANGUAGE_JAVA_1_5); 559 return evaluateIn (expr); 560 } catch (ParseException e) { 561 InvalidExpressionException iee = new InvalidExpressionException(e.getMessage()); 562 iee.initCause(e); 563 throw iee; 564 } 565 } 566 567 public void setAltCSF(StackFrame sf) { 569 altCSF = sf; 570 } 571 572 public StackFrame getAltCSF() { 573 return altCSF; 574 } 575 576 579 public Value evaluateIn (Expression expression) 580 throws InvalidExpressionException { 581 synchronized (LOCK) { 582 583 CallStackFrameImpl csf = (CallStackFrameImpl) 584 getCurrentCallStackFrame (); 585 if (csf != null) { 586 JPDAThread frameThread = csf.getThread(); 587 try { 588 Value value = evaluateIn (expression, csf.getStackFrame ()); 589 try { 590 csf.getThread(); 591 } catch (InvalidStackFrameException isfex) { 592 int depth = csf.getFrameDepth(); 594 try { 595 CallStackFrame csf2 = frameThread.getCallStack(depth, depth + 1)[0]; 596 setCurrentCallStackFrameNoFire(csf2); 597 } catch (AbsentInformationException aiex) { 598 setCurrentCallStackFrame(null); 599 } 600 } 601 return value; 602 } catch (com.sun.jdi.VMDisconnectedException e) { 603 return null; 605 } 606 } 607 if (altCSF != null) { 609 try { 610 if (!altCSF.thread().isSuspended()) { 611 altCSF = null; } else { 613 return evaluateIn (expression, altCSF); 615 } 616 } catch (InvalidStackFrameException isfex) { 617 altCSF = null; } catch (com.sun.jdi.VMDisconnectedException e) { 620 return null; 622 } 623 } 624 throw new InvalidExpressionException 625 ("No current context (stack frame)"); 626 627 } 628 } 629 630 private InvalidExpressionException methodCallsUnsupportedExc; 631 632 635 public Value evaluateIn (Expression expression, final StackFrame frame) 636 throws InvalidExpressionException { 637 synchronized (LOCK) { 638 if (frame == null) 639 throw new InvalidExpressionException ("No current context"); 640 641 List <String > imports = new ArrayList <String >(); 643 List <String > staticImports = new ArrayList <String >(); 644 imports.add ("java.lang.*"); 645 try { 646 imports.addAll (Arrays.asList (EditorContextBridge.getImports ( 647 getEngineContext ().getURL (frame, "Java") 648 ))); 649 final ThreadReference tr = frame.thread(); 650 final List <EventRequest>[] disabledBreakpoints = 651 new List [] { null }; 652 final JPDAThreadImpl[] resumedThread = new JPDAThreadImpl[] { null }; 653 EvaluationContext context; 654 org.netbeans.modules.debugger.jpda.expr.Evaluator evaluator = 655 expression.evaluator ( 656 context = new EvaluationContext ( 657 frame, 658 imports, 659 staticImports, 660 methodCallsUnsupportedExc == null, 661 new Runnable () { 662 public void run() { 663 if (disabledBreakpoints[0] == null) { 664 disabledBreakpoints[0] = disableAllBreakpoints (); 665 resumedThread[0] = (JPDAThreadImpl) getThread(tr); 666 resumedThread[0].notifyMethodInvoking(); 667 } 668 } 669 }, 670 this 671 ) 672 ); 673 try { 674 return evaluator.evaluate (); 675 } finally { 676 if (methodCallsUnsupportedExc == null && !context.canInvokeMethods()) { 677 methodCallsUnsupportedExc = 678 new InvalidExpressionException(new UnsupportedOperationException ()); 679 } 680 if (disabledBreakpoints[0] != null) { 681 enableAllBreakpoints (disabledBreakpoints[0]); 682 } 683 if (resumedThread[0] != null) { 684 resumedThread[0].notifyMethodInvokeDone(); 685 } 686 } 687 } catch (EvaluationException e) { 688 InvalidExpressionException iee = new InvalidExpressionException (e); 689 iee.initCause (e); 690 throw iee; 691 } catch (IncompatibleThreadStateException itsex) { 692 ErrorManager.getDefault().notify(itsex); 693 IllegalStateException isex = new IllegalStateException (itsex.getLocalizedMessage()); 694 isex.initCause(itsex); 695 throw isex; 696 } 697 } 698 } 699 700 703 public Value invokeMethod ( 704 ObjectReference reference, 705 Method method, 706 Value[] arguments 707 ) throws InvalidExpressionException { 708 if (currentThread == null) 709 throw new InvalidExpressionException ("No current context"); 710 synchronized (LOCK) { 711 if (methodCallsUnsupportedExc != null) { 712 throw methodCallsUnsupportedExc; 713 } 714 List <EventRequest> l = disableAllBreakpoints (); 715 ThreadReference tr = getEvaluationThread(); 716 JPDAThreadImpl thread = (JPDAThreadImpl) getThread(tr); 717 boolean threadSuspended = thread.isSuspended(); 718 CallStackFrameImpl csf = (CallStackFrameImpl) 720 getCurrentCallStackFrame (); 721 JPDAThread frameThread = null; 722 if (csf != null) { 723 try { 724 frameThread = csf.getThread(); 725 } catch (InvalidStackFrameException isfex) {} 726 } 727 thread.notifyMethodInvoking(); 728 try { 729 return org.netbeans.modules.debugger.jpda.expr.Evaluator. 730 invokeVirtual ( 731 reference, 732 method, 733 tr, 734 Arrays.asList (arguments) 735 ); 736 } catch (InvalidExpressionException ieex) { 737 if (ieex.getTargetException() instanceof UnsupportedOperationException ) { 738 methodCallsUnsupportedExc = ieex; 739 } 740 throw ieex; 741 } finally { 742 if (threadSuspended) { 743 thread.notifyMethodInvokeDone(); 744 } 745 enableAllBreakpoints (l); 746 if (frameThread != null) { 747 try { 748 csf.getThread(); 749 } catch (InvalidStackFrameException isfex) { 750 int depth = csf.getFrameDepth(); 752 try { 753 CallStackFrame csf2 = frameThread.getCallStack(depth, depth + 1)[0]; 754 setCurrentCallStackFrameNoFire(csf2); 755 } catch (AbsentInformationException aiex) { 756 setCurrentCallStackFrame(null); 757 } 758 } 759 } 760 } 761 } 762 } 763 764 public static String getGenericSignature (TypeComponent component) { 765 if (tcGenericSignatureMethod == null) return null; 766 try { 767 return (String ) tcGenericSignatureMethod.invoke 768 (component, new Object [0]); 769 } catch (IllegalAccessException e) { 770 e.printStackTrace(); 771 return null; } catch (InvocationTargetException e) { 773 e.printStackTrace(); 774 return null; } 776 } 777 778 public static String getGenericSignature (LocalVariable component) { 779 if (lvGenericSignatureMethod == null) return null; 780 try { 781 return (String ) lvGenericSignatureMethod.invoke(component, new Object [0]); 782 } catch (IllegalAccessException e) { 783 e.printStackTrace(); 784 return null; } catch (InvocationTargetException e) { 786 e.printStackTrace(); 787 return null; } 789 } 790 791 public VirtualMachine getVirtualMachine () { 792 return virtualMachine; 793 } 794 795 public Operator getOperator () { 796 return operator; 797 } 798 799 public void setStarting () { 800 setState (STATE_STARTING); 801 } 802 803 public void setRunning (VirtualMachine vm, Operator o) { 804 if (logger.isLoggable(Level.FINE)) { 805 logger.fine("Start - JPDADebuggerImpl.setRunning ()"); 806 JPDAUtils.printFeatures (logger, vm); 807 } 808 synchronized (LOCK2) { 809 starting = true; 810 } 811 synchronized (this) { 812 virtualMachine = vm; 813 } 814 synchronized (canBeModifiedLock) { 815 canBeModified = null; } 817 818 initGenericsSupport (); 819 820 operator = o; 821 822 845 setState (STATE_RUNNING); 846 synchronized (this) { 847 vm = virtualMachine; } 849 if (vm != null) { 850 synchronized (LOCK) { 851 vm.resume(); 852 } 853 } 854 855 logger.fine(" JPDADebuggerImpl.setRunning () finished, VM resumed."); 856 synchronized (LOCK2) { 857 starting = false; 858 LOCK2.notify (); 859 } 860 } 861 862 865 public void setStoppedState (ThreadReference thread) { 866 PropertyChangeEvent evt; 867 synchronized (LOCK) { 868 JPDAThread t = getThread (thread); 871 checkJSR45Languages (t); 872 evt = setCurrentThreadNoFire(t); 873 PropertyChangeEvent evt2 = setStateNoFire(STATE_STOPPED); 874 875 if (evt == null) evt = evt2; 876 else if (evt2 != null) { 877 PropertyChangeEvent evt3 = evt; 878 while(evt3.getPropagationId() != null) evt3 = (PropertyChangeEvent ) evt3.getPropagationId(); 879 evt3.setPropagationId(evt2); 880 } 881 } 882 if (evt != null) { 883 do { 884 firePropertyChange(evt); 885 evt = (PropertyChangeEvent ) evt.getPropagationId(); 886 } while (evt != null); 887 } 888 } 889 890 893 public void setStoppedStateNoContinue (ThreadReference thread) { 894 PropertyChangeEvent evt; 895 synchronized (LOCK) { 896 evt = setStateNoFire(STATE_RUNNING); 899 JPDAThread t = getThread (thread); 900 checkJSR45Languages (t); 901 PropertyChangeEvent evt2 = setCurrentThreadNoFire(t); 902 903 if (evt == null) evt = evt2; 904 else if (evt2 != null) evt.setPropagationId(evt2); 905 906 evt2 = setStateNoFire(STATE_STOPPED); 907 908 if (evt == null) evt = evt2; 909 else if (evt2 != null) { 910 PropertyChangeEvent evt3 = evt; 911 while(evt3.getPropagationId() != null) evt3 = (PropertyChangeEvent ) evt3.getPropagationId(); 912 evt3.setPropagationId(evt2); 913 } 914 915 doContinue = false; 916 } 917 if (evt != null) { 918 do { 919 firePropertyChange(evt); 920 evt = (PropertyChangeEvent ) evt.getPropagationId(); 921 } while (evt != null); 922 } 923 } 924 925 926 private boolean finishing; 927 928 931 public void finish () { 932 synchronized (this) { 935 if (finishing) { 936 return ; 938 } 939 finishing = true; 940 } 941 logger.fine("StartActionProvider.finish ()"); 942 AbstractDICookie di = (AbstractDICookie) lookupProvider.lookupFirst 943 (null, AbstractDICookie.class); 944 if (getState () == STATE_DISCONNECTED) return; 945 Operator o = getOperator(); 946 if (o != null) o.stop(); 947 try { 948 waitRunning(); } catch (DebuggerStartException dsex) { 950 } 952 VirtualMachine vm; 953 synchronized (this) { 954 vm = virtualMachine; 955 } 956 if (vm != null) { 957 try { 958 if (di instanceof AttachingDICookie) { 959 logger.fine(" StartActionProvider.finish() VM dispose"); 960 vm.dispose (); 961 } else { 962 logger.fine(" StartActionProvider.finish() VM exit"); 963 vm.exit (0); 964 } 965 } catch (VMDisconnectedException e) { 966 logger.fine(" StartActionProvider.finish() VM exception " + e); 967 } 969 } 970 synchronized (this) { 971 virtualMachine = null; 972 } 973 setState (STATE_DISCONNECTED); 974 if (jsr45EngineProviders != null) { 975 for (Iterator <JSR45DebuggerEngineProvider> i = jsr45EngineProviders.iterator(); i.hasNext();) { 976 JSR45DebuggerEngineProvider provider = i.next(); 977 provider.getDesctuctor().killEngine(); 978 } 979 jsr45EngineProviders = null; 980 } 981 javaEngineProvider.getDestructor ().killEngine (); 982 logger.fine (" StartActionProvider.finish() end."); 983 984 synchronized (LOCK2) { 986 starting = false; 987 LOCK2.notify (); 988 } 989 } 991 992 998 public void suspend () { 999 VirtualMachine vm; 1000 synchronized (this) { 1001 vm = virtualMachine; 1002 } 1003 synchronized (LOCK) { 1004 if (getState () == STATE_STOPPED) 1005 return; 1006 if (vm != null) { 1007 logger.fine("VM suspend"); 1008 vm.suspend (); 1009 List <ThreadReference> threads = vm.allThreads(); 1011 for (ThreadReference t : threads) { 1012 while (t.suspendCount() > 1) t.resume(); 1013 } 1014 } 1015 setState (STATE_STOPPED); 1016 } 1017 notifySuspendAll(); 1018 } 1019 1020 public void notifySuspendAll() { 1021 Collection threads = threadsTranslation.getTranslated(); 1022 for (Iterator it = threads.iterator(); it.hasNext(); ) { 1023 Object threadOrGroup = it.next(); 1024 if (threadOrGroup instanceof JPDAThreadImpl) { 1025 ((JPDAThreadImpl) threadOrGroup).notifySuspended(); 1026 } 1027 } 1028 } 1029 1030 1033 public void resume () { 1034 synchronized (LOCK) { 1035 if (!doContinue) { 1036 doContinue = true; 1037 return ; 1039 } 1040 } 1041 if (operator.flushStaledEvents()) { 1042 return ; 1043 } 1044 setState (STATE_RUNNING); 1045 notifyToBeResumedAll(); 1046 VirtualMachine vm; 1047 synchronized (this) { 1048 vm = virtualMachine; 1049 } 1050 synchronized (LOCK) { 1051 if (vm != null) { 1052 logger.fine("VM resume"); 1053 vm.resume (); 1054 } 1055 } 1056 } 1057 1058 1059 public boolean currentThreadToBeResumed() { 1060 synchronized (LOCK) { 1061 if (!doContinue) { 1062 doContinue = true; 1063 return false; 1065 } 1066 } 1067 if (operator.flushStaledEvents()) { 1068 return false; 1069 } 1070 setState (STATE_RUNNING); 1071 return true; 1072 } 1073 1074 public void resumeCurrentThread() { 1075 synchronized (LOCK) { 1076 if (!doContinue) { 1077 doContinue = true; 1078 return ; 1080 } 1081 } 1082 if (operator.flushStaledEvents()) { 1083 return ; 1084 } 1085 setState (STATE_RUNNING); 1086 currentThread.resume(); 1087 } 1088 1089 public void notifyToBeResumedAll() { 1090 Collection threads = threadsTranslation.getTranslated(); 1091 for (Iterator it = threads.iterator(); it.hasNext(); ) { 1092 Object threadOrGroup = it.next(); 1093 if (threadOrGroup instanceof JPDAThreadImpl) { 1094 ((JPDAThreadImpl) threadOrGroup).notifyToBeResumed(); 1095 } 1096 } 1097 } 1098 1099 public JPDAThreadGroup[] getTopLevelThreadGroups() { 1100 VirtualMachine vm; 1101 synchronized (this) { 1102 vm = virtualMachine; 1103 } 1104 if (vm == null) { 1105 return new JPDAThreadGroup[0]; 1106 } 1107 List groupList; 1108 synchronized (LOCK) { 1109 groupList = vm.topLevelThreadGroups(); 1110 } 1111 JPDAThreadGroup[] groups = new JPDAThreadGroup[groupList.size()]; 1112 for (int i = 0; i < groups.length; i++) { 1113 groups[i] = getThreadGroup((ThreadGroupReference) groupList.get(i)); 1114 } 1115 return groups; 1116 } 1117 1118 public JPDAThread getThread (ThreadReference tr) { 1119 return (JPDAThread) threadsTranslation.translate (tr); 1120 } 1121 1122 public JPDAThreadGroup getThreadGroup (ThreadGroupReference tgr) { 1123 return (JPDAThreadGroup) threadsTranslation.translate (tgr); 1124 } 1125 1126 public Variable getLocalVariable(LocalVariable lv, Value v) { 1127 return (Variable) localsTranslation.translate(lv, v); 1128 } 1129 1130 public JPDAClassType getClassType(ReferenceType cr) { 1131 return (JPDAClassType) localsTranslation.translate (cr); 1132 } 1133 1134 public Variable getVariable (Value value) { 1135 return getLocalsTreeModel ().getVariable (value); 1136 } 1137 1138 public ExpressionPool getExpressionPool() { 1139 return expressionPool; 1140 } 1141 1142 1143 1145 private static final java.util.regex.Pattern jvmVersionPattern = 1146 java.util.regex.Pattern.compile ("(\\d+)\\.(\\d+)\\.(\\d+)(_\\d+)?(-\\w+)?"); 1147 private static java.lang.reflect.Method tcGenericSignatureMethod; 1148 private static java.lang.reflect.Method lvGenericSignatureMethod; 1149 1150 1151 private void initGenericsSupport () { 1152 tcGenericSignatureMethod = null; 1153 if (Bootstrap.virtualMachineManager ().minorInterfaceVersion () >= 5) { 1154 VirtualMachine vm; 1155 synchronized (this) { 1156 vm = virtualMachine; 1157 } 1158 if (vm == null) return ; 1159 java.util.regex.Matcher m = jvmVersionPattern.matcher(vm.version ()); 1160 if (m.matches ()) { 1161 int minor = Integer.parseInt (m.group (2)); 1162 if (minor >= 5) { 1163 try { 1164 tcGenericSignatureMethod = TypeComponent.class. 1165 getMethod ("genericSignature", new Class [0]); 1166 lvGenericSignatureMethod = LocalVariable.class. 1167 getMethod ("genericSignature", new Class [0]); 1168 } catch (NoSuchMethodException e) { 1169 } 1171 } 1172 } 1173 } 1174 } 1175 1176 private PropertyChangeEvent setStateNoFire (int state) { 1177 if (state == this.state) return null; 1178 int o = this.state; 1179 this.state = state; 1180 System.setProperty( 1182 "org.openide.awt.SwingBrowserImpl.do-not-block-awt", 1183 String.valueOf (state != STATE_DISCONNECTED) 1184 ); 1185 return new PropertyChangeEvent (this, PROP_STATE, new Integer (o), new Integer (state)); 1186 } 1187 1188 private void setState (int state) { 1189 PropertyChangeEvent evt = setStateNoFire(state); 1190 if (evt != null) { 1191 firePropertyChange(evt); 1192 } 1193 } 1194 1195 1198 private void firePropertyChange (String name, Object o, Object n) { 1199 pcs.firePropertyChange (name, o, n); 1200 } 1201 1202 1205 private void firePropertyChange (PropertyChangeEvent evt) { 1206 pcs.firePropertyChange (evt); 1207 } 1208 1209 private SourcePath engineContext; 1210 public synchronized SourcePath getEngineContext () { 1211 if (engineContext == null) 1212 engineContext = (SourcePath) lookupProvider. 1213 lookupFirst (null, SourcePath.class); 1214 return engineContext; 1215 } 1216 1217 private LocalsTreeModel localsTreeModel; 1218 private LocalsTreeModel getLocalsTreeModel () { 1219 if (localsTreeModel == null) 1220 localsTreeModel = (LocalsTreeModel) lookupProvider. 1221 lookupFirst ("LocalsView", TreeModel.class); 1222 return localsTreeModel; 1223 } 1224 1225 private ThreadReference getEvaluationThread () { 1226 if (currentThread != null) return currentThread.getThreadReference (); 1227 VirtualMachine vm; 1228 synchronized (this) { 1229 vm = virtualMachine; 1230 } 1231 if (vm == null) return null; 1232 List l = vm.allThreads (); 1233 if (l.size () < 1) return null; 1234 int i, k = l.size (); 1235 ThreadReference thread = null; 1236 for (i = 0; i < k; i++) { 1237 ThreadReference t = (ThreadReference) l.get (i); 1238 if (t.isSuspended ()) { 1239 thread = t; 1240 if (t.name ().equals ("Finalizer")) 1241 return t; 1242 } 1243 } 1244 return thread; 1245 } 1246 1247 private void updateCurrentCallStackFrame (JPDAThread thread) { 1248 if ( (thread == null) || 1249 (thread.getStackDepth () < 1)) 1250 setCurrentCallStackFrame (null); 1251 else 1252 try { 1253 setCurrentCallStackFrame (thread.getCallStack (0, 1) [0]); 1254 } catch (AbsentInformationException e) { 1255 setCurrentCallStackFrame (null); 1256 } 1257 } 1258 1259 1263 private PropertyChangeEvent updateCurrentCallStackFrameNoFire(JPDAThread thread) { 1264 CallStackFrame old; 1265 CallStackFrame callStackFrame; 1266 if ( (thread == null) || 1267 (thread.getStackDepth () < 1)) 1268 old = setCurrentCallStackFrameNoFire(callStackFrame = null); 1269 else 1270 try { 1271 old = setCurrentCallStackFrameNoFire(callStackFrame = thread.getCallStack (0, 1) [0]); 1272 } catch (AbsentInformationException e) { 1273 old = setCurrentCallStackFrameNoFire(callStackFrame = null); 1274 } 1275 if (old == callStackFrame) return null; 1276 else return new PropertyChangeEvent (this, PROP_CURRENT_CALL_STACK_FRAME, 1277 old, callStackFrame); 1278 } 1279 1280 private List <EventRequest> disableAllBreakpoints () { 1281 List <EventRequest> l = new ArrayList <EventRequest>(); 1282 VirtualMachine vm = getVirtualMachine (); 1283 if (vm == null) return l; 1284 EventRequestManager erm = vm.eventRequestManager (); 1285 l.addAll (erm.accessWatchpointRequests ()); 1286 l.addAll (erm.breakpointRequests ()); 1287 l.addAll (erm.classPrepareRequests ()); 1288 l.addAll (erm.classUnloadRequests ()); 1289 l.addAll (erm.exceptionRequests ()); 1290 l.addAll (erm.methodEntryRequests ()); 1291 l.addAll (erm.methodExitRequests ()); 1292 l.addAll (erm.modificationWatchpointRequests ()); 1293 l.addAll (erm.threadDeathRequests ()); 1295 l.addAll (erm.threadStartRequests ()); 1296 int i = l.size () - 1; 1297 for (; i >= 0; i--) 1298 if (!l.get (i).isEnabled ()) 1299 l.remove (i); 1300 else 1301 l.get (i).disable (); 1302 operator.breakpointsDisabled(); 1303 return l; 1304 } 1305 1306 private void enableAllBreakpoints (List <EventRequest> l) { 1307 operator.breakpointsEnabled(); 1308 int i, k = l.size (); 1309 for (i = 0; i < k; i++) 1310 try { 1311 l.get (i).enable (); 1312 } catch (IllegalThreadStateException ex) { 1313 } catch (InvalidRequestStateException ex) { 1317 } 1319 } 1320 1321 private void checkJSR45Languages (JPDAThread t) { 1322 if (t.getStackDepth () > 0) 1323 try { 1324 CallStackFrame f = t.getCallStack (0, 1) [0]; 1325 List l = f.getAvailableStrata (); 1326 int i, k = l.size (); 1327 for (i = 0; i < k; i++) { 1328 if (!languages.contains (l.get (i))) { 1329 String language = (String ) l.get (i); 1330 DebuggerManager.getDebuggerManager ().startDebugging ( 1331 createJSR45DI (language) 1332 ); 1333 languages.add (language); 1334 } 1335 } String stratum = f.getDefaultStratum (); 1337 if ( (stratum != null) && 1338 (!stratum.equals (lastStratumn)) 1339 ) 1340 javaEngineProvider.getSession ().setCurrentLanguage (stratum); 1341 lastStratumn = stratum; 1342 } catch (AbsentInformationException e) { 1343 System.out.println("NoInformationException"); 1344 } 1345 } 1346 1347 private Set <JSR45DebuggerEngineProvider> jsr45EngineProviders; 1348 1349 private DebuggerInfo createJSR45DI (final String language) { 1350 if (jsr45EngineProviders == null) { 1351 jsr45EngineProviders = new HashSet <JSR45DebuggerEngineProvider>(1); 1352 } 1353 JSR45DebuggerEngineProvider provider = new JSR45DebuggerEngineProvider(language); 1354 jsr45EngineProviders.add(provider); 1355 return DebuggerInfo.create ( 1356 "netbeans-jpda-JSR45DICookie-" + language, 1357 new Object [] { 1358 new DelegatingSessionProvider () { 1359 public Session getSession ( 1360 DebuggerInfo debuggerInfo 1361 ) { 1362 return javaEngineProvider.getSession (); 1363 } 1364 }, 1365 provider 1366 } 1367 ); 1368 } 1369 1370 public JPDAStep createJPDAStep(int size, int depth) { 1371 Session session = (Session) lookupProvider.lookupFirst (null, Session.class); 1372 return new JPDAStepImpl(this, session, size, depth); 1373 } 1374} 1375 | Popular Tags |