/* * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.tools.example.debug.gui; import java.io.*;import java.util.*; import com.sun.jdi.*;import com.sun.tools.example.debug.bdi.*; public class CommandInterpreter { boolean echo; Environment env; private ContextManager context; private ExecutionManager runtime; private ClassManager classManager; private SourceManager sourceManager; private OutputSink out; //### Hack! Should be local in each method used. private String lastCommand = "help"; public CommandInterpreter(Environment env) { this(env, true); } public CommandInterpreter(Environment env, boolean echo) { this.env = env; this.echo = echo; this.runtime = env.getExecutionManager(); this.context = env.getContextManager(); this.classManager = env.getClassManager(); this.sourceManager = env.getSourceManager(); } private ThreadReference[] threads = null; /* * The numbering of threads is relative to the current set of threads, * and may be affected by the creation and termination of new threads. * Commands issued using such thread ids will only give reliable behavior * relative to what was shown earlier in 'list' commands if the VM is interrupted. * We need a better scheme. */ private ThreadReference[] threads() throws NoSessionException { if (threads == null) { ThreadIterator ti = new ThreadIterator(getDefaultThreadGroup()); List<ThreadReference> tlist = new ArrayList<ThreadReference>(); while (ti.hasNext()) { tlist.add(ti.nextThread()); } threads = tlist.toArray(new ThreadReference[tlist.size()]); } return threads; } private ThreadReference findThread(String idToken) throws NoSessionException { String id; ThreadReference thread = null; if (idToken.startsWith("t@")) { id = idToken.substring(2); } else { id = idToken; } try { ThreadReference[] threads = threads(); long threadID = Long.parseLong(id, 16); for (ThreadReference thread2 : threads) { if (thread2.uniqueID() == threadID) { thread = thread2; break; } } if (thread == null) { //env.failure("No thread for id \"" + idToken + "\""); env.failure("\"" + idToken + "\" is not a valid thread id."); } } catch (NumberFormatException e) { env.error("Thread id \"" + idToken + "\" is ill-formed."); thread = null; } return thread; } private ThreadIterator allThreads() throws NoSessionException { threads = null; //### Why not use runtime.allThreads().iterator() ? return new ThreadIterator(runtime.topLevelThreadGroups()); } private ThreadIterator currentThreadGroupThreads() throws NoSessionException { threads = null; return new ThreadIterator(getDefaultThreadGroup()); } private ThreadGroupIterator allThreadGroups() throws NoSessionException { threads = null; return new ThreadGroupIterator(runtime.topLevelThreadGroups()); } private ThreadGroupReference defaultThreadGroup; private ThreadGroupReference getDefaultThreadGroup() throws NoSessionException { if (defaultThreadGroup == null) { defaultThreadGroup = runtime.systemThreadGroup(); } return defaultThreadGroup; } private void setDefaultThreadGroup(ThreadGroupReference tg) { defaultThreadGroup = tg; } /* * Command handlers. */ // Command: classes private void commandClasses() throws NoSessionException { OutputSink out = env.getOutputSink(); //out.println("** classes list **"); for (ReferenceType refType : runtime.allClasses()) { out.println(refType.name()); } out.show(); } // Command: methods private void commandMethods(StringTokenizer t) throws NoSessionException { if (!t.hasMoreTokens()) { env.error("No class specified."); return; } String idClass = t.nextToken(); ReferenceType cls = findClass(idClass); if (cls != null) { List<Method> methods = cls.allMethods(); OutputSink out = env.getOutputSink(); for (int i = 0; i < methods.size(); i++) { Method method = methods.get(i); out.print(method.declaringType().name() + " " + method.name() + "("); Iterator<String> it = method.argumentTypeNames().iterator(); if (it.hasNext()) { while (true) { out.print(it.next()); if (!it.hasNext()) { break; } out.print(", "); } } out.println(")"); } out.show(); } else { //### Should validate class name syntax. env.failure("\"" + idClass + "\" is not a valid id or class name."); } } private ReferenceType findClass(String pattern) throws NoSessionException { List<ReferenceType> results = runtime.findClassesMatchingPattern(pattern); if (results.size() > 0) { //### Should handle multiple results sensibly. return results.get(0); } return null; } // Command: threads private void commandThreads(StringTokenizer t) throws NoSessionException { if (!t.hasMoreTokens()) { OutputSink out = env.getOutputSink(); printThreadGroup(out, getDefaultThreadGroup(), 0); out.show(); return; } String name = t.nextToken(); ThreadGroupReference tg = findThreadGroup(name); if (tg == null) { env.failure(name + " is not a valid threadgroup name."); } else { OutputSink out = env.getOutputSink(); printThreadGroup(out, tg, 0); out.show(); } } private ThreadGroupReference findThreadGroup(String name) throws NoSessionException { //### Issue: Uniqueness of thread group names is not enforced. ThreadGroupIterator tgi = allThreadGroups(); while (tgi.hasNext()) { ThreadGroupReference tg = tgi.nextThreadGroup(); if (tg.name().equals(name)) { return tg; } } return null; } private int printThreadGroup(OutputSink out, ThreadGroupReference tg, int iThread) { out.println("Group " + tg.name() + ":"); List<ThreadReference> tlist = tg.threads(); int maxId = 0; int maxName = 0; for (int i = 0 ; i < tlist.size() ; i++) { ThreadReference thr = tlist.get(i); int len = Utils.description(thr).length(); if (len > maxId) { maxId = len; } String name = thr.name(); int iDot = name.lastIndexOf('.'); if (iDot >= 0 && name.length() > iDot) { name = name.substring(iDot + 1); } if (name.length() > maxName) { maxName = name.length(); } } String maxNumString = String.valueOf(iThread + tlist.size()); int maxNumDigits = maxNumString.length(); for (int i = 0 ; i < tlist.size() ; i++) { ThreadReference thr = tlist.get(i); char buf[] = new char[80]; for (int j = 0; j < 79; j++) { buf[j] = ' '; } buf[79] = '\0'; StringBuffer sbOut = new StringBuffer(); sbOut.append(buf); // Right-justify the thread number at start of output string String numString = String.valueOf(iThread + i + 1); sbOut.insert(maxNumDigits - numString.length(), numString); sbOut.insert(maxNumDigits, "."); int iBuf = maxNumDigits + 2; sbOut.insert(iBuf, Utils.description(thr)); iBuf += maxId + 1; String name = thr.name(); int iDot = name.lastIndexOf('.'); if (iDot >= 0 && name.length() > iDot) { name = name.substring(iDot + 1); } sbOut.insert(iBuf, name); iBuf += maxName + 1; sbOut.insert(iBuf, Utils.getStatus(thr)); sbOut.setLength(79); out.println(sbOut.toString()); } for (ThreadGroupReference tg0 : tg.threadGroups()) { if (!tg.equals(tg0)) { // TODO ref mgt iThread += printThreadGroup(out, tg0, iThread + tlist.size()); } } return tlist.size(); } // Command: threadgroups private void commandThreadGroups() throws NoSessionException { ThreadGroupIterator it = allThreadGroups(); int cnt = 0; OutputSink out = env.getOutputSink(); while (it.hasNext()) { ThreadGroupReference tg = it.nextThreadGroup(); ++cnt; out.println("" + cnt + ". " + Utils.description(tg) + " " + tg.name()); } out.show(); } // Command: thread private void commandThread(StringTokenizer t) throws NoSessionException { if (!t.hasMoreTokens()) { env.error("Thread number not specified."); return; } ThreadReference thread = findThread(t.nextToken()); if (thread != null) { //### Should notify user. context.setCurrentThread(thread); } } // Command: threadgroup private void commandThreadGroup(StringTokenizer t) throws NoSessionException { if (!t.hasMoreTokens()) { env.error("Threadgroup name not specified."); return; } String name = t.nextToken(); ThreadGroupReference tg = findThreadGroup(name); if (tg == null) { env.failure(name + " is not a valid threadgroup name."); } else { //### Should notify user. setDefaultThreadGroup(tg); } } // Command: run private void commandRun(StringTokenizer t) throws NoSessionException { if (doLoad(false, t)) { env.notice("Running ..."); } } // Command: load private void commandLoad(StringTokenizer t) throws NoSessionException { if (doLoad(true, t)) {} } private boolean doLoad(boolean suspended, StringTokenizer t) throws NoSessionException { String clname; if (!t.hasMoreTokens()) { clname = context.getMainClassName(); if (!clname.equals("")) { // Run from prevously-set class name. try { String vmArgs = context.getVmArguments(); runtime.run(suspended, vmArgs, clname, context.getProgramArguments()); return true; } catch (VMLaunchFailureException e) { env.failure("Attempt to launch main class \"" + clname + "\" failed."); } } else { env.failure("No main class specifed and no current default defined."); } } else { clname = t.nextToken(); StringBuffer sbuf = new StringBuffer(); // Allow VM arguments to be specified here? while (t.hasMoreTokens()) { String tok = t.nextToken(); sbuf.append(tok); if (t.hasMoreTokens()) { sbuf.append(' '); } } String args = sbuf.toString(); try { String vmArgs = context.getVmArguments(); runtime.run(suspended, vmArgs, clname, args); context.setMainClassName(clname); //context.setVmArguments(vmArgs); context.setProgramArguments(args); return true; } catch (VMLaunchFailureException e) { env.failure("Attempt to launch main class \"" + clname + "\" failed."); } } return false; } // Command: connect private void commandConnect(StringTokenizer t) { try { LaunchTool.queryAndLaunchVM(runtime); } catch (VMLaunchFailureException e) { env.failure("Attempt to connect failed."); } } // Command: attach private void commandAttach(StringTokenizer t) { String portName; if (!t.hasMoreTokens()) { portName = context.getRemotePort(); if (!portName.equals("")) { try { runtime.attach(portName); } catch (VMLaunchFailureException e) { env.failure("Attempt to attach to port \"" + portName + "\" failed."); } } else { env.failure("No port specifed and no current default defined."); } } else { portName = t.nextToken(); try { runtime.attach(portName); } catch (VMLaunchFailureException e) { env.failure("Attempt to attach to port \"" + portName + "\" failed."); } context.setRemotePort(portName); } } // Command: detach private void commandDetach(StringTokenizer t) throws NoSessionException { runtime.detach(); } // Command: interrupt private void commandInterrupt(StringTokenizer t) throws NoSessionException { runtime.interrupt(); } // Command: suspend private void commandSuspend(StringTokenizer t) throws NoSessionException { if (!t.hasMoreTokens()) { // Suspend all threads in the current thread group. //### Issue: help message says default is all threads. //### Behavior here agrees with 'jdb', however. ThreadIterator ti = currentThreadGroupThreads(); while (ti.hasNext()) { // TODO - don't suspend debugger threads ti.nextThread().suspend(); } env.notice("All (non-system) threads suspended."); } else { while (t.hasMoreTokens()) { ThreadReference thread = findThread(t.nextToken()); if (thread != null) { //thread.suspend(); runtime.suspendThread(thread); } } } } // Command: resume private void commandResume(StringTokenizer t) throws NoSessionException { if (!t.hasMoreTokens()) { // Suspend all threads in the current thread group. //### Issue: help message says default is all threads. //### Behavior here agrees with 'jdb', however. ThreadIterator ti = currentThreadGroupThreads(); while (ti.hasNext()) { // TODO - don't suspend debugger threads ti.nextThread().resume(); } env.notice("All threads resumed."); } else { while (t.hasMoreTokens()) { ThreadReference thread = findThread(t.nextToken()); if (thread != null) { //thread.resume(); runtime.resumeThread(thread); } } } } // Command: cont private void commandCont() throws NoSessionException { try { runtime.go(); } catch (VMNotInterruptedException e) {Lines 1–500 of 1459. Load more
/* * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.tools.example.debug.gui; import java.io.*; import java.util.*; import com.sun.jdi.*; import com.sun.tools.example.debug.bdi.*; public class CommandInterpreter { boolean echo; Environment env; private ContextManager context; private ExecutionManager runtime; private ClassManager classManager; private SourceManager sourceManager; private OutputSink out; //### Hack! Should be local in each method used. private String lastCommand = "help"; public CommandInterpreter(Environment env) { this(env, true); } public CommandInterpreter(Environment env, boolean echo) { this.env = env; this.echo = echo; this.runtime = env.getExecutionManager(); this.context = env.getContextManager(); this.classManager = env.getClassManager(); this.sourceManager = env.getSourceManager(); } private ThreadReference[] threads = null; /* * The numbering of threads is relative to the current set of threads, * and may be affected by the creation and termination of new threads. * Commands issued using such thread ids will only give reliable behavior * relative to what was shown earlier in 'list' commands if the VM is interrupted. * We need a better scheme. */ private ThreadReference[] threads() throws NoSessionException { if (threads == null) { ThreadIterator ti = new ThreadIterator(getDefaultThreadGroup()); List<ThreadReference> tlist = new ArrayList<ThreadReference>(); while (ti.hasNext()) { tlist.add(ti.nextThread()); } threads = tlist.toArray(new ThreadReference[tlist.size()]); } return threads; } private ThreadReference findThread(String idToken) throws NoSessionException { String id; ThreadReference thread = null; if (idToken.startsWith("t@")) { id = idToken.substring(2); } else { id = idToken; } try { ThreadReference[] threads = threads(); long threadID = Long.parseLong(id, 16); for (ThreadReference thread2 : threads) { if (thread2.uniqueID() == threadID) { thread = thread2; break; } } if (thread == null) { //env.failure("No thread for id \"" + idToken + "\""); env.failure("\"" + idToken + "\" is not a valid thread id."); } } catch (NumberFormatException e) { env.error("Thread id \"" + idToken + "\" is ill-formed."); thread = null; } return thread; } private ThreadIterator allThreads() throws NoSessionException { threads = null; //### Why not use runtime.allThreads().iterator() ? return new ThreadIterator(runtime.topLevelThreadGroups()); } private ThreadIterator currentThreadGroupThreads() throws NoSessionException { threads = null; return new ThreadIterator(getDefaultThreadGroup()); } private ThreadGroupIterator allThreadGroups() throws NoSessionException { threads = null; return new ThreadGroupIterator(runtime.topLevelThreadGroups()); } private ThreadGroupReference defaultThreadGroup; private ThreadGroupReference getDefaultThreadGroup() throws NoSessionException { if (defaultThreadGroup == null) { defaultThreadGroup = runtime.systemThreadGroup(); } return defaultThreadGroup; } private void setDefaultThreadGroup(ThreadGroupReference tg) { defaultThreadGroup = tg; } /* * Command handlers. */ // Command: classes private void commandClasses() throws NoSessionException { OutputSink out = env.getOutputSink(); //out.println("** classes list **"); for (ReferenceType refType : runtime.allClasses()) { out.println(refType.name()); } out.show(); } // Command: methods private void commandMethods(StringTokenizer t) throws NoSessionException { if (!t.hasMoreTokens()) { env.error("No class specified."); return; } String idClass = t.nextToken(); ReferenceType cls = findClass(idClass); if (cls != null) { List<Method> methods = cls.allMethods(); OutputSink out = env.getOutputSink(); for (int i = 0; i < methods.size(); i++) { Method method = methods.get(i); out.print(method.declaringType().name() + " " + method.name() + "("); Iterator<String> it = method.argumentTypeNames().iterator(); if (it.hasNext()) { while (true) { out.print(it.next()); if (!it.hasNext()) { break; } out.print(", "); } } out.println(")"); } out.show(); } else { //### Should validate class name syntax. env.failure("\"" + idClass + "\" is not a valid id or class name."); } } private ReferenceType findClass(String pattern) throws NoSessionException { List<ReferenceType> results = runtime.findClassesMatchingPattern(pattern); if (results.size() > 0) { //### Should handle multiple results sensibly. return results.get(0); } return null; } // Command: threads private void commandThreads(StringTokenizer t) throws NoSessionException { if (!t.hasMoreTokens()) { OutputSink out = env.getOutputSink(); printThreadGroup(out, getDefaultThreadGroup(), 0); out.show(); return; } String name = t.nextToken(); ThreadGroupReference tg = findThreadGroup(name); if (tg == null) { env.failure(name + " is not a valid threadgroup name."); } else { OutputSink out = env.getOutputSink(); printThreadGroup(out, tg, 0); out.show(); } } private ThreadGroupReference findThreadGroup(String name) throws NoSessionException { //### Issue: Uniqueness of thread group names is not enforced. ThreadGroupIterator tgi = allThreadGroups(); while (tgi.hasNext()) { ThreadGroupReference tg = tgi.nextThreadGroup(); if (tg.name().equals(name)) { return tg; } } return null; } private int printThreadGroup(OutputSink out, ThreadGroupReference tg, int iThread) { out.println("Group " + tg.name() + ":"); List<ThreadReference> tlist = tg.threads(); int maxId = 0; int maxName = 0; for (int i = 0 ; i < tlist.size() ; i++) { ThreadReference thr = tlist.get(i); int len = Utils.description(thr).length(); if (len > maxId) { maxId = len; } String name = thr.name(); int iDot = name.lastIndexOf('.'); if (iDot >= 0 && name.length() > iDot) { name = name.substring(iDot + 1); } if (name.length() > maxName) { maxName = name.length(); } } String maxNumString = String.valueOf(iThread + tlist.size()); int maxNumDigits = maxNumString.length(); for (int i = 0 ; i < tlist.size() ; i++) { ThreadReference thr = tlist.get(i); char buf[] = new char[80]; for (int j = 0; j < 79; j++) { buf[j] = ' '; } buf[79] = '\0'; StringBuffer sbOut = new StringBuffer(); sbOut.append(buf); // Right-justify the thread number at start of output string String numString = String.valueOf(iThread + i + 1); sbOut.insert(maxNumDigits - numString.length(), numString); sbOut.insert(maxNumDigits, "."); int iBuf = maxNumDigits + 2; sbOut.insert(iBuf, Utils.description(thr)); iBuf += maxId + 1; String name = thr.name(); int iDot = name.lastIndexOf('.'); if (iDot >= 0 && name.length() > iDot) { name = name.substring(iDot + 1); } sbOut.insert(iBuf, name); iBuf += maxName + 1; sbOut.insert(iBuf, Utils.getStatus(thr)); sbOut.setLength(79); out.println(sbOut.toString()); } for (ThreadGroupReference tg0 : tg.threadGroups()) { if (!tg.equals(tg0)) { // TODO ref mgt iThread += printThreadGroup(out, tg0, iThread + tlist.size()); } } return tlist.size(); } // Command: threadgroups private void commandThreadGroups() throws NoSessionException { ThreadGroupIterator it = allThreadGroups(); int cnt = 0; OutputSink out = env.getOutputSink(); while (it.hasNext()) { ThreadGroupReference tg = it.nextThreadGroup(); ++cnt; out.println("" + cnt + ". " + Utils.description(tg) + " " + tg.name()); } out.show(); } // Command: thread private void commandThread(StringTokenizer t) throws NoSessionException { if (!t.hasMoreTokens()) { env.error("Thread number not specified."); return; } ThreadReference thread = findThread(t.nextToken()); if (thread != null) { //### Should notify user. context.setCurrentThread(thread); } } // Command: threadgroup private void commandThreadGroup(StringTokenizer t) throws NoSessionException { if (!t.hasMoreTokens()) { env.error("Threadgroup name not specified."); return; } String name = t.nextToken(); ThreadGroupReference tg = findThreadGroup(name); if (tg == null) { env.failure(name + " is not a valid threadgroup name."); } else { //### Should notify user. setDefaultThreadGroup(tg); } } // Command: run private void commandRun(StringTokenizer t) throws NoSessionException { if (doLoad(false, t)) { env.notice("Running ..."); } } // Command: load private void commandLoad(StringTokenizer t) throws NoSessionException { if (doLoad(true, t)) {} } private boolean doLoad(boolean suspended, StringTokenizer t) throws NoSessionException { String clname; if (!t.hasMoreTokens()) { clname = context.getMainClassName(); if (!clname.equals("")) { // Run from prevously-set class name. try { String vmArgs = context.getVmArguments(); runtime.run(suspended, vmArgs, clname, context.getProgramArguments()); return true; } catch (VMLaunchFailureException e) { env.failure("Attempt to launch main class \"" + clname + "\" failed."); } } else { env.failure("No main class specifed and no current default defined."); } } else { clname = t.nextToken(); StringBuffer sbuf = new StringBuffer(); // Allow VM arguments to be specified here? while (t.hasMoreTokens()) { String tok = t.nextToken(); sbuf.append(tok); if (t.hasMoreTokens()) { sbuf.append(' '); } } String args = sbuf.toString(); try { String vmArgs = context.getVmArguments(); runtime.run(suspended, vmArgs, clname, args); context.setMainClassName(clname); //context.setVmArguments(vmArgs); context.setProgramArguments(args); return true; } catch (VMLaunchFailureException e) { env.failure("Attempt to launch main class \"" + clname + "\" failed."); } } return false; } // Command: connect private void commandConnect(StringTokenizer t) { try { LaunchTool.queryAndLaunchVM(runtime); } catch (VMLaunchFailureException e) { env.failure("Attempt to connect failed."); } } // Command: attach private void commandAttach(StringTokenizer t) { String portName; if (!t.hasMoreTokens()) { portName = context.getRemotePort(); if (!portName.equals("")) { try { runtime.attach(portName); } catch (VMLaunchFailureException e) { env.failure("Attempt to attach to port \"" + portName + "\" failed."); } } else { env.failure("No port specifed and no current default defined."); } } else { portName = t.nextToken(); try { runtime.attach(portName); } catch (VMLaunchFailureException e) { env.failure("Attempt to attach to port \"" + portName + "\" failed."); } context.setRemotePort(portName); } } // Command: detach private void commandDetach(StringTokenizer t) throws NoSessionException { runtime.detach(); } // Command: interrupt private void commandInterrupt(StringTokenizer t) throws NoSessionException { runtime.interrupt(); } // Command: suspend private void commandSuspend(StringTokenizer t) throws NoSessionException { if (!t.hasMoreTokens()) { // Suspend all threads in the current thread group. //### Issue: help message says default is all threads. //### Behavior here agrees with 'jdb', however. ThreadIterator ti = currentThreadGroupThreads(); while (ti.hasNext()) { // TODO - don't suspend debugger threads ti.nextThread().suspend(); } env.notice("All (non-system) threads suspended."); } else { while (t.hasMoreTokens()) { ThreadReference thread = findThread(t.nextToken()); if (thread != null) { //thread.suspend(); runtime.suspendThread(thread); } } } } // Command: resume private void commandResume(StringTokenizer t) throws NoSessionException { if (!t.hasMoreTokens()) { // Suspend all threads in the current thread group. //### Issue: help message says default is all threads. //### Behavior here agrees with 'jdb', however. ThreadIterator ti = currentThreadGroupThreads(); while (ti.hasNext()) { // TODO - don't suspend debugger threads ti.nextThread().resume(); } env.notice("All threads resumed."); } else { while (t.hasMoreTokens()) { ThreadReference thread = findThread(t.nextToken()); if (thread != null) { //thread.resume(); runtime.resumeThread(thread); } } } } // Command: cont private void commandCont() throws NoSessionException { try { runtime.go(); } catch (VMNotInterruptedException e) {