Skip to content

Commit 554f17b

Browse files
committed
8244669: convert clhsdb "mem" command from javascript to java
Reviewed-by: clanger Backport-of: eaefb1a1ed9edea440628e3a5c5483ebd52bfcb0
1 parent c8caf68 commit 554f17b

File tree

3 files changed

+129
-37
lines changed

3 files changed

+129
-37
lines changed

src/jdk.hotspot.agent/doc/clhsdb.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ <h3>Annotated output of CLHSDB help command</h3>
4242
dumpilt -a | id <font color="red">dump inline tree for C2 compilation</font>
4343
dumpreplaydata &lt;address&gt; | -a | &lt;thread_id&gt; [&gt;replay.txt] <font color="red">dump replay data into a file</font>
4444
echo [ true | false ] <font color="red">turn on/off command echo mode</font>
45-
examine [ address/count ] | [ address,address] <font color="red">show contents of memory from given address</font>
45+
examine { address[/count] | address,address } <font color="red">show contents of memory range</font>
4646
field [ type [ name fieldtype isStatic offset address ] ] <font color="red">print info about a field of HotSpot type</font>
4747
findpc address <font color="red">print info about pointer location</font>
4848
findsym name <font color="red">print address of symbol in the executable or shared library</font>
@@ -56,7 +56,7 @@ <h3>Annotated output of CLHSDB help command</h3>
5656
jstack [-v] <font color="red">show Java stack trace of all Java threads. -v is verbose mode</font>
5757
livenmethods <font color="red">show all live nmethods</font>
5858
longConstant [ name [ value ] ] <font color="red">print out hotspot long constant(s)s</font>
59-
mem address [ length ] <font color="red">show contents of memory -- also shows closest ELF/COFF symbol if found</font>
59+
mem [ -v ] { address[/count] | address,address } <font color="red">show contents of memory range. -v adds "findpc" info for addresses</font>
6060
pmap <font color="red">show Solaris pmap-like output</font>
6161
print expression <font color="red">print given Klass*, Method* or arbitrary address</font>
6262
printas type expression <font color="red">print given address as given HotSpot type. eg. print JavaThread &lt;address&gt;</font>

src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java

Lines changed: 114 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,54 @@ Address parseAddress(String addr) {
368368
return VM.getVM().getDebugger().parseAddress(addr);
369369
}
370370

371+
String fillHexString(Address a, int width) {
372+
String s = "0x0";
373+
if (a != null) {
374+
s = a.toString();
375+
}
376+
if (s.length() != width) {
377+
return s.substring(0, 2) + "000000000000000000000".substring(0, width - s.length()) + s.substring(2);
378+
}
379+
return s;
380+
}
381+
382+
class AddressRange {
383+
private Address start;
384+
private Address end;
385+
AddressRange(Address start, Address end) {
386+
this.start = start;
387+
this.end = end;
388+
}
389+
Address getStart() {return start;}
390+
Address getEnd() {return end;}
391+
}
392+
393+
// Parses either address[/count] or address,address into address start/end values
394+
AddressRange parseAddressRange(String arg, int formatSize) {
395+
Pattern args1 = Pattern.compile("^(0x[0-9a-f]+)(/([0-9]*))?$");
396+
Pattern args2 = Pattern.compile("^(0x[0-9a-f]+),(0x[0-9a-f]+)$");
397+
Matcher m1 = args1.matcher(arg);
398+
Matcher m2 = args2.matcher(arg);
399+
Address start = null;
400+
Address end = null;
401+
402+
if (m1.matches()) {
403+
start = VM.getVM().getDebugger().parseAddress(m1.group(1));
404+
int count = 1;
405+
if (m1.group(2) != null) {
406+
count = Integer.parseInt(m1.group(3));
407+
}
408+
end = start.addOffsetTo(count * formatSize);
409+
return new AddressRange(start, end);
410+
} else if (m2.matches()) {
411+
start = VM.getVM().getDebugger().parseAddress(m2.group(1));
412+
end = VM.getVM().getDebugger().parseAddress(m2.group(2));
413+
return new AddressRange(start, end);
414+
} else {
415+
return null;
416+
}
417+
}
418+
371419
private final Command[] commandList = {
372420
new Command("reattach", true) {
373421
public void doit(Tokens t) {
@@ -413,66 +461,40 @@ public void doit(Tokens t) {
413461
}
414462
}
415463
},
416-
new Command("examine", "examine [ address/count ] | [ address,address]", false) {
417-
Pattern args1 = Pattern.compile("^(0x[0-9a-f]+)(/([0-9]*)([a-z]*))?$");
418-
Pattern args2 = Pattern.compile("^(0x[0-9a-f]+),(0x[0-9a-f]+)(/[a-z]*)?$");
419-
420-
String fill(Address a, int width) {
421-
String s = "0x0";
422-
if (a != null) {
423-
s = a.toString();
424-
}
425-
if (s.length() != width) {
426-
return s.substring(0, 2) + "000000000000000000000".substring(0, width - s.length()) + s.substring(2);
427-
}
428-
return s;
429-
}
430-
464+
new Command("examine", "examine { address[/count] | address,address }", false) {
431465
public void doit(Tokens t) {
432466
if (t.countTokens() != 1) {
433467
usage();
434468
} else {
435469
String arg = t.nextToken();
436-
Matcher m1 = args1.matcher(arg);
437-
Matcher m2 = args2.matcher(arg);
438-
Address start = null;
439-
Address end = null;
440-
String format = "";
441470
int formatSize = (int)VM.getVM().getAddressSize();
442-
443-
if (m1.matches()) {
444-
start = VM.getVM().getDebugger().parseAddress(m1.group(1));
445-
int count = 1;
446-
if (m1.group(2) != null) {
447-
count = Integer.parseInt(m1.group(3));
448-
}
449-
end = start.addOffsetTo(count * formatSize);
450-
} else if (m2.matches()) {
451-
start = VM.getVM().getDebugger().parseAddress(m2.group(1));
452-
end = VM.getVM().getDebugger().parseAddress(m2.group(2));
453-
} else {
471+
AddressRange addressRange = parseAddressRange(arg, formatSize);
472+
if (addressRange == null) {
454473
usage();
455474
return;
456475
}
476+
Address start = addressRange.getStart();
477+
Address end = addressRange.getEnd();
478+
457479
int line = 80;
458480
int formatWidth = formatSize * 8 / 4 + 2;
459481

460-
out.print(fill(start, formatWidth));
482+
out.print(fillHexString(start, formatWidth));
461483
out.print(": ");
462484
int width = line - formatWidth - 2;
463485

464486
boolean needsPrintln = true;
465487
while (start != null && start.lessThan(end)) {
466488
Address val = start.getAddressAt(0);
467-
out.print(fill(val, formatWidth));
489+
out.print(fillHexString(val, formatWidth));
468490
needsPrintln = true;
469491
width -= formatWidth;
470492
start = start.addOffsetTo(formatSize);
471493
if (width <= formatWidth) {
472494
out.println();
473495
needsPrintln = false;
474496
if (start.lessThan(end)) {
475-
out.print(fill(start, formatWidth));
497+
out.print(fillHexString(start, formatWidth));
476498
out.print(": ");
477499
width = line - formatWidth - 2;
478500
}
@@ -487,6 +509,63 @@ public void doit(Tokens t) {
487509
}
488510
}
489511
},
512+
new Command("mem", "mem [-v] { address[/count] | address,address }", false) {
513+
public void doit(Tokens t) {
514+
int formatSize = (int)VM.getVM().getAddressSize();
515+
boolean verbose = false;
516+
String arg;
517+
518+
if (t.countTokens() == 2) {
519+
arg = t.nextToken();
520+
if (arg.equals("-v")) {
521+
verbose = true;
522+
} else {
523+
usage();
524+
return;
525+
}
526+
}
527+
if (t.countTokens() != 1) {
528+
usage();
529+
return;
530+
}
531+
532+
arg = t.nextToken();
533+
AddressRange addressRange = parseAddressRange(arg, formatSize);
534+
if (addressRange == null) {
535+
usage();
536+
return;
537+
}
538+
Address start = addressRange.getStart();
539+
Address end = addressRange.getEnd();
540+
541+
if (verbose) {
542+
// Do the equivalent of a findpc on the start address.
543+
PointerLocation loc = PointerFinder.find(start);
544+
loc.printOn(out);
545+
}
546+
547+
int formatWidth = formatSize * 8 / 4 + 2;
548+
while (start != null && start.lessThan(end)) {
549+
out.print(fillHexString(start, formatWidth));
550+
out.print(": ");
551+
Address val = start.getAddressAt(0);
552+
out.print(fillHexString(val, formatWidth));
553+
if (verbose) {
554+
// If we know what this is a pointer to, then print additional information.
555+
PointerLocation loc = PointerFinder.find(val);
556+
if (!loc.isUnknown()) {
557+
out.print(" ");
558+
loc.printOn(out, false, false);
559+
} else {
560+
out.println();
561+
}
562+
} else {
563+
out.println();
564+
}
565+
start = start.addOffsetTo(formatSize);
566+
}
567+
}
568+
},
490569
new Command("dumpreplaydata", "dumpreplaydata { <address > | -a | <thread_id> }", false) {
491570
// This is used to dump replay data from ciInstanceKlass, ciMethodData etc
492571
// default file name is replay.txt, also if java crashes in compiler

test/hotspot/jtreg/serviceability/sa/ClhsdbFindPC.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,19 @@ private static void testFindPC(boolean withXcomp, boolean withCore) throws Excep
191191
methodAddr));
192192
runTest(withCore, cmds, expStrMap);
193193

194+
// Run "mem -v <addr>/30" on a Method*. The first line will look like:
195+
// Address 0x0000152e30403530: Method jdk/test/lib/apps/LingeredApp.steadyState(Ljava/lang/Object;)V@0x0000152e30403530
196+
// Followed by lines displaying the memory contents, including interpretation
197+
// of any contents that are addresses.
198+
cmdStr = "mem -v " + methodAddr + "/30";
199+
cmds = List.of(cmdStr);
200+
expStrMap = new HashMap<>();
201+
expStrMap.put(cmdStr, List.of("Method jdk/test/lib/apps/LingeredApp.steadyState",
202+
methodAddr,
203+
/* The following is from a field in the Method object. */
204+
"In interpreter codelet: method entry point"));
205+
runTest(withCore, cmds, expStrMap);
206+
194207
// Run findpc on a JavaThread*. We can find one in the jstack output.
195208
// The tid for a thread is it's JavaThread*. For example:
196209
// "main" #1 prio=5 tid=0x00000080263398f0 nid=0x277e0 ...

0 commit comments

Comments
 (0)