/** * 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(); }
/** * Starts the debugger. The method stops the current debugging (if any) and takes information from * the provided info (containing the class to start and arguments to pass it and name of class to * stop debugging in) and starts new debugging session. * * @param info debugger info about class to start * @exception DebuggerException if an error occures during the start of the debugger */ public void startDebugger(DebuggerInfo info) throws DebuggerException { debuggerInfo = info; if (virtualMachine != null) finishDebugger(); stopOnMain = info.getStopClassName() != null; mainClassName = info .getClassName(); // S ystem.out.println ("JPDADebugger stop on " + info.getStopClassName // ()); // NOI18N // open output window ... super.startDebugger(info); // stop on main if (stopOnMain) { try { String stopClassName = debuggerInfo.getStopClassName(); AbstractDebugger d = (AbstractDebugger) TopManager.getDefault().getDebugger(); breakpointMain = new CoreBreakpoint[stopMethodNames.length]; for (int x = 0; x < breakpointMain.length; x++) { breakpointMain[x] = (CoreBreakpoint) d.createBreakpoint(true); breakpointMain[x].setClassName(""); // NOI18N breakpointMain[x].setMethodName(stopMethodNames[x]); // NOI18N CoreBreakpoint.Action[] a = breakpointMain[x].getActions(); int i, ii = a.length; for (i = 0; i < ii; i++) if (a[i] instanceof PrintAction) { ((PrintAction) a[i]).setPrintText(bundle.getString("CTL_Stop_On_Main_print_text")); } breakpointMain[x].setClassName(stopClassName); } addPropertyChangeListener( new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent ev) { if (ev.getPropertyName().equals(PROP_STATE)) { if ((((Integer) ev.getNewValue()).intValue() == DEBUGGER_STOPPED) || (((Integer) ev.getNewValue()).intValue() == DEBUGGER_NOT_RUNNING)) { if (breakpointMain != null) { for (int x = 0; x < breakpointMain.length; x++) breakpointMain[x].remove(); breakpointMain = null; } removePropertyChangeListener(this); } } } }); } catch (DebuggerException e) { e.printStackTrace(); } } // start & init remote debugger ............................................ boolean launch = false; if (info instanceof ReconnectDebuggerInfo) { virtualMachine = reconnect((ReconnectDebuggerInfo) info); } else if (info instanceof RemoteDebuggerInfo) { virtualMachine = connect((RemoteDebuggerInfo) info); } else { virtualMachine = launch(info); process = virtualMachine.process(); showOutput(process, STD_OUT, STD_OUT); connectInput(process); launch = true; } requestManager = virtualMachine.eventRequestManager(); operator = new Operator( virtualMachine, launch ? new Runnable() { public void run() { startDebugger(); } } : null, new Runnable() { public void run() { try { finishDebugger(); } catch (DebuggerException e) { } } }); operator.start(); if (!launch) startDebugger(); }