public void actionPerformed(final AnActionEvent e) { DebuggerTreeNodeImpl[] selectedNode = getSelectedNodes(e.getDataContext()); final DebuggerContextImpl debuggerContext = getDebuggerContext(e.getDataContext()); final DebugProcessImpl debugProcess = debuggerContext.getDebugProcess(); if (debugProcess == null) return; //noinspection ConstantConditions for (final DebuggerTreeNodeImpl debuggerTreeNode : selectedNode) { final ThreadDescriptorImpl threadDescriptor = ((ThreadDescriptorImpl) debuggerTreeNode.getDescriptor()); if (threadDescriptor.isSuspended()) { final ThreadReferenceProxyImpl thread = threadDescriptor.getThreadReference(); debugProcess .getManagerThread() .schedule( new DebuggerCommandImpl() { @Override protected void action() throws Exception { Set<SuspendContextImpl> contexts = SuspendManagerUtil.getSuspendingContexts( debugProcess.getSuspendManager(), thread); if (!contexts.isEmpty()) { debugProcess .createResumeThreadCommand(contexts.iterator().next(), thread) .run(); } debuggerTreeNode.calcValue(); } }); } } }
private static Value convertToWrapper( EvaluationContextImpl context, PrimitiveValue value, String wrapperTypeName) throws EvaluateException { final DebugProcessImpl process = context.getDebugProcess(); final ClassType wrapperClass = (ClassType) process.findClass(context, wrapperTypeName, null); final String methodSignature = "(" + JVMNameUtil.getPrimitiveSignature(value.type().name()) + ")L" + wrapperTypeName.replace('.', '/') + ";"; List<Method> methods = wrapperClass.methodsByName("valueOf", methodSignature); if (methods.size() == 0) { // older JDK version methods = wrapperClass.methodsByName(JVMNameUtil.CONSTRUCTOR_NAME, methodSignature); } if (methods.size() == 0) { throw new EvaluateException( "Cannot construct wrapper object for value of type " + value.type() + ": Unable to find either valueOf() or constructor method"); } return process.invokeMethod( context, wrapperClass, methods.get(0), Collections.singletonList(value)); }
@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(); }
@Override public void update(final AnActionEvent e) { if (!isFirstStart(e)) { return; } final DebuggerContextImpl debuggerContext = getDebuggerContext(e.getDataContext()); final DebugProcessImpl debugProcess = debuggerContext.getDebugProcess(); if (debugProcess == null) { e.getPresentation().setVisible(false); return; } DebuggerTreeNodeImpl selectedNode = getSelectedNode(e.getDataContext()); if (selectedNode == null) { e.getPresentation().setVisible(false); return; } final NodeDescriptorImpl descriptor = selectedNode.getDescriptor(); if (descriptor instanceof ValueDescriptor) { debugProcess .getManagerThread() .schedule( new EnableCommand(debuggerContext, (ValueDescriptor) descriptor, debugProcess, e)); } else { e.getPresentation().setVisible(false); } }
@Nullable private static Value createScaledBitmap( @NotNull EvaluationContextImpl context, @NotNull ObjectReference bitmap, @NotNull Dimension currentDimensions) throws EvaluateException { DebugProcessImpl debugProcess = context.getDebugProcess(); Method createScaledBitmapMethod = DebuggerUtils.findMethod( bitmap.referenceType(), "createScaledBitmap", "(Landroid/graphics/Bitmap;IIZ)Landroid/graphics/Bitmap;"); if (createScaledBitmapMethod == null) { return null; } double s = Math.max(currentDimensions.getHeight(), currentDimensions.getWidth()) / MAX_DIMENSION; VirtualMachineProxyImpl vm = context.getDebugProcess().getVirtualMachineProxy(); Value dstWidth = DebuggerUtilsEx.createValue(vm, "int", (int) (currentDimensions.getWidth() / s)); Value dstHeight = DebuggerUtilsEx.createValue(vm, "int", (int) (currentDimensions.getHeight() / s)); Value filter = DebuggerUtilsEx.createValue(vm, "boolean", Boolean.FALSE); return debugProcess.invokeMethod( context, bitmap, createScaledBitmapMethod, Arrays.asList(bitmap, dstWidth, dstHeight, filter)); }
/** * Associates breakpoint with class. Create requests for loaded class and registers callback for * loading classes * * @param debugProcess the requesting process */ protected void createOrWaitPrepare(DebugProcessImpl debugProcess, String classToBeLoaded) { debugProcess.getRequestsManager().callbackOnPrepareClasses(this, classToBeLoaded); List list = debugProcess.getVirtualMachineProxy().classesByName(classToBeLoaded); for (final Object aList : list) { ReferenceType refType = (ReferenceType) aList; if (refType.isPrepared()) { processClassPrepare(debugProcess, refType); } } }
@Nullable private static Value getBitmapConfig(EvaluationContextImpl context, ObjectReference bitmap) throws EvaluateException { DebugProcessImpl debugProcess = context.getDebugProcess(); Method getConfig = DebuggerUtils.findMethod( bitmap.referenceType(), "getConfig", "()Landroid/graphics/Bitmap$Config;"); if (getConfig == null) { return null; } return debugProcess.invokeMethod(context, bitmap, getConfig, Collections.emptyList()); }
protected void createOrWaitPrepare( final DebugProcessImpl debugProcess, final SourcePosition classPosition) { debugProcess.getRequestsManager().callbackOnPrepareClasses(this, classPosition); List list = debugProcess.getPositionManager().getAllClasses(classPosition); for (final Object aList : list) { ReferenceType refType = (ReferenceType) aList; if (refType.isPrepared()) { processClassPrepare(debugProcess, refType); } } }
private void runAction(final EvaluationContextImpl context, LocatableEvent event) { if (LOG_ENABLED || LOG_EXPRESSION_ENABLED) { final StringBuilder buf = StringBuilderSpinAllocator.alloc(); try { if (LOG_ENABLED) { buf.append(getEventMessage(event)); buf.append("\n"); } final DebugProcessImpl debugProcess = context.getDebugProcess(); final TextWithImports expressionToEvaluate = getLogMessage(); if (LOG_EXPRESSION_ENABLED && expressionToEvaluate != null && !"".equals(expressionToEvaluate.getText())) { if (!debugProcess.isAttached()) { return; } try { ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction( getProject(), new EvaluatingComputable<ExpressionEvaluator>() { public ExpressionEvaluator compute() throws EvaluateException { return EvaluatorBuilderImpl.build( expressionToEvaluate, ContextUtil.getContextElement(context), ContextUtil.getSourcePosition(context)); } }); final Value eval = evaluator.evaluate(context); final String result = eval instanceof VoidValue ? "void" : DebuggerUtils.getValueAsString(context, eval); buf.append(result); } catch (EvaluateException e) { buf.append(DebuggerBundle.message("error.unable.to.evaluate.expression")); buf.append(" \""); buf.append(expressionToEvaluate); buf.append("\""); buf.append(" : "); buf.append(e.getMessage()); } buf.append("\n"); } if (buf.length() > 0) { debugProcess.printToConsole(buf.toString()); } } finally { StringBuilderSpinAllocator.dispose(buf); } } }
/*invoked in swing thread*/ protected void rebuild(final boolean updateOnly) { if (!updateOnly) { myThreadsCombo.removeAllItems(); synchronized (myFramesList) { myFramesList.clear(); } } final DebugProcessImpl process = getContext().getDebugProcess(); if (process != null) { process .getManagerThread() .schedule(new RefreshFramePanelCommand(updateOnly && myThreadsCombo.getItemCount() != 0)); } }
private Icon calcIcon(@Nullable DebugProcessImpl debugProcess) { final boolean muted = debugProcess != null && isMuted(debugProcess); if (!isEnabled()) { return getDisabledIcon(muted); } myInvalidMessage = ""; if (!isValid()) { return getInvalidIcon(muted); } if (debugProcess == null) { return getSetIcon(muted); } final RequestManagerImpl requestsManager = debugProcess.getRequestsManager(); final boolean isVerified = myCachedVerifiedState || requestsManager.isVerified(this); final String warning = requestsManager.getWarning(this); if (warning != null) { myInvalidMessage = warning; if (!isVerified) { return getInvalidIcon(muted); } return getVerifiedWarningsIcon(muted); } if (isVerified) { return getVerifiedIcon(muted); } return getSetIcon(muted); }
private ReferenceType loadClass(final String className) { final EvaluationContextImpl eContext = myDebuggerContext.createEvaluationContext(); try { return myDebugProcess.loadClass(eContext, className, eContext.getClassLoader()); } catch (Throwable ignored) { } return null; }
@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(); }
@Override public void removeDebugProcessListener( final ProcessHandler processHandler, final DebugProcessListener listener) { DebugProcessImpl debugProcess = getDebugProcess(processHandler); if (debugProcess != null) { debugProcess.removeDebugProcessListener(listener); } else { processHandler.addProcessListener( new ProcessAdapter() { @Override public void startNotified(ProcessEvent event) { DebugProcessImpl debugProcess = getDebugProcess(processHandler); if (debugProcess != null) { debugProcess.removeDebugProcessListener(listener); } processHandler.removeProcessListener(this); } }); } }
@Override public final void contextAction() throws Exception { try { doAction(calcPosition(myDescriptor, myDebugProcess)); } catch (ClassNotLoadedException ex) { final String className = ex.className(); if (loadClass(className) != null) { myDebugProcess.getManagerThread().schedule(createRetryCommand()); } } }
private EventRequest findRequest(DebugProcessImpl debugProcess, Class requestClass) { Set reqSet = debugProcess.getRequestsManager().findRequests(this); for (Iterator iterator = reqSet.iterator(); iterator.hasNext(); ) { EventRequest eventRequest = (EventRequest) iterator.next(); if (eventRequest.getClass().equals(requestClass)) { return eventRequest; } } return null; }
@Nullable private static List<Value> copyToBuffer( EvaluationContextImpl evaluationContext, ObjectReference bitmap, Dimension size) throws EvaluateException { DebugProcessImpl debugProcess = evaluationContext.getDebugProcess(); VirtualMachineProxyImpl virtualMachineProxy = debugProcess.getVirtualMachineProxy(); List<ReferenceType> classes = virtualMachineProxy.classesByName("byte[]"); if (classes.size() != 1 || !(classes.get(0) instanceof ArrayType)) { return null; } ArrayType byteArrayType = (ArrayType) classes.get(0); classes = virtualMachineProxy.classesByName("java.nio.ByteBuffer"); if (classes.size() != 1 || !(classes.get(0) instanceof ClassType)) { return null; } ClassType byteBufferType = (ClassType) classes.get(0); Method wrapMethod = DebuggerUtils.findMethod(byteBufferType, "wrap", "([B)Ljava/nio/ByteBuffer;"); if (wrapMethod == null) { return null; } ArrayReference byteArray = byteArrayType.newInstance(size.width * size.height * 4); Value byteBufferRef = debugProcess.invokeMethod( evaluationContext, byteBufferType, wrapMethod, ImmutableList.of(byteArray)); Method copyToBufferMethod = DebuggerUtils.findMethod( bitmap.referenceType(), "copyPixelsToBuffer", "(Ljava/nio/Buffer;)V"); if (copyToBufferMethod == null) { return null; } debugProcess.invokeMethod( evaluationContext, bitmap, copyToBufferMethod, ImmutableList.of(byteBufferRef)); return byteArray.getValues(); }
public void actionPerformed(AnActionEvent e) { final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); if (project == null) { return; } DebuggerContextImpl context = (DebuggerManagerEx.getInstanceEx(project)).getContext(); final DebuggerSession session = context.getDebuggerSession(); if (session != null && session.isAttached()) { final DebugProcessImpl process = context.getDebugProcess(); process .getManagerThread() .invoke( new DebuggerCommandImpl() { protected void action() throws Exception { final VirtualMachineProxyImpl vm = process.getVirtualMachineProxy(); vm.suspend(); try { final List<ThreadState> threads = buildThreadStates(vm); ApplicationManager.getApplication() .invokeLater( new Runnable() { public void run() { XDebugSession xSession = session.getProcess().getXDebugSession(); if (xSession != null) { DebuggerSessionTab.addThreadDump( project, threads, xSession.getUI(), session); } } }, ModalityState.NON_MODAL); } finally { vm.resume(); } } }); } }
@Override public void actionPerformed(AnActionEvent e) { DebuggerTreeNodeImpl selectedNode = getSelectedNode(e.getDataContext()); if (selectedNode == null) { return; } final NodeDescriptorImpl descriptor = selectedNode.getDescriptor(); if (!(descriptor instanceof ValueDescriptor)) { return; } DebuggerContextImpl debuggerContext = getDebuggerContext(e.getDataContext()); final DebugProcessImpl debugProcess = debuggerContext.getDebugProcess(); if (debugProcess == null) { return; } debugProcess .getManagerThread() .schedule( new NavigateCommand(debuggerContext, (ValueDescriptor) descriptor, debugProcess, e)); }
private static Value convertToPrimitive( EvaluationContextImpl context, ObjectReference value, final String conversionMethodName, String conversionMethodSignature) throws EvaluateException { final DebugProcessImpl process = context.getDebugProcess(); final ClassType wrapperClass = (ClassType) value.referenceType(); final List<Method> methods = wrapperClass.methodsByName(conversionMethodName, conversionMethodSignature); if (methods.size() == 0) { throw new EvaluateException( "Cannot convert to primitive value of type " + value.type() + ": Unable to find method " + conversionMethodName + conversionMethodSignature); } final Method method = methods.get(0); return process.invokeMethod(context, value, method, new ArrayList()); }
public void actionPerformed(AnActionEvent e) { final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); if (project == null) { return; } DebuggerContextImpl context = (DebuggerManagerEx.getInstanceEx(project)).getContext(); if (context.getDebuggerSession() != null) { final DebugProcessImpl process = context.getDebugProcess(); process .getManagerThread() .invoke( new DebuggerCommandImpl() { protected void action() throws Exception { final VirtualMachineProxyImpl vm = process.getVirtualMachineProxy(); vm.suspend(); try { final List<ThreadState> threads = buildThreadStates(vm); ApplicationManager.getApplication() .invokeLater( new Runnable() { public void run() { final DebuggerSessionTab sessionTab = DebuggerPanelsManager.getInstance(project).getSessionTab(); if (sessionTab != null) { sessionTab.addThreadDump(threads); } } }, ModalityState.NON_MODAL); } finally { vm.resume(); } } }); } }
// interaction with RequestManagerImpl public void disableBreakpoints(@NotNull final DebugProcessImpl debugProcess) { final List<Breakpoint> breakpoints = getBreakpoints(); if (!breakpoints.isEmpty()) { final RequestManagerImpl requestManager = debugProcess.getRequestsManager(); for (Breakpoint breakpoint : breakpoints) { breakpoint.markVerified(requestManager.isVerified(breakpoint)); requestManager.deleteRequest(breakpoint); } SwingUtilities.invokeLater( new Runnable() { @Override public void run() { updateBreakpointsUI(); } }); } }
@Nullable private static Integer getImageDimension( EvaluationContextImpl context, ObjectReference bitmap, DebugProcessImpl debugProcess, String methodName) throws EvaluateException { Method method = DebuggerUtils.findMethod((bitmap).referenceType(), methodName, "()I"); if (method != null) { Value widthValue = debugProcess.invokeMethod(context, bitmap, method, Collections.emptyList()); if (widthValue instanceof IntegerValue) { return ((IntegerValue) widthValue).value(); } } return null; }
private boolean isInScopeOf(DebugProcessImpl debugProcess, String className) { final SourcePosition position = getSourcePosition(); if (position != null) { final VirtualFile breakpointFile = position.getFile().getVirtualFile(); final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); if (breakpointFile != null && fileIndex.isInSourceContent(breakpointFile)) { // apply filtering to breakpoints from content sources only, not for sources attached to // libraries final Collection<VirtualFile> candidates = findClassCandidatesInSourceContent(className, debugProcess.getSearchScope(), fileIndex); if (candidates == null) { return true; } for (VirtualFile classFile : candidates) { if (breakpointFile.equals(classFile)) { return true; } } return false; } } return 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 applyThreadFilter( @NotNull final DebugProcessImpl debugProcess, @Nullable ThreadReference newFilterThread) { final RequestManagerImpl requestManager = debugProcess.getRequestsManager(); final ThreadReference oldFilterThread = requestManager.getFilterThread(); if (Comparing.equal(newFilterThread, oldFilterThread)) { // the filter already added return; } requestManager.setFilterThread(newFilterThread); if (newFilterThread == null || oldFilterThread != null) { final List<Breakpoint> breakpoints = getBreakpoints(); for (Breakpoint breakpoint : breakpoints) { if (LineBreakpoint.CATEGORY.equals(breakpoint.getCategory()) || MethodBreakpoint.CATEGORY.equals(breakpoint.getCategory())) { requestManager.deleteRequest(breakpoint); breakpoint.createRequest(debugProcess); } } } else { // important! need to add filter to _existing_ requests, otherwise Requestor->Request mapping // will be lost // and debugger trees will not be restored to original state abstract class FilterSetter<T extends EventRequest> { void applyFilter(@NotNull final List<T> requests, final ThreadReference thread) { for (T request : requests) { try { final boolean wasEnabled = request.isEnabled(); if (wasEnabled) { request.disable(); } addFilter(request, thread); if (wasEnabled) { request.enable(); } } catch (InternalException e) { LOG.info(e); } } } protected abstract void addFilter(final T request, final ThreadReference thread); } final EventRequestManager eventRequestManager = requestManager.getVMRequestManager(); new FilterSetter<BreakpointRequest>() { @Override protected void addFilter( @NotNull final BreakpointRequest request, final ThreadReference thread) { request.addThreadFilter(thread); } }.applyFilter(eventRequestManager.breakpointRequests(), newFilterThread); new FilterSetter<MethodEntryRequest>() { @Override protected void addFilter( @NotNull final MethodEntryRequest request, final ThreadReference thread) { request.addThreadFilter(thread); } }.applyFilter(eventRequestManager.methodEntryRequests(), newFilterThread); new FilterSetter<MethodExitRequest>() { @Override protected void addFilter( @NotNull final MethodExitRequest request, final ThreadReference thread) { request.addThreadFilter(thread); } }.applyFilter(eventRequestManager.methodExitRequests(), newFilterThread); } }
protected boolean isMuted(@NotNull final DebugProcessImpl debugProcess) { return debugProcess.areBreakpointsMuted(); }
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); } } }
@Override protected void createRequestForPreparedClass( final DebugProcessImpl debugProcess, final ReferenceType classType) { if (!isInScopeOf(debugProcess, classType.name())) { if (LOG.isDebugEnabled()) { LOG.debug( classType.name() + " is out of debug-process scope, breakpoint request won't be created for line " + getLineIndex()); } return; } try { List<Location> locations = debugProcess.getPositionManager().locationsOfLine(classType, getSourcePosition()); if (!locations.isEmpty()) { for (Location loc : locations) { if (LOG.isDebugEnabled()) { LOG.debug( "Found location [codeIndex=" + loc.codeIndex() + "] for reference type " + classType.name() + " at line " + getLineIndex() + "; isObsolete: " + (debugProcess.getVirtualMachineProxy().versionHigher("1.4") && loc.method().isObsolete())); } if (!acceptLocation(debugProcess, classType, loc)) { continue; } final BreakpointRequest request = debugProcess.getRequestsManager().createBreakpointRequest(this, loc); debugProcess.getRequestsManager().enableRequest(request); if (LOG.isDebugEnabled()) { LOG.debug( "Created breakpoint request for reference type " + classType.name() + " at line " + getLineIndex() + "; codeIndex=" + loc.codeIndex()); } } } else { // there's no executable code in this class debugProcess .getRequestsManager() .setInvalid( this, DebuggerBundle.message( "error.invalid.breakpoint.no.executable.code", (getLineIndex() + 1), classType.name())); if (LOG.isDebugEnabled()) { LOG.debug( "No locations of type " + classType.name() + " found at line " + getLineIndex()); } } } catch (ClassNotPreparedException ex) { if (LOG.isDebugEnabled()) { LOG.debug("ClassNotPreparedException: " + ex.getMessage()); } // there's a chance to add a breakpoint when the class is prepared } catch (ObjectCollectedException ex) { if (LOG.isDebugEnabled()) { LOG.debug("ObjectCollectedException: " + ex.getMessage()); } // there's a chance to add a breakpoint when the class is prepared } catch (InvalidLineNumberException ex) { if (LOG.isDebugEnabled()) { LOG.debug("InvalidLineNumberException: " + ex.getMessage()); } debugProcess .getRequestsManager() .setInvalid(this, DebuggerBundle.message("error.invalid.breakpoint.bad.line.number")); } catch (InternalException ex) { LOG.info(ex); } catch (Exception ex) { LOG.info(ex); } updateUI(); }
private boolean isInScopeOf(DebugProcessImpl debugProcess, String className) { final SourcePosition position = getSourcePosition(); if (position != null) { final VirtualFile breakpointFile = position.getFile().getVirtualFile(); final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); if (breakpointFile != null && fileIndex.isUnderSourceRootOfType(breakpointFile, JavaModuleSourceRootTypes.SOURCES)) { if (debugProcess.getSearchScope().contains(breakpointFile)) { return true; } // apply filtering to breakpoints from content sources only, not for sources attached to // libraries final Collection<VirtualFile> candidates = findClassCandidatesInSourceContent(className, debugProcess.getSearchScope(), fileIndex); if (LOG.isDebugEnabled()) { LOG.debug( "Found " + (candidates == null ? "null" : candidates.size()) + " candidate containing files for class " + className); } if (candidates == null) { // If no candidates are found in scope then assume that class is loaded dynamically and // allow breakpoint return true; } // breakpointFile is not in scope here and there are some candidates in scope // for (VirtualFile classFile : candidates) { // if (LOG.isDebugEnabled()) { // LOG.debug("Breakpoint file: " + breakpointFile.getPath()+ "; candidate file: " + // classFile.getPath()); // } // if (breakpointFile.equals(classFile)) { // return true; // } // } if (LOG.isDebugEnabled()) { final GlobalSearchScope scope = debugProcess.getSearchScope(); final boolean contains = scope.contains(breakpointFile); final Project project = getProject(); final List<VirtualFile> files = ContainerUtil.map( JavaFullClassNameIndex.getInstance().get(className.hashCode(), project, scope), new Function<PsiClass, VirtualFile>() { @Override public VirtualFile fun(PsiClass aClass) { return aClass.getContainingFile().getVirtualFile(); } }); final List<VirtualFile> allFiles = ContainerUtil.map( JavaFullClassNameIndex.getInstance() .get(className.hashCode(), project, new EverythingGlobalScope(project)), new Function<PsiClass, VirtualFile>() { @Override public VirtualFile fun(PsiClass aClass) { return aClass.getContainingFile().getVirtualFile(); } }); final VirtualFile contentRoot = fileIndex.getContentRootForFile(breakpointFile); final Module module = fileIndex.getModuleForFile(breakpointFile); LOG.debug( "Did not find '" + className + "' in " + scope + "; contains=" + contains + "; contentRoot=" + contentRoot + "; module = " + module + "; all files in index are: " + files + "; all possible files are: " + allFiles); } return false; } } return true; }