void destroy(VirtualMachine vm) throws Exception { EventRequestManager requestManager = vm.eventRequestManager(); for (EventRequest request : handlers.keySet()) { requestManager.deleteEventRequest(request); } debugger.destroyHandler(); }
/** The 'refType' is known to match, return the EventRequest. */ EventRequest resolveEventRequest(ReferenceType refType) throws NoSuchFieldException { Field field = refType.fieldByName(fieldId); EventRequestManager em = refType.virtualMachine().eventRequestManager(); EventRequest wp = em.createAccessWatchpointRequest(field); wp.setSuspendPolicy(suspendPolicy); wp.enable(); return wp; }
@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); }
private EventRequest createMethodRequest(JDXDebugTarget target, Object classFilter, boolean entry) throws CoreException { EventRequest request = null; EventRequestManager manager = target.getEventRequestManager(); if (manager == null) { target.requestFailed( JDXMessages.JDXMethodBreakpoint_Unable_to_create_breakpoint_request___VM_disconnected__1, null); //$NON-NLS-1$ } try { if (entry) { if (classFilter instanceof ClassType && getMethodName() != null && getMethodSignature() != null) { ClassType clazz = (ClassType) classFilter; if (clazz.name().equals(getTypeName())) { Method method = clazz.concreteMethodByName(getMethodName(), getMethodSignature()); if (method != null && !method.isNative()) { Location location = method.location(); if (location != null && location.codeIndex() != -1) { request = manager.createBreakpointRequest(location); } } } } if (request == null) { request = manager.createMethodEntryRequest(); if (classFilter instanceof String) { ((MethodEntryRequest) request).addClassFilter((String) classFilter); } else if (classFilter instanceof ReferenceType) { ((MethodEntryRequest) request).addClassFilter((ReferenceType) classFilter); } } } else { request = manager.createMethodExitRequest(); if (classFilter instanceof String) { ((MethodExitRequest) request).addClassFilter((String) classFilter); } else if (classFilter instanceof ReferenceType) { ((MethodExitRequest) request).addClassFilter((ReferenceType) classFilter); } } configureRequest(request, target); } catch (VMDisconnectedException e) { if (!target.isAvailable()) { return null; } Plugin.log(e); } catch (RuntimeException e) { target.internalError(e); } return request; }
/** Removes last step request. */ void removeStepRequest() { if (stepRequest != null) { requestManager.deleteEventRequest(stepRequest); stepRequest = null; } if (findSourceMER != null) { requestManager.deleteEventRequest(findSourceMER); findSourceMER = null; } if (findSourceSR != null) { requestManager.deleteEventRequest(findSourceSR); findSourceSR = null; } }
@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); } } }
private void setEventRequests(VirtualMachine vm) { EventRequestManager erm = vm.eventRequestManager(); // Normally, we want all uncaught exceptions. We request them // via the same mechanism as Commands.commandCatchException() // so the user can ignore them later if they are not // interested. // FIXME: this works but generates spurious messages on stdout // during startup: // Set uncaught java.lang.Throwable // Set deferred uncaught java.lang.Throwable Commands evaluator = new Commands(); evaluator.commandCatchException(new StringTokenizer("uncaught java.lang.Throwable")); ThreadStartRequest tsr = erm.createThreadStartRequest(); tsr.enable(); ThreadDeathRequest tdr = erm.createThreadDeathRequest(); tdr.enable(); }
@Override protected void deleteRequests() { // Delete the old requests, if any. try { if (startRequest != null) { VirtualMachine vm = startRequest.virtualMachine(); EventRequestManager erm = vm.eventRequestManager(); erm.deleteEventRequest(startRequest); } if (deathRequest != null) { VirtualMachine vm = deathRequest.virtualMachine(); EventRequestManager erm = vm.eventRequestManager(); erm.deleteEventRequest(deathRequest); } } catch (VMDisconnectedException vmde) { // This happens all the time. } finally { startRequest = null; deathRequest = null; } }
/** Create the method entry and exit event requests. */ protected void createRequests() { BreakpointGroup group = getBreakpointGroup(); if (group == null) { // Nothing we can do right now. return; } Session session = BreakpointProvider.getSession(group); if (session == null || !session.isConnected()) { // Nothing we can do right now. return; } EventRequestManager erm = session.getConnection().getVM().eventRequestManager(); // Create the new requests. if (onStart) { startRequest = erm.createThreadStartRequest(); register(startRequest); } if (onDeath) { deathRequest = erm.createThreadDeathRequest(); register(deathRequest); } }
/** * If this line can not be current => stepOver & return true. {support for non java languages} * * <p>return false on the other hand. */ boolean resolveCanBeCurrent(ThreadReference tr, Line l) { if ((l != null) && (!canBeCurrent(l, false))) { try { removeStepRequest(); findSourceSR = requestManager.createStepRequest(tr, StepRequest.STEP_LINE, StepRequest.STEP_OVER); findSourceSR.addCountFilter(1); findSourceSR.setSuspendPolicy(EventRequest.SUSPEND_ALL); operator.register(findSourceSR, this); findSourceSR.enable(); operator.resume(); } catch (DuplicateRequestException e) { e.printStackTrace(); } return true; } return false; }
/** Step out. */ public synchronized void stepOut() throws DebuggerException { if (virtualMachine == null) return; removeStepRequest(); try { setLastAction(ACTION_STEP_OUT); stepRequest = requestManager.createStepRequest( currentThread.getThreadReference(), StepRequest.STEP_LINE, StepRequest.STEP_OUT); stepRequest.addCountFilter(1); stepRequest.setSuspendPolicy(EventRequest.SUSPEND_ALL); operator.register(stepRequest, this); stepRequest.enable(); virtualMachine.resume(); super.stepOut(); } catch (DuplicateRequestException e) { e.printStackTrace(); } }
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); } }
/** * Generate the trace. Enable events, start thread to display events, start threads to forward * remote error and output streams, resume the remote VM, wait for the final event, and shutdown. */ protected void generateTrace() { // vm.setDebugTraceMode(debugTraceMode); // vm.setDebugTraceMode(VirtualMachine.TRACE_ALL); // vm.setDebugTraceMode(VirtualMachine.TRACE_NONE); // formerly, seems to have no effect // For internal debugging PrintWriter writer = null; // Calling this seems to set something internally to make the // Eclipse JDI wake up. Without it, an ObjectCollectedException // is thrown on excReq.enable(). No idea why this works, // but at least exception handling has returned. (Suspect that it may // block until all or at least some threads are available, meaning // that the app has launched and we have legit objects to talk to). vm.allThreads(); // The bug may not have been noticed because the test suite waits for // a thread to be available, and queries it by calling allThreads(). // See org.eclipse.debug.jdi.tests.AbstractJDITest for the example. EventRequestManager mgr = vm.eventRequestManager(); // get only the uncaught exceptions ExceptionRequest excReq = mgr.createExceptionRequest(null, false, true); // System.out.println(excReq); // this version reports all exceptions, caught or uncaught // ExceptionRequest excReq = mgr.createExceptionRequest(null, true, true); // suspend so we can step excReq.setSuspendPolicy(EventRequest.SUSPEND_ALL); // excReq.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD); // excReq.setSuspendPolicy(EventRequest.SUSPEND_NONE); // another option? excReq.enable(); Thread eventThread = new Thread() { public void run() { try { boolean connected = true; while (connected) { EventQueue eventQueue = vm.eventQueue(); // remove() blocks until event(s) available EventSet eventSet = eventQueue.remove(); // listener.vmEvent(eventSet); for (Event event : eventSet) { // System.out.println("EventThread.handleEvent -> " + event); if (event instanceof VMStartEvent) { vm.resume(); } else if (event instanceof ExceptionEvent) { // for (ThreadReference thread : vm.allThreads()) { // System.out.println("thread : " + thread); //// thread.suspend(); // } exceptionEvent((ExceptionEvent) event); } else if (event instanceof VMDisconnectEvent) { connected = false; } } } // } catch (VMDisconnectedException e) { // Logger.getLogger(VMEventReader.class.getName()).log(Level.INFO, // "VMEventReader quit on VM disconnect"); } catch (Exception e) { System.err.println("crashed in event thread due to " + e.getMessage()); // Logger.getLogger(VMEventReader.class.getName()).log(Level.SEVERE, // "VMEventReader quit", e); e.printStackTrace(); } } }; eventThread.start(); errThread = new MessageSiphon(process.getErrorStream(), this).getThread(); outThread = new StreamRedirectThread("JVM stdout Reader", process.getInputStream(), System.out); errThread.start(); outThread.start(); // Shutdown begins when event thread terminates try { if (eventThread != null) eventThread.join(); // is this the problem? // System.out.println("in here"); // Bug #852 tracked to this next line in the code. // http://dev.processing.org/bugs/show_bug.cgi?id=852 errThread.join(); // Make sure output is forwarded // System.out.println("and then"); outThread.join(); // before we exit // System.out.println("finished join for errThread and outThread"); // At this point, disable the run button. // This happens when the sketch is exited by hitting ESC, // or the user manually closes the sketch window. // TODO this should be handled better, should it not? if (editor != null) { editor.deactivateRun(); } } catch (InterruptedException exc) { // we don't interrupt } // System.out.println("and leaving"); if (writer != null) writer.close(); }
/** Finds the first executed line with source code. */ public void traceToSourceCode(ThreadReference thread) { // S ystem.out.println ("Start finding!!! "); // NOI18N // create Step Request for searching a source code try { findSourceSR = requestManager.createStepRequest(thread, StepRequest.STEP_LINE, StepRequest.STEP_OUT); findSourceSR.addCountFilter(1); findSourceSR.setSuspendPolicy(EventRequest.SUSPEND_ALL); operator.register(findSourceSR, this); findSourceSR.enable(); } catch (DuplicateRequestException e) { e.printStackTrace(); } // create Method Entry Request for searching a source code findSourceMER = requestManager.createMethodEntryRequest(); findSourceMER.setSuspendPolicy(EventRequest.SUSPEND_ALL); findSourceMER.addThreadFilter(thread); findSourceCounter = 0; operator.register( findSourceMER, new Executor() { public void exec(com.sun.jdi.event.Event event) { if (findSourceCounter == 500) { // finding source takes a long time operator.resume(); if (findSourceMER != null) { requestManager.deleteEventRequest(findSourceMER); findSourceMER = null; } return; } findSourceCounter++; Location loc = ((MethodEntryEvent) event).location(); if (loc == null) { // no line => continue finding operator.resume(); return; } String className = loc.declaringType().name(); int ln = loc.lineNumber(); // S ystem.out.println ("FIND " + className + " : " + ln); // NOI18N try { Line l = null; if ((l = Utils.getLineForSource(className, loc.sourceName(), ln)) == null) { // no line => continue finding operator.resume(); return; } // WOW I have a nice line! ThreadReference tr = ((MethodEntryEvent) event).thread(); if (resolveCanBeCurrent(tr, l)) // if can not be current => steps to some line return; // line can be current! String threadName = tr.name(); String methodName = loc.method() != null ? loc.method().name() : ""; // NOI18N String lineNumber = ln == -1 ? "?" : "" + ln; // NOI18N makeCurrent(threadName, className, methodName, lineNumber, true, tr); operator.stopRequest(); } catch (AbsentInformationException e) { } } }); findSourceMER.enable(); operator.resume(); return; }