< prev index next >
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java
Print this page
*** 22,49 ****
--- 22,58 ----
*
*/
package sun.jvm.hotspot;
+ import java.lang.module.Configuration;
+ import java.lang.module.ModuleFinder;
+ import java.nio.file.Path;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
+ import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+ import java.util.ServiceLoader;
+ import java.util.Set;
import java.util.Stack;
+ import java.util.stream.Collectors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+ import sun.jvm.hotspot.api.Command;
+ import sun.jvm.hotspot.api.Tokens;
import sun.jvm.hotspot.ci.ciEnv;
import sun.jvm.hotspot.code.CodeBlob;
import sun.jvm.hotspot.code.CodeCacheVisitor;
import sun.jvm.hotspot.code.NMethod;
import sun.jvm.hotspot.debugger.Address;
*** 136,271 ****
emitted.put(kls.getName(), kls);
return true;
}
}
! static class Tokens {
! final String input;
! int i;
! String[] tokens;
! int length;
!
! String[] splitWhitespace(String cmd) {
! String[] t = cmd.split("\\s");
! if (t.length == 1 && t[0].length() == 0) {
! return new String[0];
! }
! return t;
! }
!
! void add(String s, ArrayList t) {
! if (s.length() > 0) {
! t.add(s);
! }
! }
!
! Tokens(String cmd) {
! input = cmd;
!
! // check for quoting
! int quote = cmd.indexOf('"');
! ArrayList t = new ArrayList();
! if (quote != -1) {
! while (cmd.length() > 0) {
! if (quote != -1) {
! int endquote = cmd.indexOf('"', quote + 1);
! if (endquote == -1) {
! throw new RuntimeException("mismatched quotes: " + input);
! }
!
! String before = cmd.substring(0, quote).trim();
! String quoted = cmd.substring(quote + 1, endquote);
! cmd = cmd.substring(endquote + 1).trim();
! if (before.length() > 0) {
! String[] w = splitWhitespace(before);
! for (int i = 0; i < w.length; i++) {
! add(w[i], t);
! }
! }
! add(quoted, t);
! quote = cmd.indexOf('"');
! } else {
! String[] w = splitWhitespace(cmd);
! for (int i = 0; i < w.length; i++) {
! add(w[i], t);
! }
! cmd = "";
!
! }
! }
! } else {
! String[] w = splitWhitespace(cmd);
! for (int i = 0; i < w.length; i++) {
! add(w[i], t);
! }
! }
! tokens = (String[])t.toArray(new String[0]);
! i = 0;
! length = tokens.length;
!
! //for (int i = 0; i < tokens.length; i++) {
! // System.out.println("\"" + tokens[i] + "\"");
! //}
! }
!
! String nextToken() {
! return tokens[i++];
! }
! boolean hasMoreTokens() {
! return i < length;
! }
! int countTokens() {
! return length - i;
! }
! void trim(int n) {
! if (length >= n) {
! length -= n;
! } else {
! throw new IndexOutOfBoundsException(String.valueOf(n));
! }
! }
! String join(String sep) {
! StringBuffer result = new StringBuffer();
! for (int w = i; w < length; w++) {
! result.append(tokens[w]);
! if (w + 1 < length) {
! result.append(sep);
! }
! }
! return result.toString();
! }
!
! String at(int i) {
! if (i < 0 || i >= length) {
! throw new IndexOutOfBoundsException(String.valueOf(i));
! }
! return tokens[i];
! }
! }
!
!
! abstract class Command {
! Command(String n, String u, boolean ok) {
name = n;
usage = u;
okIfDisconnected = ok;
}
! Command(String n, boolean ok) {
name = n;
usage = n;
okIfDisconnected = ok;
}
! final String name;
! final String usage;
! final boolean okIfDisconnected;
! abstract void doit(Tokens t);
! void usage() {
! out.println("Usage: " + usage);
}
void printOopValue(Oop oop) {
if (oop != null) {
Klass k = oop.getKlass();
Symbol s = k.getName();
if (s != null) {
--- 145,189 ----
emitted.put(kls.getName(), kls);
return true;
}
}
! abstract class ClhsdbCommand implements Command {
! ClhsdbCommand(String n, String u, boolean ok) {
name = n;
usage = u;
okIfDisconnected = ok;
}
! ClhsdbCommand(String n, boolean ok) {
name = n;
usage = n;
okIfDisconnected = ok;
}
! private final String name;
! private final String usage;
! private final boolean okIfDisconnected;
!
! @Override
! public String name() {
! return name;
! }
!
! @Override
! public String usage() {
! return "Usage: " + usage;
! }
!
! @Override
! public boolean okIfDisconnected() {
! return okIfDisconnected;
}
+ @Override
+ public abstract void doit(Tokens t, PrintStream out);
+
void printOopValue(Oop oop) {
if (oop != null) {
Klass k = oop.getKlass();
Symbol s = k.getName();
if (s != null) {
*** 388,411 ****
Address parseAddress(String addr) {
return VM.getVM().getDebugger().parseAddress(addr);
}
private final Command[] commandList = {
! new Command("reattach", true) {
! public void doit(Tokens t) {
int tokens = t.countTokens();
if (tokens != 0) {
usage();
return;
}
preAttach();
debugger.reattach();
postAttach();
}
},
! new Command("attach", "attach pid | exec core", true) {
! public void doit(Tokens t) {
int tokens = t.countTokens();
if (tokens == 1) {
preAttach();
debugger.attach(t.nextToken());
postAttach();
--- 306,331 ----
Address parseAddress(String addr) {
return VM.getVM().getDebugger().parseAddress(addr);
}
private final Command[] commandList = {
! new ClhsdbCommand("reattach", true) {
! @Override
! public void doit(Tokens t, PrintStream out) {
int tokens = t.countTokens();
if (tokens != 0) {
usage();
return;
}
preAttach();
debugger.reattach();
postAttach();
}
},
! new ClhsdbCommand("attach", "attach pid | exec core", true) {
! @Override
! public void doit(Tokens t, PrintStream out) {
int tokens = t.countTokens();
if (tokens == 1) {
preAttach();
debugger.attach(t.nextToken());
postAttach();
*** 416,435 ****
} else {
usage();
}
}
},
! new Command("detach", false) {
! public void doit(Tokens t) {
if (t.countTokens() != 0) {
usage();
} else {
debugger.detach();
}
}
},
! new Command("examine", "examine [ address/count ] | [ address,address]", false) {
Pattern args1 = Pattern.compile("^(0x[0-9a-f]+)(/([0-9]*)([a-z]*))?$");
Pattern args2 = Pattern.compile("^(0x[0-9a-f]+),(0x[0-9a-f]+)(/[a-z]*)?$");
String fill(Address a, int width) {
String s = "0x0";
--- 336,356 ----
} else {
usage();
}
}
},
! new ClhsdbCommand("detach", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 0) {
usage();
} else {
debugger.detach();
}
}
},
! new ClhsdbCommand("examine", "examine [ address/count ] | [ address,address]", false) {
Pattern args1 = Pattern.compile("^(0x[0-9a-f]+)(/([0-9]*)([a-z]*))?$");
Pattern args2 = Pattern.compile("^(0x[0-9a-f]+),(0x[0-9a-f]+)(/[a-z]*)?$");
String fill(Address a, int width) {
String s = "0x0";
*** 440,450 ****
return s.substring(0, 2) + "000000000000000000000".substring(0, width - s.length()) + s.substring(2);
}
return s;
}
! public void doit(Tokens t) {
if (t.countTokens() != 1) {
usage();
} else {
String arg = t.nextToken();
Matcher m1 = args1.matcher(arg);
--- 361,372 ----
return s.substring(0, 2) + "000000000000000000000".substring(0, width - s.length()) + s.substring(2);
}
return s;
}
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
String arg = t.nextToken();
Matcher m1 = args1.matcher(arg);
*** 499,513 ****
out.println();
}
}
}
},
! new Command("dumpreplaydata", "dumpreplaydata { <address > | -a | <thread_id> }", false) {
// This is used to dump replay data from ciInstanceKlass, ciMethodData etc
// default file name is replay.txt, also if java crashes in compiler
// thread, this file will be dumped in error processing.
! public void doit(Tokens t) {
if (t.countTokens() != 1) {
usage();
return;
}
String name = t.nextToken();
--- 421,436 ----
out.println();
}
}
}
},
! new ClhsdbCommand("dumpreplaydata", "dumpreplaydata { <address > | -a | <thread_id> }", false) {
// This is used to dump replay data from ciInstanceKlass, ciMethodData etc
// default file name is replay.txt, also if java crashes in compiler
// thread, this file will be dumped in error processing.
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
return;
}
String name = t.nextToken();
*** 550,565 ****
}
}
}
}
},
! new Command("buildreplayjars", "buildreplayjars [ all | app | boot ] | [ prefix ]", false) {
// This is used to dump jar files of all the classes
// loaded in the core. Everything with null classloader
// will go in boot.jar and everything else will go in
// app.jar. boot.jar usually not needed, unless changed by jvmti.
! public void doit(Tokens t) {
int tcount = t.countTokens();
if (tcount > 2) {
usage();
return;
}
--- 473,489 ----
}
}
}
}
},
! new ClhsdbCommand("buildreplayjars", "buildreplayjars [ all | app | boot ] | [ prefix ]", false) {
// This is used to dump jar files of all the classes
// loaded in the core. Everything with null classloader
// will go in boot.jar and everything else will go in
// app.jar. boot.jar usually not needed, unless changed by jvmti.
! @Override
! public void doit(Tokens t, PrintStream out) {
int tcount = t.countTokens();
if (tcount > 2) {
usage();
return;
}
*** 604,637 ****
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
},
! new Command("findpc", "findpc address", false) {
! public void doit(Tokens t) {
if (t.countTokens() != 1) {
usage();
} else {
Address a = VM.getVM().getDebugger().parseAddress(t.nextToken());
PointerLocation loc = PointerFinder.find(a);
loc.printOn(out);
}
}
},
! new Command("symbol", "symbol address", false) {
! public void doit(Tokens t) {
if (t.countTokens() != 1) {
usage();
} else {
Address a = VM.getVM().getDebugger().parseAddress(t.nextToken());
Symbol.create(a).printValueOn(out);
out.println();
}
}
},
! new Command("flags", "flags [ flag | -nd ]", false) {
! public void doit(Tokens t) {
int tokens = t.countTokens();
if (tokens != 0 && tokens != 1) {
usage();
} else {
String name = tokens > 0 ? t.nextToken() : null;
--- 528,564 ----
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
},
! new ClhsdbCommand("findpc", "findpc address", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
Address a = VM.getVM().getDebugger().parseAddress(t.nextToken());
PointerLocation loc = PointerFinder.find(a);
loc.printOn(out);
}
}
},
! new ClhsdbCommand("symbol", "symbol address", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
Address a = VM.getVM().getDebugger().parseAddress(t.nextToken());
Symbol.create(a).printValueOn(out);
out.println();
}
}
},
! new ClhsdbCommand("flags", "flags [ flag | -nd ]", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
int tokens = t.countTokens();
if (tokens != 0 && tokens != 1) {
usage();
} else {
String name = tokens > 0 ? t.nextToken() : null;
*** 663,674 ****
}
}
}
}
},
! new Command("help", "help [ command ]", true) {
! public void doit(Tokens t) {
int tokens = t.countTokens();
Command cmd = null;
if (tokens == 1) {
cmd = findCommand(t.nextToken());
}
--- 590,602 ----
}
}
}
}
},
! new ClhsdbCommand("help", "help [ command ]", true) {
! @Override
! public void doit(Tokens t, PrintStream out) {
int tokens = t.countTokens();
Command cmd = null;
if (tokens == 1) {
cmd = findCommand(t.nextToken());
}
*** 683,699 ****
return o1.toString().compareTo(o2.toString());
}
});
for (int i = 0; i < keys.length; i++) {
out.print(" ");
! out.println(((Command)commands.get(keys[i])).usage);
}
}
}
},
! new Command("history", "history", true) {
! public void doit(Tokens t) {
int tokens = t.countTokens();
if (tokens != 0 && (tokens != 1 || !t.nextToken().equals("-h"))) {
usage();
return;
}
--- 611,628 ----
return o1.toString().compareTo(o2.toString());
}
});
for (int i = 0; i < keys.length; i++) {
out.print(" ");
! out.println(((Command)commands.get(keys[i])).usage());
}
}
}
},
! new ClhsdbCommand("history", "history", true) {
! @Override
! public void doit(Tokens t, PrintStream out) {
int tokens = t.countTokens();
if (tokens != 0 && (tokens != 1 || !t.nextToken().equals("-h"))) {
usage();
return;
}
*** 703,714 ****
out.println(history.get(i));
}
}
},
// decode raw address
! new Command("dis", "dis address [length]", false) {
! public void doit(Tokens t) {
int tokens = t.countTokens();
if (tokens != 1 && tokens != 2) {
usage();
return;
}
--- 632,644 ----
out.println(history.get(i));
}
}
},
// decode raw address
! new ClhsdbCommand("dis", "dis address [length]", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
int tokens = t.countTokens();
if (tokens != 1 && tokens != 2) {
usage();
return;
}
*** 733,744 ****
out.println(generator.genHTMLForRawDisassembly(addr, len));
}
},
// decode codeblob or nmethod
! new Command("disassemble", "disassemble address", false) {
! public void doit(Tokens t) {
int tokens = t.countTokens();
if (tokens != 1) {
usage();
return;
}
--- 663,675 ----
out.println(generator.genHTMLForRawDisassembly(addr, len));
}
},
// decode codeblob or nmethod
! new ClhsdbCommand("disassemble", "disassemble address", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
int tokens = t.countTokens();
if (tokens != 1) {
usage();
return;
}
*** 754,765 ****
HTMLGenerator generator = new HTMLGenerator(false);
out.println(generator.genHTML(addr));
}
},
// print Java bytecode disassembly
! new Command("jdis", "jdis address", false) {
! public void doit(Tokens t) {
int tokens = t.countTokens();
if (tokens != 1) {
usage();
return;
}
--- 685,697 ----
HTMLGenerator generator = new HTMLGenerator(false);
out.println(generator.genHTML(addr));
}
},
// print Java bytecode disassembly
! new ClhsdbCommand("jdis", "jdis address", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
int tokens = t.countTokens();
if (tokens != 1) {
usage();
return;
}
*** 767,778 ****
Method m = (Method)Metadata.instantiateWrapperFor(a);
HTMLGenerator html = new HTMLGenerator(false);
out.println(html.genHTML(m));
}
},
! new Command("revptrs", "revptrs address", false) {
! public void doit(Tokens t) {
int tokens = t.countTokens();
if (tokens != 1 && (tokens != 2 || !t.nextToken().equals("-c"))) {
usage();
return;
}
--- 699,711 ----
Method m = (Method)Metadata.instantiateWrapperFor(a);
HTMLGenerator html = new HTMLGenerator(false);
out.println(html.genHTML(m));
}
},
! new ClhsdbCommand("revptrs", "revptrs address", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
int tokens = t.countTokens();
if (tokens != 1 && (tokens != 2 || !t.nextToken().equals("-c"))) {
usage();
return;
}
*** 829,841 ****
}
}
}
}
},
! new Command("printmdo", "printmdo [ -a | expression ]", false) {
// Print every MDO in the heap or the one referenced by expression.
! public void doit(Tokens t) {
if (t.countTokens() != 1) {
usage();
} else {
String s = t.nextToken();
if (s.equals("-a")) {
--- 762,775 ----
}
}
}
}
},
! new ClhsdbCommand("printmdo", "printmdo [ -a | expression ]", false) {
// Print every MDO in the heap or the one referenced by expression.
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
String s = t.nextToken();
if (s.equals("-a")) {
*** 865,877 ****
mdo.printDataOn(out);
}
}
}
},
! new Command("printall", "printall", false) {
// Print every MDO in the heap or the one referenced by expression.
! public void doit(Tokens t) {
if (t.countTokens() != 0) {
usage();
} else {
ClassLoaderDataGraph cldg = VM.getVM().getClassLoaderDataGraph();
cldg.classesDo(new ClassLoaderDataGraph.ClassVisitor() {
--- 799,812 ----
mdo.printDataOn(out);
}
}
}
},
! new ClhsdbCommand("printall", "printall", false) {
// Print every MDO in the heap or the one referenced by expression.
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 0) {
usage();
} else {
ClassLoaderDataGraph cldg = VM.getVM().getClassLoaderDataGraph();
cldg.classesDo(new ClassLoaderDataGraph.ClassVisitor() {
*** 888,900 ****
}
);
}
}
},
! new Command("dumpideal", "dumpideal { -a | id }", false) {
// Do a full dump of the nodes reachabile from root in each compiler thread.
! public void doit(Tokens t) {
if (t.countTokens() != 1) {
usage();
} else {
String name = t.nextToken();
boolean all = name.equals("-a");
--- 823,836 ----
}
);
}
}
},
! new ClhsdbCommand("dumpideal", "dumpideal { -a | id }", false) {
// Do a full dump of the nodes reachabile from root in each compiler thread.
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
String name = t.nextToken();
boolean all = name.equals("-a");
*** 918,930 ****
}
}
}
}
},
! new Command("dumpcfg", "dumpcfg { -a | id }", false) {
// Dump the PhaseCFG for every compiler thread that has one live.
! public void doit(Tokens t) {
if (t.countTokens() != 1) {
usage();
} else {
String name = t.nextToken();
boolean all = name.equals("-a");
--- 854,867 ----
}
}
}
}
},
! new ClhsdbCommand("dumpcfg", "dumpcfg { -a | id }", false) {
// Dump the PhaseCFG for every compiler thread that has one live.
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
String name = t.nextToken();
boolean all = name.equals("-a");
*** 946,958 ****
}
}
}
}
},
! new Command("dumpilt", "dumpilt { -a | id }", false) {
// dumps the InlineTree of a C2 compile
! public void doit(Tokens t) {
if (t.countTokens() != 1) {
usage();
} else {
String name = t.nextToken();
boolean all = name.equals("-a");
--- 883,896 ----
}
}
}
}
},
! new ClhsdbCommand("dumpilt", "dumpilt { -a | id }", false) {
// dumps the InlineTree of a C2 compile
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
String name = t.nextToken();
boolean all = name.equals("-a");
*** 976,987 ****
}
}
}
}
},
! new Command("vmstructsdump", "vmstructsdump", false) {
! public void doit(Tokens t) {
if (t.countTokens() != 0) {
usage();
return;
}
--- 914,926 ----
}
}
}
}
},
! new ClhsdbCommand("vmstructsdump", "vmstructsdump", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 0) {
usage();
return;
}
*** 1012,1023 ****
dumpFields((Type)i.next(), false);
}
}
},
! new Command("inspect", "inspect expression", false) {
! public void doit(Tokens t) {
if (t.countTokens() != 1) {
usage();
} else {
Address a = VM.getVM().getDebugger().parseAddress(t.nextToken());
SimpleTreeNode node = null;
--- 951,963 ----
dumpFields((Type)i.next(), false);
}
}
},
! new ClhsdbCommand("inspect", "inspect expression", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
Address a = VM.getVM().getDebugger().parseAddress(t.nextToken());
SimpleTreeNode node = null;
*** 1052,1090 ****
printNode(node);
}
}
}
},
! new Command("jhisto", "jhisto", false) {
! public void doit(Tokens t) {
ObjectHistogram histo = new ObjectHistogram();
histo.run(out, err);
}
},
! new Command("jstack", "jstack [-v]", false) {
! public void doit(Tokens t) {
boolean verbose = false;
if (t.countTokens() > 0 && t.nextToken().equals("-v")) {
verbose = true;
}
StackTrace jstack = new StackTrace(verbose, true);
jstack.run(out);
}
},
! new Command("print", "print expression", false) {
! public void doit(Tokens t) {
if (t.countTokens() != 1) {
usage();
} else {
Address a = VM.getVM().getDebugger().parseAddress(t.nextToken());
HTMLGenerator gen = new HTMLGenerator(false);
out.println(gen.genHTML(a));
}
}
},
! new Command("printas", "printas type expression", false) {
! public void doit(Tokens t) {
if (t.countTokens() != 2) {
usage();
} else {
Type type = agent.getTypeDataBase().lookupType(t.nextToken());
Address a = VM.getVM().getDebugger().parseAddress(t.nextToken());
--- 992,1034 ----
printNode(node);
}
}
}
},
! new ClhsdbCommand("jhisto", "jhisto", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
ObjectHistogram histo = new ObjectHistogram();
histo.run(out, err);
}
},
! new ClhsdbCommand("jstack", "jstack [-v]", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
boolean verbose = false;
if (t.countTokens() > 0 && t.nextToken().equals("-v")) {
verbose = true;
}
StackTrace jstack = new StackTrace(verbose, true);
jstack.run(out);
}
},
! new ClhsdbCommand("print", "print expression", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
Address a = VM.getVM().getDebugger().parseAddress(t.nextToken());
HTMLGenerator gen = new HTMLGenerator(false);
out.println(gen.genHTML(a));
}
}
},
! new ClhsdbCommand("printas", "printas type expression", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 2) {
usage();
} else {
Type type = agent.getTypeDataBase().lookupType(t.nextToken());
Address a = VM.getVM().getDebugger().parseAddress(t.nextToken());
*** 1094,1105 ****
" (size = " + type.getSize() + ")");
printNode(node);
}
}
},
! new Command("printstatics", "printstatics [ type ]", false) {
! public void doit(Tokens t) {
if (t.countTokens() > 1) {
usage();
} else {
if (t.countTokens() == 0) {
out.println("All known static fields");
--- 1038,1050 ----
" (size = " + type.getSize() + ")");
printNode(node);
}
}
},
! new ClhsdbCommand("printstatics", "printstatics [ type ]", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() > 1) {
usage();
} else {
if (t.countTokens() == 0) {
out.println("All known static fields");
*** 1110,1158 ****
printNode(new CTypeTreeNodeAdapter(type));
}
}
}
},
! new Command("pmap", "pmap", false) {
! public void doit(Tokens t) {
PMap pmap = new PMap();
pmap.run(out, debugger.getAgent().getDebugger());
}
},
! new Command("pstack", "pstack [-v]", false) {
! public void doit(Tokens t) {
boolean verbose = false;
if (t.countTokens() > 0 && t.nextToken().equals("-v")) {
verbose = true;
}
PStack pstack = new PStack(verbose, true);
pstack.run(out, debugger.getAgent().getDebugger());
}
},
! new Command("quit", true) {
! public void doit(Tokens t) {
if (t.countTokens() != 0) {
usage();
} else {
debugger.detach();
quit = true;
}
}
},
! new Command("echo", "echo [ true | false ]", true) {
! public void doit(Tokens t) {
if (t.countTokens() == 0) {
out.println("echo is " + doEcho);
} else if (t.countTokens() == 1) {
doEcho = Boolean.valueOf(t.nextToken()).booleanValue();
} else {
usage();
}
}
},
! new Command("versioncheck", "versioncheck [ true | false ]", true) {
! public void doit(Tokens t) {
if (t.countTokens() == 0) {
out.println("versioncheck is " +
(System.getProperty("sun.jvm.hotspot.runtime.VM.disableVersionCheck") == null));
} else if (t.countTokens() == 1) {
if (Boolean.valueOf(t.nextToken()).booleanValue()) {
--- 1055,1108 ----
printNode(new CTypeTreeNodeAdapter(type));
}
}
}
},
! new ClhsdbCommand("pmap", "pmap", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
PMap pmap = new PMap();
pmap.run(out, debugger.getAgent().getDebugger());
}
},
! new ClhsdbCommand("pstack", "pstack [-v]", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
boolean verbose = false;
if (t.countTokens() > 0 && t.nextToken().equals("-v")) {
verbose = true;
}
PStack pstack = new PStack(verbose, true);
pstack.run(out, debugger.getAgent().getDebugger());
}
},
! new ClhsdbCommand("quit", true) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 0) {
usage();
} else {
debugger.detach();
quit = true;
}
}
},
! new ClhsdbCommand("echo", "echo [ true | false ]", true) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() == 0) {
out.println("echo is " + doEcho);
} else if (t.countTokens() == 1) {
doEcho = Boolean.valueOf(t.nextToken()).booleanValue();
} else {
usage();
}
}
},
! new ClhsdbCommand("versioncheck", "versioncheck [ true | false ]", true) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() == 0) {
out.println("versioncheck is " +
(System.getProperty("sun.jvm.hotspot.runtime.VM.disableVersionCheck") == null));
} else if (t.countTokens() == 1) {
if (Boolean.valueOf(t.nextToken()).booleanValue()) {
*** 1163,1174 ****
} else {
usage();
}
}
},
! new Command("scanoops", "scanoops start end [ type ]", false) {
! public void doit(Tokens t) {
if (t.countTokens() != 2 && t.countTokens() != 3) {
usage();
} else {
long stride = VM.getVM().getAddressSize();
Address base = VM.getVM().getDebugger().parseAddress(t.nextToken());
--- 1113,1125 ----
} else {
usage();
}
}
},
! new ClhsdbCommand("scanoops", "scanoops start end [ type ]", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 2 && t.countTokens() != 3) {
usage();
} else {
long stride = VM.getVM().getAddressSize();
Address base = VM.getVM().getDebugger().parseAddress(t.nextToken());
*** 1199,1210 ****
base = base.addOffsetTo(step);
}
}
}
},
! new Command("intConstant", "intConstant [ name [ value ] ]", true) {
! public void doit(Tokens t) {
if (t.countTokens() != 1 && t.countTokens() != 0 && t.countTokens() != 2) {
usage();
return;
}
HotSpotTypeDataBase db = (HotSpotTypeDataBase)agent.getTypeDataBase();
--- 1150,1162 ----
base = base.addOffsetTo(step);
}
}
}
},
! new ClhsdbCommand("intConstant", "intConstant [ name [ value ] ]", true) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1 && t.countTokens() != 0 && t.countTokens() != 2) {
usage();
return;
}
HotSpotTypeDataBase db = (HotSpotTypeDataBase)agent.getTypeDataBase();
*** 1222,1233 ****
Integer value = Integer.valueOf(t.nextToken());
db.addIntConstant(name, value);
}
}
},
! new Command("longConstant", "longConstant [ name [ value ] ]", true) {
! public void doit(Tokens t) {
if (t.countTokens() != 1 && t.countTokens() != 0 && t.countTokens() != 2) {
usage();
return;
}
HotSpotTypeDataBase db = (HotSpotTypeDataBase)agent.getTypeDataBase();
--- 1174,1186 ----
Integer value = Integer.valueOf(t.nextToken());
db.addIntConstant(name, value);
}
}
},
! new ClhsdbCommand("longConstant", "longConstant [ name [ value ] ]", true) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1 && t.countTokens() != 0 && t.countTokens() != 2) {
usage();
return;
}
HotSpotTypeDataBase db = (HotSpotTypeDataBase)agent.getTypeDataBase();
*** 1245,1256 ****
Long value = Long.valueOf(t.nextToken());
db.addLongConstant(name, value);
}
}
},
! new Command("field", "field [ type [ name fieldtype isStatic offset address ] ]", true) {
! public void doit(Tokens t) {
if (t.countTokens() != 1 && t.countTokens() != 0 && t.countTokens() != 6) {
usage();
return;
}
if (t.countTokens() == 1) {
--- 1198,1210 ----
Long value = Long.valueOf(t.nextToken());
db.addLongConstant(name, value);
}
}
},
! new ClhsdbCommand("field", "field [ type [ name fieldtype isStatic offset address ] ]", true) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1 && t.countTokens() != 0 && t.countTokens() != 6) {
usage();
return;
}
if (t.countTokens() == 1) {
*** 1280,1302 ****
Iterator i = containingType.getFields();
while (i.hasNext()) {
Field f = (Field) i.next();
if (f.getName().equals(fieldName)) {
if (f.isStatic() != isStatic) {
! throw new RuntimeException("static/nonstatic mismatch: " + t.input);
}
if (!isStatic) {
if (f.getOffset() != offset) {
! throw new RuntimeException("bad redefinition of field offset: " + t.input);
}
} else {
if (!f.getStaticFieldAddress().equals(staticAddress)) {
! throw new RuntimeException("bad redefinition of field location: " + t.input);
}
}
if (f.getType() != fieldType) {
! throw new RuntimeException("bad redefinition of field type: " + t.input);
}
return;
}
}
--- 1234,1256 ----
Iterator i = containingType.getFields();
while (i.hasNext()) {
Field f = (Field) i.next();
if (f.getName().equals(fieldName)) {
if (f.isStatic() != isStatic) {
! throw new RuntimeException("static/nonstatic mismatch: " + t.getInput());
}
if (!isStatic) {
if (f.getOffset() != offset) {
! throw new RuntimeException("bad redefinition of field offset: " + t.getInput());
}
} else {
if (!f.getStaticFieldAddress().equals(staticAddress)) {
! throw new RuntimeException("bad redefinition of field location: " + t.getInput());
}
}
if (f.getType() != fieldType) {
! throw new RuntimeException("bad redefinition of field type: " + t.getInput());
}
return;
}
}
*** 1310,1328 ****
}
}
},
! new Command("tokenize", "tokenize ...", true) {
! public void doit(Tokens t) {
while (t.hasMoreTokens()) {
out.println("\"" + t.nextToken() + "\"");
}
}
},
! new Command("type", "type [ type [ name super isOop isInteger isUnsigned size ] ]", true) {
! public void doit(Tokens t) {
if (t.countTokens() != 1 && t.countTokens() != 0 && t.countTokens() != 6) {
usage();
return;
}
if (t.countTokens() == 6) {
--- 1264,1284 ----
}
}
},
! new ClhsdbCommand("tokenize", "tokenize ...", true) {
! @Override
! public void doit(Tokens t, PrintStream out) {
while (t.hasMoreTokens()) {
out.println("\"" + t.nextToken() + "\"");
}
}
},
! new ClhsdbCommand("type", "type [ type [ name super isOop isInteger isUnsigned size ] ]", true) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1 && t.countTokens() != 0 && t.countTokens() != 6) {
usage();
return;
}
if (t.countTokens() == 6) {
*** 1341,1379 ****
type = (BasicType)agent.getTypeDataBase().lookupType(typeName);
} catch (RuntimeException e) {
}
if (type != null) {
if (type.isOopType() != isOop) {
! throw new RuntimeException("oop mismatch in type definition: " + t.input);
}
if (type.isCIntegerType() != isInteger) {
! throw new RuntimeException("integer type mismatch in type definition: " + t.input);
}
if (type.isCIntegerType() && (((CIntegerType)type).isUnsigned()) != isUnsigned) {
! throw new RuntimeException("unsigned mismatch in type definition: " + t.input);
}
if (type.getSuperclass() == null) {
if (superclassName != null) {
if (type.getSize() == -1) {
type.setSuperclass(agent.getTypeDataBase().lookupType(superclassName));
} else {
! throw new RuntimeException("unexpected superclass in type definition: " + t.input);
}
}
} else {
if (superclassName == null) {
! throw new RuntimeException("missing superclass in type definition: " + t.input);
}
if (!type.getSuperclass().getName().equals(superclassName)) {
! throw new RuntimeException("incorrect superclass in type definition: " + t.input);
}
}
if (type.getSize() != size) {
if (type.getSize() == -1) {
type.setSize(size);
}
! throw new RuntimeException("size mismatch in type definition: " + t.input);
}
return;
}
// Create type
--- 1297,1335 ----
type = (BasicType)agent.getTypeDataBase().lookupType(typeName);
} catch (RuntimeException e) {
}
if (type != null) {
if (type.isOopType() != isOop) {
! throw new RuntimeException("oop mismatch in type definition: " + t.getInput());
}
if (type.isCIntegerType() != isInteger) {
! throw new RuntimeException("integer type mismatch in type definition: " + t.getInput());
}
if (type.isCIntegerType() && (((CIntegerType)type).isUnsigned()) != isUnsigned) {
! throw new RuntimeException("unsigned mismatch in type definition: " + t.getInput());
}
if (type.getSuperclass() == null) {
if (superclassName != null) {
if (type.getSize() == -1) {
type.setSuperclass(agent.getTypeDataBase().lookupType(superclassName));
} else {
! throw new RuntimeException("unexpected superclass in type definition: " + t.getInput());
}
}
} else {
if (superclassName == null) {
! throw new RuntimeException("missing superclass in type definition: " + t.getInput());
}
if (!type.getSuperclass().getName().equals(superclassName)) {
! throw new RuntimeException("incorrect superclass in type definition: " + t.getInput());
}
}
if (type.getSize() != size) {
if (type.getSize() == -1) {
type.setSize(size);
}
! throw new RuntimeException("size mismatch in type definition: " + t.getInput());
}
return;
}
// Create type
*** 1405,1416 ****
}
}
}
},
! new Command("source", "source filename", true) {
! public void doit(Tokens t) {
if (t.countTokens() != 1) {
usage();
return;
}
String file = t.nextToken();
--- 1361,1373 ----
}
}
}
},
! new ClhsdbCommand("source", "source filename", true) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
return;
}
String file = t.nextToken();
*** 1428,1439 ****
in = savedInput;
}
}
},
! new Command("search", "search [ heap | perm | rawheap | codecache | threads ] value", false) {
! public void doit(Tokens t) {
if (t.countTokens() != 2) {
usage();
return;
}
String type = t.nextToken();
--- 1385,1397 ----
in = savedInput;
}
}
},
! new ClhsdbCommand("search", "search [ heap | perm | rawheap | codecache | threads ] value", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 2) {
usage();
return;
}
String type = t.nextToken();
*** 1534,1545 ****
VM.getVM().getCodeCache().iterate(v);
}
}
},
! new Command("dumpcodecache", "dumpcodecache", false) {
! public void doit(Tokens t) {
if (t.countTokens() != 0) {
usage();
} else {
final PrintStream fout = out;
final HTMLGenerator gen = new HTMLGenerator(false);
--- 1492,1504 ----
VM.getVM().getCodeCache().iterate(v);
}
}
},
! new ClhsdbCommand("dumpcodecache", "dumpcodecache", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 0) {
usage();
} else {
final PrintStream fout = out;
final HTMLGenerator gen = new HTMLGenerator(false);
*** 1556,1567 ****
};
VM.getVM().getCodeCache().iterate(v);
}
}
},
! new Command("where", "where { -a | id }", false) {
! public void doit(Tokens t) {
if (t.countTokens() != 1) {
usage();
} else {
String name = t.nextToken();
Threads threads = VM.getVM().getThreads();
--- 1515,1527 ----
};
VM.getVM().getCodeCache().iterate(v);
}
}
},
! new ClhsdbCommand("where", "where { -a | id }", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
String name = t.nextToken();
Threads threads = VM.getVM().getThreads();
*** 1586,1597 ****
}
if (!all) out.println("Couldn't find thread " + name);
}
}
},
! new Command("thread", "thread { -a | id }", false) {
! public void doit(Tokens t) {
if (t.countTokens() != 1) {
usage();
} else {
String name = t.nextToken();
Threads threads = VM.getVM().getThreads();
--- 1546,1558 ----
}
if (!all) out.println("Couldn't find thread " + name);
}
}
},
! new ClhsdbCommand("thread", "thread { -a | id }", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
String name = t.nextToken();
Threads threads = VM.getVM().getThreads();
*** 1612,1623 ****
}
}
}
},
! new Command("threads", false) {
! public void doit(Tokens t) {
if (t.countTokens() != 0) {
usage();
} else {
Threads threads = VM.getVM().getThreads();
for (int i = 0; i < threads.getNumberOfThreads(); i++) {
--- 1573,1584 ----
}
}
}
},
! new ClhsdbCommand("threads", false) {
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 0) {
usage();
} else {
Threads threads = VM.getVM().getThreads();
for (int i = 0; i < threads.getNumberOfThreads(); i++) {
*** 1629,1640 ****
}
}
}
},
! new Command("livenmethods", false) {
! public void doit(Tokens t) {
if (t.countTokens() != 0) {
usage();
} else {
ArrayList nmethods = new ArrayList();
Threads threads = VM.getVM().getThreads();
--- 1590,1602 ----
}
}
}
},
! new ClhsdbCommand("livenmethods", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 0) {
usage();
} else {
ArrayList nmethods = new ArrayList();
Threads threads = VM.getVM().getThreads();
*** 1656,1667 ****
}
}
}
}
},
! new Command("g1regiondetails", false) {
! public void doit(Tokens t) {
if (t.countTokens() != 0) {
usage();
} else {
CollectedHeap heap = VM.getVM().getUniverse().heap();
if (!(heap instanceof G1CollectedHeap)) {
--- 1618,1630 ----
}
}
}
}
},
! new ClhsdbCommand("g1regiondetails", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 0) {
usage();
} else {
CollectedHeap heap = VM.getVM().getUniverse().heap();
if (!(heap instanceof G1CollectedHeap)) {
*** 1671,1709 ****
out.println("Region Details:");
((G1CollectedHeap)heap).printRegionDetails(out);
}
}
},
! new Command("universe", false) {
! public void doit(Tokens t) {
if (t.countTokens() != 0) {
usage();
} else {
Universe u = VM.getVM().getUniverse();
out.println("Heap Parameters:");
u.heap().printOn(out);
}
}
},
! new Command("verbose", "verbose true | false", true) {
! public void doit(Tokens t) {
if (t.countTokens() != 1) {
usage();
} else {
verboseExceptions = Boolean.valueOf(t.nextToken()).booleanValue();
}
}
},
! new Command("assert", "assert true | false", true) {
! public void doit(Tokens t) {
if (t.countTokens() != 1) {
usage();
} else {
Assert.ASSERTS_ENABLED = Boolean.valueOf(t.nextToken()).booleanValue();
}
}
},
};
private boolean verboseExceptions = false;
private ArrayList history = new ArrayList();
private HashMap commands = new HashMap();
--- 1634,1685 ----
out.println("Region Details:");
((G1CollectedHeap)heap).printRegionDetails(out);
}
}
},
! new ClhsdbCommand("universe", false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 0) {
usage();
} else {
Universe u = VM.getVM().getUniverse();
out.println("Heap Parameters:");
u.heap().printOn(out);
}
}
},
! new ClhsdbCommand("verbose", "verbose true | false", true) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
verboseExceptions = Boolean.valueOf(t.nextToken()).booleanValue();
}
}
},
! new ClhsdbCommand("assert", "assert true | false", true) {
! @Override
! public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
Assert.ASSERTS_ENABLED = Boolean.valueOf(t.nextToken()).booleanValue();
}
}
},
+ new ClhsdbCommand("load_plugin", "load_plugin [path]", true) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
+ if (t.countTokens() != 1) {
+ usage();
+ } else {
+ registerCommand(Path.of(t.nextToken()));
+ }
+ }
+ },
};
private boolean verboseExceptions = false;
private ArrayList history = new ArrayList();
private HashMap commands = new HashMap();
*** 1778,1799 ****
}
*/
}
public void registerCommand(String cmd, String usage, final String func) {
! commands.put(cmd, new Command(cmd, usage, false) {
! public void doit(Tokens t) {
final int len = t.countTokens();
Object[] args = new Object[len];
for (int i = 0; i < len; i++) {
args[i] = t.nextToken();
}
jsengine.call(func, args);
}
});
}
public void setOutput(PrintStream o) {
out = o;
}
public void setErr(PrintStream e) {
--- 1754,1807 ----
}
*/
}
public void registerCommand(String cmd, String usage, final String func) {
! commands.put(cmd, new ClhsdbCommand(cmd, usage, false) {
! @Override
! public void doit(Tokens t, PrintStream out) {
final int len = t.countTokens();
Object[] args = new Object[len];
for (int i = 0; i < len; i++) {
args[i] = t.nextToken();
}
jsengine.call(func, args);
}
});
}
+ public void registerCommand(Path path) {
+ Module saModule = this.getClass().getModule();
+ ModuleLayer saLayer = saModule.getLayer();
+
+ // Create new module for the path
+ ModuleFinder finder = ModuleFinder.of(path);
+ Set<String> moduleNames = finder.findAll()
+ .stream()
+ .map(r -> r.descriptor().name())
+ .peek(m -> System.out.println("Module found: " + m))
+ .collect(Collectors.toSet());
+
+ Configuration conf = saLayer.configuration()
+ .resolveAndBind(finder, ModuleFinder.of(), moduleNames);
+ ModuleLayer layer = saLayer.defineModulesWithOneLoader(conf, saModule.getClassLoader());
+
+ // Export all SA packages to the new module
+ layer.modules()
+ .stream()
+ .forEach(m -> saModule.getPackages()
+ .stream()
+ .forEach(p -> saModule.addExports(p, m)));
+
+ // Register command in the new module
+ ServiceLoader.load(layer, Command.class)
+ .stream()
+ .map(ServiceLoader.Provider::get)
+ .peek(s -> System.out.println("Installing: " + s.name()))
+ .forEach(s -> commands.put(s.name(), s));
+ }
+
public void setOutput(PrintStream o) {
out = o;
}
public void setErr(PrintStream e) {
*** 1806,1819 ****
this.in = in;
this.out = out;
this.err = err;
for (int i = 0; i < commandList.length; i++) {
Command c = commandList[i];
! if (commands.get(c.name) != null) {
! throw new InternalError(c.name + " has multiple definitions");
}
! commands.put(c.name, c);
}
if (debugger.isAttached()) {
postAttach();
}
}
--- 1814,1827 ----
this.in = in;
this.out = out;
this.err = err;
for (int i = 0; i < commandList.length; i++) {
Command c = commandList[i];
! if (commands.get(c.name()) != null) {
! throw new InternalError(c.name() + " has multiple definitions");
}
! commands.put(c.name(), c);
}
if (debugger.isAttached()) {
postAttach();
}
}
*** 1977,1991 ****
/*
* Check for an unknown command
*/
if (doit == null) {
out.println("Unrecognized command. Try help...");
! } else if (!debugger.isAttached() && !doit.okIfDisconnected) {
out.println("Command not valid until attached to a VM");
} else {
try {
! doit.doit(args);
} catch (Exception e) {
out.println("Error: " + e);
if (verboseExceptions) {
e.printStackTrace(out);
}
--- 1985,1999 ----
/*
* Check for an unknown command
*/
if (doit == null) {
out.println("Unrecognized command. Try help...");
! } else if (!debugger.isAttached() && !doit.okIfDisconnected()) {
out.println("Command not valid until attached to a VM");
} else {
try {
! doit.doit(args, out);
} catch (Exception e) {
out.println("Error: " + e);
if (verboseExceptions) {
e.printStackTrace(out);
}
< prev index next >