/** 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; } }
/** * 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(); } }
/** * 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; }