comparison agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java @ 1385:bc32f286fae0

6945219: minor SA fixes Reviewed-by: twisti
author never
date Tue, 20 Apr 2010 13:26:33 -0700
parents 873ec3787992
children c18cbe5936b8
comparison
equal deleted inserted replaced
1384:c544d979f886 1385:bc32f286fae0
1 /* 1 /*
2 * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. 2 * Copyright 2005-2010 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
492 if (printIndex) out.print(i + " "); 492 if (printIndex) out.print(i + " ");
493 out.println(history.get(i)); 493 out.println(history.get(i));
494 } 494 }
495 } 495 }
496 }, 496 },
497 new Command("revptrs", "revptrs address", false) {
498 public void doit(Tokens t) {
499 int tokens = t.countTokens();
500 if (tokens != 1 && (tokens != 2 || !t.nextToken().equals("-c"))) {
501 usage();
502 return;
503 }
504 boolean chase = tokens == 2;
505 ReversePtrs revptrs = VM.getVM().getRevPtrs();
506 if (revptrs == null) {
507 out.println("Computing reverse pointers...");
508 ReversePtrsAnalysis analysis = new ReversePtrsAnalysis();
509 final boolean[] complete = new boolean[1];
510 HeapProgressThunk thunk = new HeapProgressThunk() {
511 public void heapIterationFractionUpdate(double d) {}
512 public synchronized void heapIterationComplete() {
513 complete[0] = true;
514 notify();
515 }
516 };
517 analysis.setHeapProgressThunk(thunk);
518 analysis.run();
519 while (!complete[0]) {
520 synchronized (thunk) {
521 try {
522 thunk.wait();
523 } catch (Exception e) {
524 }
525 }
526 }
527 revptrs = VM.getVM().getRevPtrs();
528 out.println("Done.");
529 }
530 Address a = VM.getVM().getDebugger().parseAddress(t.nextToken());
531 if (VM.getVM().getUniverse().heap().isInReserved(a)) {
532 OopHandle handle = a.addOffsetToAsOopHandle(0);
533 Oop oop = VM.getVM().getObjectHeap().newOop(handle);
534 ArrayList ptrs = revptrs.get(oop);
535 if (ptrs == null) {
536 out.println("no live references to " + a);
537 } else {
538 if (chase) {
539 while (ptrs.size() == 1) {
540 LivenessPathElement e = (LivenessPathElement)ptrs.get(0);
541 ByteArrayOutputStream bos = new ByteArrayOutputStream();
542 Oop.printOopValueOn(e.getObj(), new PrintStream(bos));
543 out.println(bos.toString());
544 ptrs = revptrs.get(e.getObj());
545 }
546 } else {
547 for (int i = 0; i < ptrs.size(); i++) {
548 LivenessPathElement e = (LivenessPathElement)ptrs.get(i);
549 ByteArrayOutputStream bos = new ByteArrayOutputStream();
550 Oop.printOopValueOn(e.getObj(), new PrintStream(bos));
551 out.println(bos.toString());
552 oop = e.getObj();
553 }
554 }
555 }
556 }
557 }
558 },
497 new Command("inspect", "inspect expression", false) { 559 new Command("inspect", "inspect expression", false) {
498 public void doit(Tokens t) { 560 public void doit(Tokens t) {
499 if (t.countTokens() != 1) { 561 if (t.countTokens() != 1) {
500 usage(); 562 usage();
501 } else { 563 } else {
814 } else if (t.countTokens() == 1) { 876 } else if (t.countTokens() == 1) {
815 Type type = agent.getTypeDataBase().lookupType(t.nextToken()); 877 Type type = agent.getTypeDataBase().lookupType(t.nextToken());
816 dumpType(type); 878 dumpType(type);
817 } else { 879 } else {
818 Iterator i = agent.getTypeDataBase().getTypes(); 880 Iterator i = agent.getTypeDataBase().getTypes();
881 // Make sure the types are emitted in an order than can be read back in
882 HashSet emitted = new HashSet();
883 Stack pending = new Stack();
819 while (i.hasNext()) { 884 while (i.hasNext()) {
820 dumpType((Type)i.next()); 885 Type n = (Type)i.next();
886 if (emitted.contains(n.getName())) {
887 continue;
888 }
889
890 while (n != null && !emitted.contains(n.getName())) {
891 pending.push(n);
892 n = n.getSuperclass();
893 }
894 while (!pending.empty()) {
895 n = (Type)pending.pop();
896 dumpType(n);
897 emitted.add(n.getName());
898 }
821 } 899 }
822 } 900 }
823 } 901 }
824 902
825 }, 903 },
844 in = savedInput; 922 in = savedInput;
845 } 923 }
846 924
847 } 925 }
848 }, 926 },
849 new Command("search", "search [ heap | codecache | threads ] value", false) { 927 new Command("search", "search [ heap | perm | rawheap | codecache | threads ] value", false) {
850 public void doit(Tokens t) { 928 public void doit(Tokens t) {
851 if (t.countTokens() != 2) { 929 if (t.countTokens() != 2) {
852 usage(); 930 usage();
853 } else { 931 return;
854 String type = t.nextToken(); 932 }
855 final Address value = VM.getVM().getDebugger().parseAddress(t.nextToken()); 933 String type = t.nextToken();
856 final long stride = VM.getVM().getAddressSize(); 934 final Address value = VM.getVM().getDebugger().parseAddress(t.nextToken());
857 if (type.equals("threads")) { 935 final long stride = VM.getVM().getAddressSize();
858 Threads threads = VM.getVM().getThreads(); 936 if (type.equals("threads")) {
859 for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) { 937 Threads threads = VM.getVM().getThreads();
860 Address base = thread.getBaseOfStackPointer(); 938 for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
861 Address end = thread.getLastJavaSP(); 939 Address base = thread.getBaseOfStackPointer();
862 if (end == null) continue; 940 Address end = thread.getLastJavaSP();
863 if (end.lessThan(base)) { 941 if (end == null) continue;
864 Address tmp = base; 942 if (end.lessThan(base)) {
865 base = end; 943 Address tmp = base;
866 end = tmp; 944 base = end;
867 } 945 end = tmp;
868 out.println("Searching " + base + " " + end); 946 }
869 while (base != null && base.lessThan(end)) { 947 out.println("Searching " + base + " " + end);
870 Address val = base.getAddressAt(0); 948 while (base != null && base.lessThan(end)) {
949 Address val = base.getAddressAt(0);
950 if (AddressOps.equal(val, value)) {
951 out.println(base);
952 }
953 base = base.addOffsetTo(stride);
954 }
955 }
956 } else if (type.equals("rawheap")) {
957 RawHeapVisitor iterator = new RawHeapVisitor() {
958 public void prologue(long used) {
959 }
960
961 public void visitAddress(Address addr) {
962 Address val = addr.getAddressAt(0);
871 if (AddressOps.equal(val, value)) { 963 if (AddressOps.equal(val, value)) {
872 out.println(base); 964 out.println("found at " + addr);
873 } 965 }
874 base = base.addOffsetTo(stride); 966 }
875 } 967 public void visitCompOopAddress(Address addr) {
876 } 968 Address val = addr.getCompOopAddressAt(0);
877 } else if (type.equals("heap")) { 969 if (AddressOps.equal(val, value)) {
878 RawHeapVisitor iterator = new RawHeapVisitor() { 970 out.println("found at " + addr);
879 public void prologue(long used) {
880 } 971 }
881 972 }
882 public void visitAddress(Address addr) { 973 public void epilogue() {
883 Address val = addr.getAddressAt(0); 974 }
975 };
976 VM.getVM().getObjectHeap().iterateRaw(iterator);
977 } else if (type.equals("heap") || type.equals("perm")) {
978 HeapVisitor iterator = new DefaultHeapVisitor() {
979 public boolean doObj(Oop obj) {
980 int index = 0;
981 Address start = obj.getHandle();
982 long end = obj.getObjectSize();
983 while (index < end) {
984 Address val = start.getAddressAt(index);
884 if (AddressOps.equal(val, value)) { 985 if (AddressOps.equal(val, value)) {
885 out.println("found at " + addr); 986 out.println("found in " + obj.getHandle());
987 break;
886 } 988 }
989 index += 4;
887 } 990 }
888 public void visitCompOopAddress(Address addr) { 991 return false;
889 Address val = addr.getCompOopAddressAt(0); 992 }
993 };
994 if (type.equals("heap")) {
995 VM.getVM().getObjectHeap().iterate(iterator);
996 } else {
997 VM.getVM().getObjectHeap().iteratePerm(iterator);
998 }
999 } else if (type.equals("codecache")) {
1000 CodeCacheVisitor v = new CodeCacheVisitor() {
1001 public void prologue(Address start, Address end) {
1002 }
1003 public void visit(CodeBlob blob) {
1004 boolean printed = false;
1005 Address base = blob.getAddress();
1006 Address end = base.addOffsetTo(blob.getSize());
1007 while (base != null && base.lessThan(end)) {
1008 Address val = base.getAddressAt(0);
890 if (AddressOps.equal(val, value)) { 1009 if (AddressOps.equal(val, value)) {
891 out.println("found at " + addr); 1010 if (!printed) {
1011 printed = true;
1012 blob.printOn(out);
1013 }
1014 out.println("found at " + base + "\n");
892 } 1015 }
1016 base = base.addOffsetTo(stride);
893 } 1017 }
894 public void epilogue() { 1018 }
895 } 1019 public void epilogue() {
896 }; 1020 }
897 VM.getVM().getObjectHeap().iterateRaw(iterator); 1021
898 } else if (type.equals("codecache")) { 1022
899 CodeCacheVisitor v = new CodeCacheVisitor() { 1023 };
900 public void prologue(Address start, Address end) { 1024 VM.getVM().getCodeCache().iterate(v);
901 } 1025
902 public void visit(CodeBlob blob) {
903 boolean printed = false;
904 Address base = blob.getAddress();
905 Address end = base.addOffsetTo(blob.getSize());
906 while (base != null && base.lessThan(end)) {
907 Address val = base.getAddressAt(0);
908 if (AddressOps.equal(val, value)) {
909 if (!printed) {
910 printed = true;
911 blob.printOn(out);
912 }
913 out.println("found at " + base + "\n");
914 }
915 base = base.addOffsetTo(stride);
916 }
917 }
918 public void epilogue() {
919 }
920
921
922 };
923 VM.getVM().getCodeCache().iterate(v);
924
925 }
926 } 1026 }
927 } 1027 }
928 }, 1028 },
929 new Command("dumpcodecache", "dumpcodecache", false) { 1029 new Command("dumpcodecache", "dumpcodecache", false) {
930 public void doit(Tokens t) { 1030 public void doit(Tokens t) {
955 } else { 1055 } else {
956 String name = t.nextToken(); 1056 String name = t.nextToken();
957 Threads threads = VM.getVM().getThreads(); 1057 Threads threads = VM.getVM().getThreads();
958 boolean all = name.equals("-a"); 1058 boolean all = name.equals("-a");
959 for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) { 1059 for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
960 StringWriter sw = new StringWriter();
961 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 1060 ByteArrayOutputStream bos = new ByteArrayOutputStream();
962 thread.printThreadIDOn(new PrintStream(bos)); 1061 thread.printThreadIDOn(new PrintStream(bos));
963 if (all || bos.toString().equals(name)) { 1062 if (all || bos.toString().equals(name)) {
1063 out.println(bos.toString() + " = " + thread.getAddress());
964 HTMLGenerator gen = new HTMLGenerator(false); 1064 HTMLGenerator gen = new HTMLGenerator(false);
965 out.println(gen.genHTMLForJavaStackTrace(thread)); 1065 try {
1066 out.println(gen.genHTMLForJavaStackTrace(thread));
1067 } catch (Exception e) {
1068 err.println("Error: " + e);
1069 if (verboseExceptions) {
1070 e.printStackTrace(err);
1071 }
1072 }
966 if (!all) return; 1073 if (!all) return;
967 } 1074 }
968 } 1075 }
969 if (!all) out.println("Couldn't find thread " + name); 1076 if (!all) out.println("Couldn't find thread " + name);
1077 }
1078 }
1079 },
1080 new Command("thread", "thread { -a | id }", false) {
1081 public void doit(Tokens t) {
1082 if (t.countTokens() != 1) {
1083 usage();
1084 } else {
1085 String name = t.nextToken();
1086 Threads threads = VM.getVM().getThreads();
1087 boolean all = name.equals("-a");
1088 for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
1089 ByteArrayOutputStream bos = new ByteArrayOutputStream();
1090 thread.printThreadIDOn(new PrintStream(bos));
1091 if (all || bos.toString().equals(name)) {
1092 out.println(bos.toString() + " = " + thread.getAddress());
1093 if (!all) return;
1094 }
1095 }
1096 out.println("Couldn't find thread " + name);
970 } 1097 }
971 } 1098 }
972 }, 1099 },
973 1100
974 new Command("threads", false) { 1101 new Command("threads", false) {
1159 1286
1160 executeCommand(ln); 1287 executeCommand(ln);
1161 } 1288 }
1162 } 1289 }
1163 1290
1164 static Pattern historyPattern = Pattern.compile("((!\\*)|(!\\$)|(!!-?)|(!-?[0-9][0-9]*))"); 1291 static Pattern historyPattern = Pattern.compile("((!\\*)|(!\\$)|(!!-?)|(!-?[0-9][0-9]*)|(![a-zA-Z][^ ]*))");
1165 1292
1166 public void executeCommand(String ln) { 1293 public void executeCommand(String ln) {
1167 if (ln.indexOf('!') != -1) { 1294 if (ln.indexOf('!') != -1) {
1168 int size = history.size(); 1295 int size = history.size();
1169 if (size == 0) { 1296 if (size == 0) {
1193 } else if (cmd.equals("!$")) { 1320 } else if (cmd.equals("!$")) {
1194 Tokens item = new Tokens((String)history.get(history.size() - 1)); 1321 Tokens item = new Tokens((String)history.get(history.size() - 1));
1195 result.append(item.at(item.countTokens() - 1)); 1322 result.append(item.at(item.countTokens() - 1));
1196 } else { 1323 } else {
1197 String tail = cmd.substring(1); 1324 String tail = cmd.substring(1);
1198 int index = Integer.parseInt(tail); 1325 switch (tail.charAt(0)) {
1199 if (index < 0) { 1326 case '0':
1200 index = history.size() + index; 1327 case '1':
1201 } 1328 case '2':
1202 if (index > size) { 1329 case '3':
1203 err.println("No such history item"); 1330 case '4':
1204 } else { 1331 case '5':
1205 result.append((String)history.get(index)); 1332 case '6':
1333 case '7':
1334 case '8':
1335 case '9':
1336 case '-': {
1337 int index = Integer.parseInt(tail);
1338 if (index < 0) {
1339 index = history.size() + index;
1340 }
1341 if (index > size) {
1342 err.println("No such history item");
1343 } else {
1344 result.append((String)history.get(index));
1345 }
1346 break;
1347 }
1348 default: {
1349 for (int i = history.size() - 1; i >= 0; i--) {
1350 String s = (String)history.get(i);
1351 if (s.startsWith(tail)) {
1352 result.append(s);
1353 }
1354 }
1355 }
1206 } 1356 }
1207 } 1357 }
1208 } 1358 }
1209 if (result.length() == 0) { 1359 if (result.length() == 0) {
1210 err.println("malformed history reference"); 1360 err.println("malformed history reference");