@Override public final void action() throws Exception { if (LOG.isDebugEnabled()) { LOG.debug("trying " + this); } final SuspendContextImpl suspendContext = getSuspendContext(); if (suspendContext == null) { if (LOG.isDebugEnabled()) { LOG.debug("skip processing - context is null " + this); } notifyCancelled(); return; } if (suspendContext.myInProgress) { suspendContext.postponeCommand(this); } else { try { if (!suspendContext.isResumed()) { suspendContext.myInProgress = true; contextAction(suspendContext); } else { notifyCancelled(); } } finally { suspendContext.myInProgress = false; if (suspendContext.isResumed()) { for (SuspendContextCommandImpl postponed = suspendContext.pollPostponedCommand(); postponed != null; postponed = suspendContext.pollPostponedCommand()) { postponed.notifyCancelled(); } } else { SuspendContextCommandImpl postponed = suspendContext.pollPostponedCommand(); if (postponed != null) { final Stack<SuspendContextCommandImpl> stack = new Stack<>(); while (postponed != null) { stack.push(postponed); postponed = suspendContext.pollPostponedCommand(); } final DebuggerManagerThreadImpl managerThread = suspendContext.getDebugProcess().getManagerThread(); while (!stack.isEmpty()) { managerThread.pushBack(stack.pop()); } } } } } }
@Override public void createRequest(@NotNull DebugProcessImpl debugProcess) { DebuggerManagerThreadImpl.assertIsManagerThread(); // check is this breakpoint is enabled, vm reference is valid and there're no requests created // yet if (!isEnabled() || !debugProcess.isAttached() || isMuted(debugProcess) || !debugProcess.getRequestsManager().findRequests(this).isEmpty()) { return; } if (!isValid()) { return; } SourcePosition position = getSourcePosition(); if (position != null) { createOrWaitPrepare(debugProcess, position); } else { LOG.error( "Unable to create request for breakpoint with null position: " + getDisplayName() + " at " + myXBreakpoint.getSourcePosition()); } updateUI(); }
public void initExecutionStacks(ThreadReferenceProxyImpl newThread) { DebuggerManagerThreadImpl.assertIsManagerThread(); myThread = newThread; if (newThread != null) { myActiveExecutionStack = new JavaExecutionStack(newThread, myDebugProcess, true); } }
protected void commandCancelled() { if (!DebuggerManagerThreadImpl.isManagerThread()) { return; } // context thread is not suspended final DebuggerContextImpl context = getDebuggerContext(); final SuspendContextImpl suspendContext = context.getSuspendContext(); if (suspendContext == null) { return; } final ThreadReferenceProxyImpl threadToSelect = context.getThreadProxy(); if (threadToSelect == null) { return; } if (!suspendContext.isResumed()) { final SuspendContextImpl threadContext = SuspendManagerUtil.getSuspendContextForThread(suspendContext, threadToSelect); context .getDebugProcess() .getManagerThread() .schedule(new RebuildFramesListCommand(context, threadContext)); refillThreadsCombo(threadToSelect); } }
public void redefineClasses(Map<ReferenceType, byte[]> map) { DebuggerManagerThreadImpl.assertIsManagerThread(); try { myVirtualMachine.redefineClasses(map); } finally { clearCaches(); } }
public void threadGroupCreated(ThreadGroupReference threadGroupReference) { DebuggerManagerThreadImpl.assertIsManagerThread(); if (!isJ2ME()) { ThreadGroupReferenceProxyImpl proxy = new ThreadGroupReferenceProxyImpl(this, threadGroupReference); myThreadGroups.put(threadGroupReference, proxy); } }
static JavaValue create( JavaValue parent, @NotNull ValueDescriptorImpl valueDescriptor, @NotNull EvaluationContextImpl evaluationContext, NodeManagerImpl nodeManager, boolean contextSet) { DebuggerManagerThreadImpl.assertIsManagerThread(); return new JavaValue(parent, valueDescriptor, evaluationContext, nodeManager, contextSet); }
@Nullable @Contract("null -> null; !null -> !null") public ThreadReferenceProxyImpl getThreadReferenceProxy(@Nullable ThreadReference thread) { DebuggerManagerThreadImpl.assertIsManagerThread(); if (thread == null) { return null; } return myAllThreads.computeIfAbsent(thread, t -> new ThreadReferenceProxyImpl(this, t)); }
@Override public Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException { DebuggerManagerThreadImpl.assertIsManagerThread(); try { return (myObject != null) ? myObject.getValue(myField) : myField.declaringType().getValue(myField); } catch (ObjectCollectedException ignored) { throw EvaluateExceptionUtil.OBJECT_WAS_COLLECTED; } }
public void reBuild(final XValueNodeImpl node) { DebuggerManagerThreadImpl.assertIsManagerThread(); myCurrentChildrenStart = 0; node.getTree() .getLaterInvocator() .offer( new Runnable() { @Override public void run() { node.clearChildren(); computePresentation(node, XValuePlace.TREE); } }); }
public ThreadGroupReferenceProxyImpl getThreadGroupReferenceProxy(ThreadGroupReference group) { DebuggerManagerThreadImpl.assertIsManagerThread(); if (group == null) { return null; } ThreadGroupReferenceProxyImpl proxy = myThreadGroups.get(group); if (proxy == null) { if (!myIsJ2ME.isAvailable()) { proxy = new ThreadGroupReferenceProxyImpl(this, group); myThreadGroups.put(group, proxy); } } return proxy; }
public static List<Pair<Breakpoint, Event>> getEventDescriptors( SuspendContextImpl suspendContext) { DebuggerManagerThreadImpl.assertIsManagerThread(); if (suspendContext == null || suspendContext.getEventSet() == null) { return Collections.emptyList(); } final List<Pair<Breakpoint, Event>> eventDescriptors = new ArrayList<Pair<Breakpoint, Event>>(); final RequestManagerImpl requestManager = suspendContext.getDebugProcess().getRequestsManager(); for (final Event event : suspendContext.getEventSet()) { Requestor requestor = requestManager.findRequestor(event.request()); if (requestor instanceof Breakpoint) { eventDescriptors.add(new Pair<Breakpoint, Event>((Breakpoint) requestor, event)); } } return eventDescriptors; }
@Override public void buildChildren( final Value value, final ChildrenBuilder builder, final EvaluationContext evaluationContext) { DebuggerManagerThreadImpl.assertIsManagerThread(); final ValueDescriptorImpl parentDescriptor = (ValueDescriptorImpl) builder.getParentDescriptor(); final NodeManager nodeManager = builder.getNodeManager(); final NodeDescriptorFactory nodeDescriptorFactory = builder.getDescriptorManager(); List<DebuggerTreeNode> children = new ArrayList<>(); if (value instanceof ObjectReference) { final ObjectReference objRef = (ObjectReference) value; final ReferenceType refType = objRef.referenceType(); // default ObjectReference processing List<Field> fields = refType.allFields(); if (!fields.isEmpty()) { Set<String> names = new HashSet<>(); for (Field field : fields) { if (shouldDisplay(evaluationContext, objRef, field)) { FieldDescriptor fieldDescriptor = createFieldDescriptor( parentDescriptor, nodeDescriptorFactory, objRef, field, evaluationContext); String name = fieldDescriptor.getName(); if (names.contains(name)) { fieldDescriptor.putUserData(FieldDescriptor.SHOW_DECLARING_TYPE, Boolean.TRUE); } else { names.add(name); } children.add(nodeManager.createNode(fieldDescriptor, evaluationContext)); } } if (children.isEmpty()) { children.add( nodeManager.createMessageNode( DebuggerBundle.message("message.node.class.no.fields.to.display"))); } else if (XDebuggerSettingsManager.getInstance().getDataViewSettings().isSortValues()) { children.sort(NodeManagerImpl.getNodeComparator()); } } else { children.add( nodeManager.createMessageNode(MessageDescriptor.CLASS_HAS_NO_FIELDS.getLabel())); } } builder.setChildren(children); }
DebuggerContextImpl getFrameDebuggerContext() { DebuggerManagerThreadImpl.assertIsManagerThread(); DebuggerContextImpl context = myDebugProcess.getDebuggerContext(); if (context.getFrameProxy() != getStackFrameProxy()) { SuspendContextImpl threadSuspendContext = SuspendManagerUtil.getSuspendContextForThread( context.getSuspendContext(), getStackFrameProxy().threadProxy()); context = DebuggerContextImpl.createDebuggerContext( myDebugProcess.mySession, threadSuspendContext, getStackFrameProxy().threadProxy(), getStackFrameProxy()); context.setPositionCache(myDescriptor.getSourcePosition()); context.initCaches(); } return context; }
public void resume() { DebuggerManagerThreadImpl.assertIsManagerThread(); if (myPausePressedCount > 0) { myPausePressedCount--; } clearCaches(); LOG.debug("before resume VM"); try { myVirtualMachine.resume(); } catch (InternalException e) { // ok to ignore. Although documentation says it is safe to invoke resume() on running VM, // sometimes this leads to com.sun.jdi.InternalException: Unexpected JDWP Error: 13 // (THREAD_NOT_SUSPENDED) LOG.info(e); } LOG.debug("VM resumed"); // logThreads(); }
@Override public void createRequest(@NotNull DebugProcessImpl debugProcess) { DebuggerManagerThreadImpl.assertIsManagerThread(); // check is this breakpoint is enabled, vm reference is valid and there're no requests created // yet if (!isEnabled() || !debugProcess.isAttached() || isMuted(debugProcess) || !debugProcess.getRequestsManager().findRequests(this).isEmpty()) { return; } if (!isValid()) { return; } createOrWaitPrepare(debugProcess, getSourcePosition()); updateUI(); }
/** @return a list of all ThreadReferenceProxies */ public Collection<ThreadReferenceProxyImpl> allThreads() { DebuggerManagerThreadImpl.assertIsManagerThread(); if (myAllThreadsDirty) { myAllThreadsDirty = false; final List<ThreadReference> currentThreads = myVirtualMachine.allThreads(); final Map<ThreadReference, ThreadReferenceProxyImpl> result = new HashMap<>(); for (final ThreadReference threadReference : currentThreads) { ThreadReferenceProxyImpl proxy = myAllThreads.get(threadReference); if (proxy == null) { proxy = new ThreadReferenceProxyImpl(this, threadReference); } result.put(threadReference, proxy); } myAllThreads = result; } return myAllThreads.values(); }
protected void resume() { assertNotResumed(); DebuggerManagerThreadImpl.assertIsManagerThread(); try { if (!Patches.IBM_JDK_DISABLE_COLLECTION_BUG) { for (ObjectReference objectReference : myKeptReferences) { DebuggerUtilsEx.enableCollection(objectReference); } myKeptReferences.clear(); } for (SuspendContextCommandImpl cmd = pollPostponedCommand(); cmd != null; cmd = pollPostponedCommand()) { cmd.notifyCancelled(); } resumeImpl(); } finally { myIsResumed = true; } }
public void createRequest(DebugProcessImpl debugProcess) { DebuggerManagerThreadImpl.assertIsManagerThread(); if (!ENABLED || !debugProcess.isAttached() || debugProcess.areBreakpointsMuted() || !debugProcess.getRequestsManager().findRequests(this).isEmpty()) { return; } try { RequestManagerImpl requestManager = debugProcess.getRequestsManager(); if (WATCH_ENTRY) { MethodEntryRequest entryRequest = (MethodEntryRequest) findRequest(debugProcess, MethodEntryRequest.class); if (entryRequest == null) { entryRequest = requestManager.createMethodEntryRequest(this); } else { entryRequest.disable(); } entryRequest.addClassFilter(myClassPattern); debugProcess.getRequestsManager().enableRequest(entryRequest); } if (WATCH_EXIT) { MethodExitRequest exitRequest = (MethodExitRequest) findRequest(debugProcess, MethodExitRequest.class); if (exitRequest == null) { exitRequest = requestManager.createMethodExitRequest(this); } else { exitRequest.disable(); } exitRequest.addClassFilter(myClassPattern); debugProcess.getRequestsManager().enableRequest(exitRequest); } } catch (Exception e) { LOG.debug(e); } }
public void setRenderer(NodeRenderer nodeRenderer, final XValueNodeImpl node) { DebuggerManagerThreadImpl.assertIsManagerThread(); myValueDescriptor.setRenderer(nodeRenderer); reBuild(node); }
@Override public boolean isExpandable( Value value, EvaluationContext evaluationContext, NodeDescriptor parentDescriptor) { DebuggerManagerThreadImpl.assertIsManagerThread(); return valueExpandable(value); }
public void threadStarted(ThreadReference thread) { DebuggerManagerThreadImpl.assertIsManagerThread(); getThreadReferenceProxy(thread); // add a proxy }
public void threadStopped(ThreadReference thread) { DebuggerManagerThreadImpl.assertIsManagerThread(); myAllThreads.remove(thread); }
public void suspend() { DebuggerManagerThreadImpl.assertIsManagerThread(); myPausePressedCount++; myVirtualMachine.suspend(); clearCaches(); }
@Override public boolean isDebuggerManagerThread() { return DebuggerManagerThreadImpl.isManagerThread(); }
public void threadGroupRemoved(ThreadGroupReference threadGroupReference) { DebuggerManagerThreadImpl.assertIsManagerThread(); myThreadGroups.remove(threadGroupReference); }
public void contextAction() throws Exception { final ThreadReferenceProxyImpl thread = myDebuggerContext.getThreadProxy(); try { if (!getSuspendContext().getDebugProcess().getSuspendManager().isSuspended(thread)) { DebuggerInvocationUtil.swingInvokeLater( getProject(), new Runnable() { public void run() { try { myFramesListener.setEnabled(false); synchronized (myFramesList) { final DefaultListModel model = myFramesList.getModel(); model.clear(); model.addElement( new Object() { public String toString() { return DebuggerBundle.message("frame.panel.frames.not.available"); } }); myFramesList.setSelectedIndex(0); } } finally { myFramesListener.setEnabled(true); } } }); return; } } catch (ObjectCollectedException e) { return; } List<StackFrameProxyImpl> frames; try { frames = thread.frames(); } catch (EvaluateException e) { frames = Collections.emptyList(); } final StackFrameProxyImpl contextFrame = myDebuggerContext.getFrameProxy(); final EvaluationContextImpl evaluationContext = myDebuggerContext.createEvaluationContext(); final DebuggerManagerThreadImpl managerThread = myDebuggerContext.getDebugProcess().getManagerThread(); final MethodsTracker tracker = new MethodsTracker(); final int totalFramesCount = frames.size(); int index = 0; final long timestamp = System.nanoTime(); for (StackFrameProxyImpl stackFrameProxy : frames) { managerThread.schedule( new AppendFrameCommand( getSuspendContext(), stackFrameProxy, evaluationContext, tracker, index++, stackFrameProxy.equals(contextFrame), totalFramesCount, timestamp)); } }
public void reloadClasses(final Map<String, HotSwapFile> modifiedClasses) { DebuggerManagerThreadImpl.assertIsManagerThread(); if (modifiedClasses == null || modifiedClasses.size() == 0) { myProgress.addMessage( myDebuggerSession, MessageCategory.INFORMATION, DebuggerBundle.message("status.hotswap.loaded.classes.up.to.date")); return; } final DebugProcessImpl debugProcess = getDebugProcess(); final VirtualMachineProxyImpl virtualMachineProxy = debugProcess.getVirtualMachineProxy(); final Project project = debugProcess.getProject(); final BreakpointManager breakpointManager = (DebuggerManagerEx.getInstanceEx(project)).getBreakpointManager(); breakpointManager.disableBreakpoints(debugProcess); // virtualMachineProxy.suspend(); try { RedefineProcessor redefineProcessor = new RedefineProcessor(virtualMachineProxy); int processedEntriesCount = 0; for (final Map.Entry<String, HotSwapFile> entry : modifiedClasses.entrySet()) { // stop if process is finished already if (debugProcess.isDetached() || debugProcess.isDetaching()) { break; } if (redefineProcessor.getProcessedClassesCount() == 0 && myProgress.isCancelled()) { // once at least one class has been actually reloaded, do not interrupt the whole process break; } processedEntriesCount++; final String qualifiedName = entry.getKey(); if (qualifiedName != null) { myProgress.setText(qualifiedName); myProgress.setFraction(processedEntriesCount / (double) modifiedClasses.size()); } try { redefineProcessor.processClass(qualifiedName, entry.getValue().file); } catch (IOException e) { reportProblem(qualifiedName, e); } } if (redefineProcessor.getProcessedClassesCount() == 0 && myProgress.isCancelled()) { // once at least one class has been actually reloaded, do not interrupt the whole process return; } redefineProcessor.processPending(); myProgress.setFraction(1); final int partiallyRedefinedClassesCount = redefineProcessor.getPartiallyRedefinedClassesCount(); if (partiallyRedefinedClassesCount == 0) { myProgress.addMessage( myDebuggerSession, MessageCategory.INFORMATION, DebuggerBundle.message( "status.classes.reloaded", redefineProcessor.getProcessedClassesCount())); } else { final String message = DebuggerBundle.message( "status.classes.not.all.versions.reloaded", partiallyRedefinedClassesCount, redefineProcessor.getProcessedClassesCount()); myProgress.addMessage(myDebuggerSession, MessageCategory.WARNING, message); } LOG.debug("classes reloaded"); } catch (Throwable e) { processException(e); } debugProcess.getPositionManager().clearCache(); DebuggerContextImpl context = myDebuggerSession.getContextManager().getContext(); SuspendContextImpl suspendContext = context.getSuspendContext(); if (suspendContext != null) { XExecutionStack stack = suspendContext.getActiveExecutionStack(); if (stack != null) { ((JavaExecutionStack) stack).initTopFrame(); } } final Semaphore waitSemaphore = new Semaphore(); waitSemaphore.down(); //noinspection SSBasedInspection SwingUtilities.invokeLater( () -> { try { if (!project.isDisposed()) { breakpointManager.reloadBreakpoints(); debugProcess.getRequestsManager().clearWarnings(); if (LOG.isDebugEnabled()) { LOG.debug("requests updated"); LOG.debug("time stamp set"); } myDebuggerSession.refresh(false); XDebugSession session = myDebuggerSession.getXDebugSession(); if (session != null) { session.rebuildViews(); } } } catch (Throwable e) { LOG.error(e); } finally { waitSemaphore.up(); } }); waitSemaphore.waitFor(); if (!project.isDisposed()) { try { breakpointManager.enableBreakpoints(debugProcess); } catch (Exception e) { processException(e); } } }