@Override public void addBreakpoint(Breakpoint breakpoint) throws DebuggerException { final String className = breakpoint.getLocation().getTarget(); final int lineNumber = breakpoint.getLocation().getLineNumber(); List<ReferenceType> classes = vm.classesByName(className); // it may mean that class doesn't loaded by a target JVM yet if (classes.isEmpty()) { deferBreakpoint(breakpoint); throw new DebuggerException("Class not loaded"); } ReferenceType clazz = classes.get(0); List<com.sun.jdi.Location> locations; try { locations = clazz.locationsOfLine(lineNumber); } catch (AbsentInformationException | ClassNotPreparedException e) { throw new DebuggerException(e.getMessage(), e); } if (locations.isEmpty()) { throw new DebuggerException("Line " + lineNumber + " not found in class " + className); } com.sun.jdi.Location location = locations.get(0); if (location.method() == null) { // Line is out of method. throw new DebuggerException("Invalid line " + lineNumber + " in class " + className); } // Ignore new breakpoint if already have breakpoint at the same location. EventRequestManager requestManager = getEventManager(); for (BreakpointRequest breakpointRequest : requestManager.breakpointRequests()) { if (location.equals(breakpointRequest.location())) { LOG.debug("Breakpoint at {} already set", location); return; } } try { EventRequest breakPointRequest = requestManager.createBreakpointRequest(location); breakPointRequest.setSuspendPolicy(EventRequest.SUSPEND_ALL); String expression = breakpoint.getCondition(); if (!(expression == null || expression.isEmpty())) { ExpressionParser parser = ExpressionParser.newInstance(expression); breakPointRequest.putProperty( "org.eclipse.che.ide.java.debug.condition.expression.parser", parser); } breakPointRequest.setEnabled(true); } catch (NativeMethodException | IllegalThreadStateException | InvalidRequestStateException e) { throw new DebuggerException(e.getMessage(), e); } debuggerCallback.onEvent(new BreakpointActivatedEventImpl(breakpoint)); LOG.debug("Add breakpoint: {}", location); }
@Override public void deleteBreakpoint(Location location) throws DebuggerException { final String className = location.getTarget(); final int lineNumber = location.getLineNumber(); EventRequestManager requestManager = getEventManager(); List<BreakpointRequest> snapshot = new ArrayList<>(requestManager.breakpointRequests()); for (BreakpointRequest breakpointRequest : snapshot) { com.sun.jdi.Location jdiLocation = breakpointRequest.location(); if (jdiLocation.declaringType().name().equals(className) && jdiLocation.lineNumber() == lineNumber) { requestManager.deleteEventRequest(breakpointRequest); LOG.debug("Delete breakpoint: {}", location); } } }
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); } }