private void commandFrame(StringTokenizer t) throws NoSessionException { ThreadReference current = context.getCurrentThread(); if (current == null) { env.failure("No current thread."); return; } if (!t.hasMoreTokens()) { env.error("usage: frame <frame-index>"); return; } String idToken = t.nextToken(); int n; try { n = Integer.valueOf(idToken).intValue(); } catch (NumberFormatException e) { n = 0; } if (n <= 0) { env.error("use positive frame index"); return; } try { int delta = context.setCurrentFrameIndex(current, n); if (delta == 0) { env.notice("Frame unchanged."); } else if (delta < 0) { env.notice("Moved up " + -delta + " frames."); } else { env.notice("Moved down " + delta + " frames."); } } catch (VMNotInterruptedException e) { env.failure("Target VM must be in interrupted state."); } }
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 void commandWhere(StringTokenizer t, boolean showPC) throws NoSessionException { ThreadReference current = context.getCurrentThread(); if (!t.hasMoreTokens()) { if (current == null) { env.error("No thread specified."); return; } dumpStack(current, showPC); } else { String token = t.nextToken(); if (token.toLowerCase().equals("all")) { ThreadIterator it = allThreads(); while (it.hasNext()) { ThreadReference thread = it.next(); out.println(thread.name() + ": "); dumpStack(thread, showPC); } } else { ThreadReference thread = findThread(t.nextToken()); // ### Do we want to set current thread here? // ### Should notify user of change. if (thread != null) { context.setCurrentThread(thread); } dumpStack(thread, showPC); } } }
private void commandStop(StringTokenizer t) throws NoSessionException { String token; if (!t.hasMoreTokens()) { listEventRequests(); } else { token = t.nextToken(); // Ignore optional "at" or "in" token. // Allowed for backward compatibility. if (token.equals("at") || token.equals("in")) { if (t.hasMoreTokens()) { token = t.nextToken(); } else { env.error("Missing breakpoint specification."); return; } } BreakpointSpec bpSpec = parseBreakpointSpec(token); if (bpSpec != null) { // ### Add sanity-checks for deferred breakpoint. runtime.install(bpSpec); } else { env.error("Ill-formed breakpoint specification."); } } }
private void commandClear(StringTokenizer t) throws NoSessionException { if (!t.hasMoreTokens()) { // Print set breakpoints listEventRequests(); return; } // ### need 'clear all' BreakpointSpec bpSpec = parseBreakpointSpec(t.nextToken()); if (bpSpec != null) { List<EventRequestSpec> specs = runtime.eventRequestSpecs(); if (specs.isEmpty()) { env.notice("No breakpoints set."); } else { List<EventRequestSpec> toDelete = new ArrayList<EventRequestSpec>(); for (EventRequestSpec spec : specs) { if (spec.equals(bpSpec)) { toDelete.add(spec); } } // The request used for matching should be found if (toDelete.size() <= 1) { env.notice("No matching breakpoint set."); } for (EventRequestSpec spec : toDelete) { runtime.delete(spec); } } } else { env.error("Ill-formed breakpoint specification."); } }
/** Command: unmonitor Unmonitor an expression */ private void commandUnmonitor(StringTokenizer t) throws NoSessionException { if (!t.hasMoreTokens()) { env.error("Argument required"); } else { env.getMonitorListModel().remove(t.nextToken("")); } }
private void commandKill(StringTokenizer t) throws NoSessionException { // ### Should change the way in which thread ids and threadgroup names // ### are distinguished. if (!t.hasMoreTokens()) { env.error("Usage: kill <threadgroup name> or <thread id>"); return; } while (t.hasMoreTokens()) { String idToken = t.nextToken(); ThreadReference thread = findThread(idToken); if (thread != null) { runtime.stopThread(thread); env.notice("Thread " + thread.name() + " killed."); return; } else { /* Check for threadgroup name, NOT skipping "system". */ // ### Should skip "system"? Classic 'jdb' does this. // ### Should deal with possible non-uniqueness of threadgroup names. ThreadGroupIterator itg = allThreadGroups(); while (itg.hasNext()) { ThreadGroupReference tg = itg.nextThreadGroup(); if (tg.name().equals(idToken)) { ThreadIterator it = new ThreadIterator(tg); while (it.hasNext()) { runtime.stopThread(it.nextThread()); } env.notice("Threadgroup " + tg.name() + "killed."); return; } } env.failure("\"" + idToken + "\" is not a valid threadgroup or id."); } } }
static void setExcludes(String excludeString) { StringTokenizer t = new StringTokenizer(excludeString, " ,;"); List<String> list = new ArrayList<String>(); while (t.hasMoreTokens()) { list.add(t.nextToken()); } excludes = list; }
private void commandClasspath(StringTokenizer t) { if (!t.hasMoreTokens()) { out.println(classManager.getClassPath().asString()); } else { // ### Should throw exception for invalid path. // ### E.g., vetoable property change. classManager.setClassPath(new SearchPath(t.nextToken())); } }
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); } }
int readCount(StringTokenizer t) { int cnt = 1; if (t.hasMoreTokens()) { String idToken = t.nextToken(); try { cnt = Integer.valueOf(idToken).intValue(); } catch (NumberFormatException e) { cnt = -1; } } return cnt; }
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); } }
private void commandPrint(StringTokenizer t, boolean dumpObject) throws NoSessionException { if (!t.hasMoreTokens()) { // ### Probably confused if expresion contains whitespace. env.error("No expression specified."); return; } ThreadReference current = context.getCurrentThread(); if (current == null) { env.failure("No default thread specified: " + "use the \"thread\" command first."); return; } StackFrame frame; try { frame = context.getCurrentFrame(current); if (frame == null) { env.failure("Thread has not yet created any stack frames."); return; } } catch (VMNotInterruptedException e) { env.failure("Target VM must be in interrupted state."); return; } while (t.hasMoreTokens()) { String expr = t.nextToken(""); Value val = null; try { val = runtime.evaluate(frame, expr); } catch (Exception e) { env.error("Exception: " + e); // ### Fix this! } if (val == null) { return; // Error message already printed } OutputSink out = env.getOutputSink(); if (dumpObject && (val instanceof ObjectReference) && !(val instanceof StringReference)) { ObjectReference obj = (ObjectReference) val; ReferenceType refType = obj.referenceType(); out.println(expr + " = " + val.toString() + " {"); dump(out, obj, refType, refType); out.println("}"); } else { out.println(expr + " = " + val.toString()); } out.show(); } }
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 void commandStep(StringTokenizer t) throws NoSessionException { ThreadReference current = context.getCurrentThread(); if (current == null) { env.failure("No current thread."); return; } try { if (t.hasMoreTokens() && t.nextToken().toLowerCase().equals("up")) { runtime.stepOut(current); } else { runtime.stepIntoLine(current); } } catch (AbsentInformationException e) { env.failure( "No linenumber information available -- " + "Try \"stepi\" to step by instructions."); } }
private void commandView(StringTokenizer t) throws NoSessionException { if (!t.hasMoreTokens()) { env.error("Argument required"); } else { String name = t.nextToken(); if (name.endsWith(".java") || name.indexOf(File.separatorChar) >= 0) { env.viewSource(name); } else { // ### JDI crashes taking line number for class. /** * *** ReferenceType cls = findClass(name); if (cls != null) { * env.viewLocation(cls.location()); } else { env.failure("No such class"); } *** */ String fileName = name.replace('.', File.separatorChar) + ".java"; env.viewSource(fileName); } } }
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; }
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); } } } }
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); } }
private void commandList(StringTokenizer t) throws NoSessionException { ThreadReference current = context.getCurrentThread(); if (current == null) { env.error("No thread specified."); return; } Location loc; try { StackFrame frame = context.getCurrentFrame(current); if (frame == null) { env.failure("Thread has not yet begun execution."); return; } loc = frame.location(); } catch (VMNotInterruptedException e) { env.failure("Target VM must be in interrupted state."); return; } SourceModel source = sourceManager.sourceForLocation(loc); if (source == null) { if (loc.method().isNative()) { env.failure("Current method is native."); return; } env.failure("No source available for " + Utils.locationString(loc) + "."); return; } ReferenceType refType = loc.declaringType(); int lineno = loc.lineNumber(); if (t.hasMoreTokens()) { String id = t.nextToken(); // See if token is a line number. try { lineno = Integer.valueOf(id).intValue(); } catch (NumberFormatException nfe) { // It isn't -- see if it's a method name. List<Method> meths = refType.methodsByName(id); if (meths == null || meths.size() == 0) { env.failure( id + " is not a valid line number or " + "method name for class " + refType.name()); return; } else if (meths.size() > 1) { env.failure(id + " is an ambiguous method name in" + refType.name()); return; } loc = meths.get(0).location(); lineno = loc.lineNumber(); } } int startLine = (lineno > 4) ? lineno - 4 : 1; int endLine = startLine + 9; String sourceLine = source.sourceLine(lineno); if (sourceLine == null) { env.failure("" + lineno + " is an invalid line number for " + refType.name()); } else { OutputSink out = env.getOutputSink(); for (int i = startLine; i <= endLine; i++) { sourceLine = source.sourceLine(i); if (sourceLine == null) { break; } out.print(i); out.print("\t"); if (i == lineno) { out.print("=> "); } else { out.print(" "); } out.println(sourceLine); } out.show(); } }
public void executeCommand(String command) { // ### Treatment of 'out' here is dirty... out = env.getOutputSink(); if (echo) { out.println(">>> " + command); } StringTokenizer t = new StringTokenizer(command); try { String cmd; if (t.hasMoreTokens()) { cmd = t.nextToken().toLowerCase(); lastCommand = cmd; } else { cmd = lastCommand; } if (cmd.equals("print")) { commandPrint(t, false); } else if (cmd.equals("eval")) { commandPrint(t, false); } else if (cmd.equals("dump")) { commandPrint(t, true); } else if (cmd.equals("locals")) { commandLocals(); } else if (cmd.equals("classes")) { commandClasses(); } else if (cmd.equals("methods")) { commandMethods(t); } else if (cmd.equals("threads")) { commandThreads(t); } else if (cmd.equals("thread")) { commandThread(t); } else if (cmd.equals("suspend")) { commandSuspend(t); } else if (cmd.equals("resume")) { commandResume(t); } else if (cmd.equals("cont")) { commandCont(); } else if (cmd.equals("threadgroups")) { commandThreadGroups(); } else if (cmd.equals("threadgroup")) { commandThreadGroup(t); } else if (cmd.equals("run")) { commandRun(t); } else if (cmd.equals("load")) { commandLoad(t); } else if (cmd.equals("connect")) { commandConnect(t); } else if (cmd.equals("attach")) { commandAttach(t); } else if (cmd.equals("detach")) { commandDetach(t); } else if (cmd.equals("interrupt")) { commandInterrupt(t); // ### Not implemented. // } else if (cmd.equals("catch")) { // commandCatchException(t); // ### Not implemented. // } else if (cmd.equals("ignore")) { // commandIgnoreException(t); } else if (cmd.equals("step")) { commandStep(t); } else if (cmd.equals("stepi")) { commandStepi(); } else if (cmd.equals("next")) { commandNext(); } else if (cmd.equals("nexti")) { commandNexti(); } else if (cmd.equals("kill")) { commandKill(t); } else if (cmd.equals("where")) { commandWhere(t, false); } else if (cmd.equals("wherei")) { commandWhere(t, true); } else if (cmd.equals("up")) { commandUp(t); } else if (cmd.equals("down")) { commandDown(t); } else if (cmd.equals("frame")) { commandFrame(t); } else if (cmd.equals("stop")) { commandStop(t); } else if (cmd.equals("clear")) { commandClear(t); } else if (cmd.equals("list")) { commandList(t); } else if (cmd.equals("use")) { commandUse(t); } else if (cmd.equals("sourcepath")) { commandSourcepath(t); } else if (cmd.equals("classpath")) { commandClasspath(t); } else if (cmd.equals("monitor")) { commandMonitor(t); } else if (cmd.equals("unmonitor")) { commandUnmonitor(t); } else if (cmd.equals("view")) { commandView(t); // } else if (cmd.equals("read")) { // readCommand(t); } else if (cmd.equals("help") || cmd.equals("?")) { help(); } else if (cmd.equals("quit") || cmd.equals("exit")) { try { runtime.detach(); } catch (NoSessionException e) { // ignore } env.terminate(); } else { // ### Dubious repeat-count feature inherited from 'jdb' if (t.hasMoreTokens()) { try { int repeat = Integer.parseInt(cmd); String subcom = t.nextToken(""); while (repeat-- > 0) { executeCommand(subcom); } return; } catch (NumberFormatException exc) { } } out.println("huh? Try help..."); out.flush(); } } catch (NoSessionException e) { out.println("There is no currently attached VM session."); out.flush(); } catch (Exception e) { out.println("Internal exception: " + e.toString()); out.flush(); System.out.println("JDB internal exception: " + e.toString()); e.printStackTrace(); } out.show(); }
private BreakpointSpec parseBreakpointSpec(String bptSpec) { StringTokenizer t = new StringTokenizer(bptSpec); BreakpointSpec bpSpec = null; // try { String token = t.nextToken("@:( \t\n\r"); // We can't use hasMoreTokens here because it will cause any leading // paren to be lost. String rest; try { rest = t.nextToken("").trim(); } catch (NoSuchElementException e) { rest = null; } if ((rest != null) && rest.startsWith("@")) { t = new StringTokenizer(rest.substring(1)); String sourceName = token; String lineToken = t.nextToken(); int lineNumber = Integer.valueOf(lineToken).intValue(); if (t.hasMoreTokens()) { return null; } bpSpec = runtime.createSourceLineBreakpoint(sourceName, lineNumber); } else if ((rest != null) && rest.startsWith(":")) { t = new StringTokenizer(rest.substring(1)); String classId = token; String lineToken = t.nextToken(); int lineNumber = Integer.valueOf(lineToken).intValue(); if (t.hasMoreTokens()) { return null; } bpSpec = runtime.createClassLineBreakpoint(classId, lineNumber); } else { // Try stripping method from class.method token. int idot = token.lastIndexOf("."); if ((idot <= 0) || /* No dot or dot in first char */ (idot >= token.length() - 1)) { /* dot in last char */ return null; } String methodName = token.substring(idot + 1); String classId = token.substring(0, idot); List<String> argumentList = null; if (rest != null) { if (!rest.startsWith("(") || !rest.endsWith(")")) { // ### Should throw exception with error message // out.println("Invalid method specification: " // + methodName + rest); return null; } // Trim the parens // ### What about spaces in arglist? rest = rest.substring(1, rest.length() - 1); argumentList = new ArrayList<String>(); t = new StringTokenizer(rest, ","); while (t.hasMoreTokens()) { argumentList.add(t.nextToken()); } } bpSpec = runtime.createMethodBreakpoint(classId, methodName, argumentList); } // } catch (Exception e) { // env.error("Exception attempting to create breakpoint: " + e); // return null; // } return bpSpec; }