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."); } } }
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."); } }
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 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 commandNexti() throws NoSessionException { ThreadReference current = context.getCurrentThread(); if (current == null) { env.failure("No current thread."); return; } runtime.stepOverInstruction(current); }
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; }
private void commandClasses() throws NoSessionException { OutputSink out = env.getOutputSink(); // out.println("** classes list **"); for (ReferenceType refType : runtime.allClasses()) { out.println(refType.name()); } out.show(); }
private void commandCont() throws NoSessionException { try { runtime.go(); } catch (VMNotInterruptedException e) { // ### failure? env.notice("Target VM is already running."); } }
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 commandNext() throws NoSessionException { ThreadReference current = context.getCurrentThread(); if (current == null) { env.failure("No current thread."); return; } try { runtime.stepOverLine(current); } catch (AbsentInformationException e) { env.failure( "No linenumber information available -- " + "Try \"nexti\" to step by instructions."); } }
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 listEventRequests() throws NoSessionException { // Print set breakpoints List<EventRequestSpec> specs = runtime.eventRequestSpecs(); if (specs.isEmpty()) { env.notice("No breakpoints/watchpoints/exceptions set."); } else { OutputSink out = env.getOutputSink(); out.println("Current breakpoints/watchpoints/exceptions set:"); for (EventRequestSpec bp : specs) { out.println("\t" + bp); } out.show(); } }
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 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 commandInterrupt(StringTokenizer t) throws NoSessionException { runtime.interrupt(); }
private ThreadGroupIterator allThreadGroups() throws NoSessionException { threads = null; return new ThreadGroupIterator(runtime.topLevelThreadGroups()); }
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; }
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 ThreadGroupReference getDefaultThreadGroup() throws NoSessionException { if (defaultThreadGroup == null) { defaultThreadGroup = runtime.systemThreadGroup(); } return defaultThreadGroup; }
private void commandDetach(StringTokenizer t) throws NoSessionException { runtime.detach(); }
private ThreadIterator allThreads() throws NoSessionException { threads = null; // ### Why not use runtime.allThreads().iterator() ? return new ThreadIterator(runtime.topLevelThreadGroups()); }