mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-20 07:15:31 +00:00
8244669: convert clhsdb "mem" command from javascript to java
Reviewed-by: sspitsyn, kevinw, poonam
This commit is contained in:
parent
d64820dfef
commit
eaefb1a1ed
@ -42,7 +42,7 @@ Available commands:
|
||||
dumpilt -a | id <font color="red">dump inline tree for C2 compilation</font>
|
||||
dumpreplaydata <address> | -a | <thread_id> [>replay.txt] <font color="red">dump replay data into a file</font>
|
||||
echo [ true | false ] <font color="red">turn on/off command echo mode</font>
|
||||
examine [ address/count ] | [ address,address] <font color="red">show contents of memory from given address</font>
|
||||
examine { address[/count] | address,address } <font color="red">show contents of memory range</font>
|
||||
field [ type [ name fieldtype isStatic offset address ] ] <font color="red">print info about a field of HotSpot type</font>
|
||||
findpc address <font color="red">print info about pointer location</font>
|
||||
findsym name <font color="red">print address of symbol in the executable or shared library</font>
|
||||
@ -56,7 +56,7 @@ Available commands:
|
||||
jstack [-v] <font color="red">show Java stack trace of all Java threads. -v is verbose mode</font>
|
||||
livenmethods <font color="red">show all live nmethods</font>
|
||||
longConstant [ name [ value ] ] <font color="red">print out hotspot long constant(s)s</font>
|
||||
mem address [ length ] <font color="red">show contents of memory -- also shows closest ELF/COFF symbol if found</font>
|
||||
mem [ -v ] { address[/count] | address,address } <font color="red">show contents of memory range. -v adds "findpc" info for addresses</font>
|
||||
pmap <font color="red">show Solaris pmap-like output</font>
|
||||
print expression <font color="red">print given Klass*, Method* or arbitrary address</font>
|
||||
printas type expression <font color="red">print given address as given HotSpot type. eg. print JavaThread <address></font>
|
||||
|
||||
@ -364,6 +364,54 @@ public class CommandProcessor {
|
||||
return VM.getVM().getDebugger().parseAddress(addr);
|
||||
}
|
||||
|
||||
String fillHexString(Address a, int width) {
|
||||
String s = "0x0";
|
||||
if (a != null) {
|
||||
s = a.toString();
|
||||
}
|
||||
if (s.length() != width) {
|
||||
return s.substring(0, 2) + "000000000000000000000".substring(0, width - s.length()) + s.substring(2);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
class AddressRange {
|
||||
private Address start;
|
||||
private Address end;
|
||||
AddressRange(Address start, Address end) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
Address getStart() {return start;}
|
||||
Address getEnd() {return end;}
|
||||
}
|
||||
|
||||
// Parses either address[/count] or address,address into address start/end values
|
||||
AddressRange parseAddressRange(String arg, int formatSize) {
|
||||
Pattern args1 = Pattern.compile("^(0x[0-9a-f]+)(/([0-9]*))?$");
|
||||
Pattern args2 = Pattern.compile("^(0x[0-9a-f]+),(0x[0-9a-f]+)$");
|
||||
Matcher m1 = args1.matcher(arg);
|
||||
Matcher m2 = args2.matcher(arg);
|
||||
Address start = null;
|
||||
Address end = null;
|
||||
|
||||
if (m1.matches()) {
|
||||
start = VM.getVM().getDebugger().parseAddress(m1.group(1));
|
||||
int count = 1;
|
||||
if (m1.group(2) != null) {
|
||||
count = Integer.parseInt(m1.group(3));
|
||||
}
|
||||
end = start.addOffsetTo(count * formatSize);
|
||||
return new AddressRange(start, end);
|
||||
} else if (m2.matches()) {
|
||||
start = VM.getVM().getDebugger().parseAddress(m2.group(1));
|
||||
end = VM.getVM().getDebugger().parseAddress(m2.group(2));
|
||||
return new AddressRange(start, end);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private final Command[] commandList = {
|
||||
new Command("reattach", true) {
|
||||
public void doit(Tokens t) {
|
||||
@ -409,57 +457,32 @@ public class CommandProcessor {
|
||||
}
|
||||
}
|
||||
},
|
||||
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";
|
||||
if (a != null) {
|
||||
s = a.toString();
|
||||
}
|
||||
if (s.length() != width) {
|
||||
return s.substring(0, 2) + "000000000000000000000".substring(0, width - s.length()) + s.substring(2);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
new Command("examine", "examine { address[/count] | address,address }", false) {
|
||||
public void doit(Tokens t) {
|
||||
if (t.countTokens() != 1) {
|
||||
usage();
|
||||
} else {
|
||||
String arg = t.nextToken();
|
||||
Matcher m1 = args1.matcher(arg);
|
||||
Matcher m2 = args2.matcher(arg);
|
||||
Address start = null;
|
||||
Address end = null;
|
||||
int formatSize = (int)VM.getVM().getAddressSize();
|
||||
|
||||
if (m1.matches()) {
|
||||
start = VM.getVM().getDebugger().parseAddress(m1.group(1));
|
||||
int count = 1;
|
||||
if (m1.group(2) != null) {
|
||||
count = Integer.parseInt(m1.group(3));
|
||||
}
|
||||
end = start.addOffsetTo(count * formatSize);
|
||||
} else if (m2.matches()) {
|
||||
start = VM.getVM().getDebugger().parseAddress(m2.group(1));
|
||||
end = VM.getVM().getDebugger().parseAddress(m2.group(2));
|
||||
} else {
|
||||
AddressRange addressRange = parseAddressRange(arg, formatSize);
|
||||
if (addressRange == null) {
|
||||
usage();
|
||||
return;
|
||||
}
|
||||
Address start = addressRange.getStart();
|
||||
Address end = addressRange.getEnd();
|
||||
|
||||
int line = 80;
|
||||
int formatWidth = formatSize * 8 / 4 + 2;
|
||||
|
||||
out.print(fill(start, formatWidth));
|
||||
out.print(fillHexString(start, formatWidth));
|
||||
out.print(": ");
|
||||
int width = line - formatWidth - 2;
|
||||
|
||||
boolean needsPrintln = true;
|
||||
while (start != null && start.lessThan(end)) {
|
||||
Address val = start.getAddressAt(0);
|
||||
out.print(fill(val, formatWidth));
|
||||
out.print(fillHexString(val, formatWidth));
|
||||
needsPrintln = true;
|
||||
width -= formatWidth;
|
||||
start = start.addOffsetTo(formatSize);
|
||||
@ -467,7 +490,7 @@ public class CommandProcessor {
|
||||
out.println();
|
||||
needsPrintln = false;
|
||||
if (start.lessThan(end)) {
|
||||
out.print(fill(start, formatWidth));
|
||||
out.print(fillHexString(start, formatWidth));
|
||||
out.print(": ");
|
||||
width = line - formatWidth - 2;
|
||||
}
|
||||
@ -482,6 +505,63 @@ public class CommandProcessor {
|
||||
}
|
||||
}
|
||||
},
|
||||
new Command("mem", "mem [-v] { address[/count] | address,address }", false) {
|
||||
public void doit(Tokens t) {
|
||||
int formatSize = (int)VM.getVM().getAddressSize();
|
||||
boolean verbose = false;
|
||||
String arg;
|
||||
|
||||
if (t.countTokens() == 2) {
|
||||
arg = t.nextToken();
|
||||
if (arg.equals("-v")) {
|
||||
verbose = true;
|
||||
} else {
|
||||
usage();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (t.countTokens() != 1) {
|
||||
usage();
|
||||
return;
|
||||
}
|
||||
|
||||
arg = t.nextToken();
|
||||
AddressRange addressRange = parseAddressRange(arg, formatSize);
|
||||
if (addressRange == null) {
|
||||
usage();
|
||||
return;
|
||||
}
|
||||
Address start = addressRange.getStart();
|
||||
Address end = addressRange.getEnd();
|
||||
|
||||
if (verbose) {
|
||||
// Do the equivalent of a findpc on the start address.
|
||||
PointerLocation loc = PointerFinder.find(start);
|
||||
loc.printOn(out);
|
||||
}
|
||||
|
||||
int formatWidth = formatSize * 8 / 4 + 2;
|
||||
while (start != null && start.lessThan(end)) {
|
||||
out.print(fillHexString(start, formatWidth));
|
||||
out.print(": ");
|
||||
Address val = start.getAddressAt(0);
|
||||
out.print(fillHexString(val, formatWidth));
|
||||
if (verbose) {
|
||||
// If we know what this is a pointer to, then print additional information.
|
||||
PointerLocation loc = PointerFinder.find(val);
|
||||
if (!loc.isUnknown()) {
|
||||
out.print(" ");
|
||||
loc.printOn(out, false, false);
|
||||
} else {
|
||||
out.println();
|
||||
}
|
||||
} else {
|
||||
out.println();
|
||||
}
|
||||
start = start.addOffsetTo(formatSize);
|
||||
}
|
||||
}
|
||||
},
|
||||
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
|
||||
|
||||
@ -191,6 +191,19 @@ public class ClhsdbFindPC {
|
||||
methodAddr));
|
||||
runTest(withCore, cmds, expStrMap);
|
||||
|
||||
// Run "mem -v <addr>/30" on a Method*. The first line will look like:
|
||||
// Address 0x0000152e30403530: Method jdk/test/lib/apps/LingeredApp.steadyState(Ljava/lang/Object;)V@0x0000152e30403530
|
||||
// Followed by lines displaying the memory contents, including interpretation
|
||||
// of any contents that are addresses.
|
||||
cmdStr = "mem -v " + methodAddr + "/30";
|
||||
cmds = List.of(cmdStr);
|
||||
expStrMap = new HashMap<>();
|
||||
expStrMap.put(cmdStr, List.of("Method jdk/test/lib/apps/LingeredApp.steadyState",
|
||||
methodAddr,
|
||||
/* The following is from a field in the Method object. */
|
||||
"In interpreter codelet: method entry point"));
|
||||
runTest(withCore, cmds, expStrMap);
|
||||
|
||||
// Run findpc on a JavaThread*. We can find one in the jstack output.
|
||||
// The tid for a thread is it's JavaThread*. For example:
|
||||
// "main" #1 prio=5 tid=0x00000080263398f0 nid=0x277e0 ...
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user