private void collectAndRegisterOtherDebuggersThreads(List<PyThreadInfo> threads) { for (RemoteDebugger d : getOtherDebuggers()) { threads.addAll(d.getThreads()); for (PyThreadInfo t : d.getThreads()) { myThreadRegistry.register(t.getId(), d); } } }
private List<PyThreadInfo> collectAllThreads() { List<PyThreadInfo> result = Lists.newArrayList(); result.addAll(myMainDebugger.getThreads()); // collect threads and add them to registry to faster access // we don't register mainDebugger as it is default if there is no mapping for (RemoteDebugger d : myOtherDebuggers) { result.addAll(d.getThreads()); for (PyThreadInfo t : d.getThreads()) { myThreadRegistry.register(t.getId(), d); } } return result; }
@Override public void waitForConnect() throws Exception { try { //noinspection SocketOpenedButNotSafelyClosed final Socket socket = myServerSocket.accept(); ApplicationManager.getApplication() .executeOnPooledThread( new Runnable() { @Override public void run() { try { // do we need any synchronization here with myMainDebugger.waitForConnect() ??? // TODO sendDebuggerPort(socket, myDebugServerSocket, myDebugProcess); } catch (Exception e) { throw new RuntimeException(e); } } }); myMainDebugger.waitForConnect(); disposeAcceptor(); myDebugProcessAcceptor = new DebuggerProcessAcceptor(this, myServerSocket); ApplicationManager.getApplication().executeOnPooledThread(myDebugProcessAcceptor); } finally { } }
/** @return newly constructed string containing classpath obtained from filesystems */ public String getClasspath() { if (remoteDebugger != null) { try { return remoteDebugger.getSourcePath(); } catch (Exception e) { } } return ""; // getDefaultClasspath (); // NOI18N }
private void removeDisconnected(ArrayList<RemoteDebugger> debuggers) { boolean allConnected = true; for (RemoteDebugger d : debuggers) { if (!d.isConnected()) { allConnected = false; } } if (!allConnected) { List<RemoteDebugger> newList = Lists.newArrayList(); for (RemoteDebugger d : debuggers) { if (d.isConnected()) { newList.add(d); } } synchronized (myOtherDebuggers) { myOtherDebuggers.clear(); myOtherDebuggers.addAll(newList); } } }
@Override public void run() { while (myShouldAccept) { try { final ServerSocket serverSocketCopy = myServerSocket; if (serverSocketCopy == null) { break; } Socket socket = serverSocketCopy.accept(); try { final ServerSocket serverSocket = createServerSocket(); final RemoteDebugger debugger = new RemoteDebugger( myMultiProcessDebugger.myDebugProcess, serverSocket, myMultiProcessDebugger.myTimeoutInMillis); addCloseListener(debugger); sendDebuggerPort(socket, serverSocket, myMultiProcessDebugger.myDebugProcess); socket.close(); debugger.waitForConnect(); debugger.handshake(); myMultiProcessDebugger.addDebugger(debugger); myMultiProcessDebugger.myDebugProcess.init(); debugger.run(); } catch (Exception e) { LOG.warn(e); } finally { if (!socket.isClosed()) { socket.close(); } } } catch (Exception ignore) { if (myServerSocket == null) { myShouldAccept = false; } } } }
/** Disconnects from running debugged process. */ public void disconnect() throws DebuggerException { threadGroup.setRemoteThreadGroup(null); if (remoteDebugger != null) { remoteDebugger.close(); remoteDebugger = null; } if (debuggerThread != null) { debuggerThread.interrupt(); debuggerThread.stop(); } super.finishDebugger(); synchronizer = null; }
@Override public Collection<PyThreadInfo> getThreads() { List<PyThreadInfo> threads = Lists.newArrayList(myMainDebugger.getThreads()); List<PyThreadInfo> result = Lists.newArrayList(); cleanOtherDebuggers(); collectAndRegisterOtherDebuggersThreads( threads); // we don't register mainDebugger as it is default if there is no mapping if (myOtherDebuggers.size() > 0) { // here we add process id to thread name in case there are more then one process threads = addProcessIdToThreadName(threads, result); } return Collections.unmodifiableCollection(threads); }
private void addCloseListener(@NotNull final RemoteDebugger debugger) { debugger.addCloseListener( new RemoteDebuggerCloseListener() { @Override public void closed() { notifyThreadsClosed(debugger); } @Override public void communicationError() { notifyThreadsClosed(debugger); } @Override public void detached() { notifyThreadsClosed(debugger); } }); }
/** * 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 (remoteDebugger != null) finishDebugger(); // S ystem.out.println("startDebugger " + info); // NOI18N // RemoteDebugging support hostName = null; password = null; boolean local = true; if (info instanceof ReconnectDebuggerInfo) { ReconnectDebuggerInfo rdi = (ReconnectDebuggerInfo) info; hostName = rdi.getHostName(); password = rdi.getPassword(); local = false; } else if (info instanceof RemoteDebuggerInfo) { hostName = ((RemoteDebuggerInfo) info).getHostName(); password = ((RemoteDebuggerInfo) info).getPassword(); local = false; } boolean stopOnMain = info.getStopClassName() != null; stopOnMainFlag = stopOnMain; // S ystem.out.println ("ToolsDebugger.startDebugger " + info.getStopClassName ()); // NOI18N // T hread.dumpStack (); synchronizer = new RequestSynchronizer(); // open output window ... super.startDebugger(info); // start & init remote debugger ................................................ // process = null; if (local) { // create process & read password for local debugging // create starting string & NbProcessDescriptor NbProcessDescriptor debugerProcess; if (info instanceof ProcessDebuggerInfo) debugerProcess = ((ProcessDebuggerInfo) info).getDebuggerProcess(); else debugerProcess = ProcessDebuggerType.DEFAULT_DEBUGGER_PROCESS; HashMap map; if (info instanceof ToolsDebugger10Info) { map = Utils.processDebuggerInfo( info, "-debug", // NOI18N "sun.tools.debug.EmptyApp" // NOI18N ); map.put(ToolsDebugger10Type.JAVA_HOME_SWITCH, ((ToolsDebugger10Info) info).getJavaHome()); } else { if (info instanceof ToolsDebugger11Info) { String javaHome11 = ((ToolsDebugger11Info) info).getJavaHome(); if ((javaHome11 == null) || (javaHome11.trim().length() == 0)) { finishDebugger(); throw new DebuggerException(bundle.getString("EXC_JDK11_home_is_not_set")); } map = Utils.processDebuggerInfo( info, "-debug -nojit", // NOI18N "sun.tools.debug.EmptyApp" // NOI18N ); map.put(ToolsDebugger11Type.JAVA_HOME_SWITCH, javaHome11); } else { map = Utils.processDebuggerInfo( info, "-Xdebug", // NOI18N "sun.tools.agent.EmptyApp" // NOI18N ); } } MapFormat format = new MapFormat(map); String s = format.format( debugerProcess.getProcessName() + " " + debugerProcess.getArguments() // NOI18N ); println(s, ERR_OUT); // start process & read password ...................................... try { process = debugerProcess.exec(format); BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(process.getInputStream())); password = bufferedreader.readLine(); showOutput(process, ERR_OUT, ERR_OUT); connectInput(process); } catch (java.lang.Exception e) { finishDebugger(); throw new DebuggerException( new MessageFormat(bundle.getString("EXC_While_create_debuggee")) .format( new Object[] {format.format(debugerProcess.getProcessName()), e.toString()}), e); } if (password == null) { // no reply finishDebugger(); throw new DebuggerException( new MessageFormat(bundle.getString("EXC_While_connect_to_debuggee")) .format(new Object[] {format.format(debugerProcess.getProcessName())})); } if (password.indexOf("=") < 0) { // NOI18N // unexpected reply println(bundle.getString("CTL_Unexpected_reply") + ": " + password, ERR_OUT); showOutput(process, ERR_OUT + STD_OUT, ERR_OUT); finishDebugger(); throw new DebuggerException( new MessageFormat(bundle.getString("EXC_Unecpected_debugger_reply")) .format(new Object[] {password})); } password = password.substring(password.indexOf("=") + 1); // NOI18N println(bundle.getString("CTL_Password") + ": " + password, ERR_OUT); hostName = "127.0.0.1"; // NOI18N } // end of local debugging specific else if (info instanceof ReconnectDebuggerInfo) { println(bundle.getString("CTL_Reconnecting"), ERR_OUT | STD_OUT); } else println(bundle.getString("CTL_Connecting_to") + ": " + hostName + ":" + password, ERR_OUT); // start RemoteDebugger ................................................... try { remoteDebugger = new RemoteDebugger( hostName, password.length() < 1 ? null : password, new ToolsCallback(this), isShowMessages()); } catch (java.net.ConnectException e) { finishDebugger(); throw new DebuggerException( new MessageFormat(bundle.getString("EXC_Cannot_connect_to_debuggee")) .format(new Object[] {e.toString()}), e); } catch (Throwable e) { if (e instanceof ThreadDeath) throw (ThreadDeath) e; // e.printStackTrace (); finishDebugger(); throw new DebuggerException( new MessageFormat(bundle.getString("EXC_Cannot_connect_to_debuggee")) .format(new Object[] {e.toString()}), e); } // create arguments for main class ............................................... mainClassName = info.getClassName(); RemoteClass cls; String[] args = null; if ((mainClassName != null) && (mainClassName.length() > 0)) { String[] infoArgs = info.getArguments(); args = new String[infoArgs.length + 1]; args[0] = mainClassName; System.arraycopy(infoArgs, 0, args, 1, infoArgs.length); // args[0] = name of class // args[...] = parameters // find main class ......................................................... try { cls = remoteDebugger.findClass(mainClassName); } catch (Throwable e) { if (e instanceof ThreadDeath) throw (ThreadDeath) e; finishDebugger(); throw new DebuggerException( new MessageFormat(bundle.getString("EXC_Cannot_find_class")) .format(new Object[] {mainClassName, e.toString()}), e); } if (cls == null) { finishDebugger(); throw new DebuggerException( new MessageFormat(bundle.getString("EXC_Cannot_find_class")) .format(new Object[] {mainClassName, new ClassNotFoundException().toString()})); } } // set breakpoint on stop class method ............................................... if (stopOnMain) { RemoteClass stopClass = null; try { stopClass = remoteDebugger.findClass(stopClassName = info.getStopClassName()); } catch (Throwable e) { if (e instanceof ThreadDeath) throw (ThreadDeath) e; println( bundle.getString("MSG_Exc_while_finding_class") + stopClassName + '\n' + e, ERR_OUT); } if (stopClass == null) { println(bundle.getString("CTL_No_such_class") + ": " + stopClassName, ERR_OUT); } else { try { RemoteField[] rf = stopClass.getMethods(); int i, k = rf.length; Type t = Type.tMethod(Type.tVoid, new Type[] {Type.tArray(Type.tString)}); Type startT = Type.tMethod(Type.tVoid); RemoteField startM = null; RemoteField initM = null; RemoteField constM = null; for (i = 0; i < k; i++) { if (rf[i].getName().equals("main") && // NOI18N rf[i].getType().equals(t)) break; else if (rf[i].getName().equals("start") && // NOI18N rf[i].getType().equals(startT)) startM = rf[i]; else if (rf[i].getName().equals("init") && // NOI18N rf[i].getType().equals(startT)) initM = rf[i]; else if (rf[i].getName().equals("<init>") && // NOI18N rf[i].getType().equals(startT)) constM = rf[i]; } if (i < k) // [PENDING] stop on non main too !!!!!!!!!!!!!!!!!!!!! stopClass.setBreakpointMethod(rf[i]); // have main else if (initM != null) stopClass.setBreakpointMethod(initM); else if (startM != null) stopClass.setBreakpointMethod(startM); else if (constM != null) stopClass.setBreakpointMethod(constM); // S ystem.out.println ("Stop: " + (i <k) + " " + initM +" " + startM +" " + constM); // // NOI18N /* pendingBreakpoints = new RemoteField [1]; pendingBreakpoints [0] = rf[i]; pendingBreakpointsClass = stopClass;*/ } catch (Throwable e) { if (e instanceof ThreadDeath) throw (ThreadDeath) e; println(bundle.getString("MSG_Exc_while_setting_breakpoint") + '\n' + e, ERR_OUT); } } } // stopOnMain setBreakpoints(); updateWatches(); println(bundle.getString("CTL_Debugger_running"), STL_OUT); setDebuggerState(DEBUGGER_RUNNING); // run debugged class ............................................... if (args != null) { RemoteThreadGroup rtg = null; try { rtg = remoteDebugger.run(args.length, args); // threadGroup.setRemoteThreadGroup (rtg); } catch (Throwable e) { if (e instanceof ThreadDeath) throw (ThreadDeath) e; finishDebugger(); throw new DebuggerException( new MessageFormat(bundle.getString("EXC_While_calling_run")) .format(new Object[] {mainClassName, e.toString()}), e); } if (rtg == null) { finishDebugger(); throw new DebuggerException( new MessageFormat(bundle.getString("EXC_While_calling_run")) .format( new Object[] { mainClassName, "" // NOI18N })); } } // start refresh thread ................................................. if (debuggerThread != null) debuggerThread.stop(); debuggerThread = new Thread( new Runnable() { public void run() { for (; ; ) { try { Thread.sleep(5000); } catch (InterruptedException ex) { } if (getState() == DEBUGGER_RUNNING) try { threadGroup.threadChanged(); } catch (Throwable e) { if (e instanceof ThreadDeath) throw (ThreadDeath) e; if (e instanceof java.net.SocketException) { debuggerThread = null; try { finishDebugger(); } catch (Throwable ee) { if (ee instanceof ThreadDeath) throw (ThreadDeath) ee; } Thread.currentThread().stop(); } } } } }, "Debugger refresh thread"); // NOI18N debuggerThread.setPriority(Thread.MIN_PRIORITY); debuggerThread.start(); }
public void removeCloseListener(RemoteDebuggerCloseListener listener) { myMainDebugger.removeCloseListener(listener); }
@Override public boolean isConnected() { return myMainDebugger.isConnected(); }
@Override public void removeExceptionBreakpoint(ExceptionBreakpointCommandFactory factory) { for (RemoteDebugger d : allDebuggers()) { d.execute(factory.createRemoveCommand(d)); } }
public void addCloseListener(RemoteDebuggerCloseListener listener) { myMainDebugger.addCloseListener(listener); }
@Override public void run() throws PyDebuggerException { myMainDebugger.run(); }
@Override public String loadSource(String path) { return myMainDebugger.loadSource(path); }
@Override public String handshake() throws PyDebuggerException { return myMainDebugger.handshake(); }