23 */
24
25 package sun.jvm.hotspot;
26
27 import java.io.*;
28 import java.math.*;
29 import java.util.*;
30 import java.util.regex.*;
31
32 import sun.jvm.hotspot.types.Type;
33 import sun.jvm.hotspot.types.Field;
34 import sun.jvm.hotspot.HotSpotTypeDataBase;
35 import sun.jvm.hotspot.types.basic.BasicType;
36 import sun.jvm.hotspot.types.CIntegerType;
37 import sun.jvm.hotspot.code.*;
38 import sun.jvm.hotspot.compiler.*;
39 import sun.jvm.hotspot.debugger.*;
40 import sun.jvm.hotspot.interpreter.*;
41 import sun.jvm.hotspot.memory.*;
42 import sun.jvm.hotspot.oops.*;
43 import sun.jvm.hotspot.runtime.*;
44 import sun.jvm.hotspot.utilities.*;
45 import sun.jvm.hotspot.utilities.soql.*;
46 import sun.jvm.hotspot.ui.classbrowser.*;
47 import sun.jvm.hotspot.ui.tree.*;
48 import sun.jvm.hotspot.tools.*;
49 import sun.jvm.hotspot.tools.ObjectHistogram;
50 import sun.jvm.hotspot.tools.StackTrace;
51
52 public class CommandProcessor {
53 public abstract static class DebuggerInterface {
54 public abstract HotSpotAgent getAgent();
55 public abstract boolean isAttached();
56 public abstract void attach(String pid);
57 public abstract void attach(String java, String core);
58 public abstract void detach();
59 public abstract void reattach();
60 }
61
62 static class Tokens {
63 final String input;
64 int i;
65 String[] tokens;
66 int length;
67
68 String[] splitWhitespace(String cmd) {
69 String[] t = cmd.split("\\s");
70 if (t.length == 1 && t[0].length() == 0) {
71 return new String[0];
72 }
73 return t;
74 }
75
76 void add(String s, ArrayList t) {
77 if (s.length() > 0) {
78 t.add(s);
79 }
80 }
81
241 if (type.getSuperclass() != null) {
242 quote(type.getSuperclass().getName());
243 out.print(" ");
244 } else {
245 out.print("null ");
246 }
247 out.print(type.isOopType());
248 out.print(" ");
249 if (type.isCIntegerType()) {
250 out.print("true ");
251 out.print(((CIntegerType)type).isUnsigned());
252 out.print(" ");
253 } else {
254 out.print("false false ");
255 }
256 out.print(type.getSize());
257 out.println();
258 }
259
260 void dumpFields(Type type) {
261 Iterator i = type.getFields();
262 while (i.hasNext()) {
263 Field f = (Field) i.next();
264 out.print("field ");
265 quote(type.getName());
266 out.print(" ");
267 out.print(f.getName());
268 out.print(" ");
269 quote(f.getType().getName());
270 out.print(" ");
271 out.print(f.isStatic());
272 out.print(" ");
273 if (f.isStatic()) {
274 out.print("0 ");
275 out.print(f.getStaticFieldAddress());
276 } else {
277 out.print(f.getOffset());
278 out.print(" 0x0");
279 }
280 out.println();
281 }
282 }
283
441 },
442 new Command("symboltable", "symboltable name", false) {
443 public void doit(Tokens t) {
444 if (t.countTokens() != 1) {
445 usage();
446 } else {
447 out.println(SymbolTable.getTheTable().probe(t.nextToken()));
448 }
449 }
450 },
451 new Command("symboldump", "symboldump", false) {
452 public void doit(Tokens t) {
453 SymbolTable.getTheTable().symbolsDo(new SymbolTable.SymbolVisitor() {
454 public void visit(Symbol sym) {
455 sym.printValueOn(out);
456 out.println();
457 }
458 });
459 }
460 },
461 new Command("flags", "flags [ flag ]", false) {
462 public void doit(Tokens t) {
463 int tokens = t.countTokens();
464 if (tokens != 0 && tokens != 1) {
465 usage();
466 } else {
467 String name = tokens > 0 ? t.nextToken() : null;
468
469 VM.Flag[] flags = VM.getVM().getCommandLineFlags();
470 if (flags == null) {
471 out.println("Command Flag info not available (use 1.4.1_03 or later)!");
472 } else {
473 boolean printed = false;
474 for (int f = 0; f < flags.length; f++) {
475 VM.Flag flag = flags[f];
476 if (name == null || flag.getName().equals(name)) {
477 out.println(flag.getName() + " = " + flag.getValue());
478 printed = true;
479 }
480 }
481 if (name != null && !printed) {
482 out.println("Couldn't find flag: " + name);
483 }
484 }
485 }
486 }
487 },
488 new Command("help", "help [ command ]", true) {
489 public void doit(Tokens t) {
490 int tokens = t.countTokens();
491 Command cmd = null;
492 if (tokens == 1) {
493 cmd = findCommand(t.nextToken());
494 }
495
496 if (cmd != null) {
497 cmd.usage();
569 while (ptrs.size() == 1) {
570 LivenessPathElement e = (LivenessPathElement)ptrs.get(0);
571 ByteArrayOutputStream bos = new ByteArrayOutputStream();
572 Oop.printOopValueOn(e.getObj(), new PrintStream(bos));
573 out.println(bos.toString());
574 ptrs = revptrs.get(e.getObj());
575 }
576 } else {
577 for (int i = 0; i < ptrs.size(); i++) {
578 LivenessPathElement e = (LivenessPathElement)ptrs.get(i);
579 ByteArrayOutputStream bos = new ByteArrayOutputStream();
580 Oop.printOopValueOn(e.getObj(), new PrintStream(bos));
581 out.println(bos.toString());
582 oop = e.getObj();
583 }
584 }
585 }
586 }
587 }
588 },
589 new Command("inspect", "inspect expression", false) {
590 public void doit(Tokens t) {
591 if (t.countTokens() != 1) {
592 usage();
593 } else {
594 Address a = VM.getVM().getDebugger().parseAddress(t.nextToken());
595 SimpleTreeNode node = null;
596 if (VM.getVM().getUniverse().heap().isInReserved(a)) {
597 OopHandle handle = a.addOffsetToAsOopHandle(0);
598 Oop oop = VM.getVM().getObjectHeap().newOop(handle);
599 node = new OopTreeNodeAdapter(oop, null);
600
601 out.println("instance of " + node.getValue() + " @ " + a +
602 " (size = " + oop.getObjectSize() + ")");
603 } else if (VM.getVM().getCodeCache().contains(a)) {
604 CodeBlob blob = VM.getVM().getCodeCache().findBlobUnsafe(a);
605 a = blob.headerBegin();
606 }
607 if (node == null) {
608 Type type = VM.getVM().getTypeDataBase().guessTypeForAddress(a);
743 while (base != null && base.lessThan(end)) {
744 long step = stride;
745 OopHandle handle = base.addOffsetToAsOopHandle(0);
746 if (RobustOopDeterminator.oopLooksValid(handle)) {
747 try {
748 Oop oop = VM.getVM().getObjectHeap().newOop(handle);
749 if (klass == null || oop.getKlass().isSubtypeOf(klass))
750 out.println(handle.toString() + " " + oop.getKlass().getName().asString());
751 step = oop.getObjectSize();
752 } catch (UnknownOopException ex) {
753 // ok
754 } catch (RuntimeException ex) {
755 ex.printStackTrace();
756 }
757 }
758 base = base.addOffsetTo(step);
759 }
760 }
761 }
762 },
763 new Command("field", "field [ type [ name fieldtype isStatic offset address ] ]", true) {
764 public void doit(Tokens t) {
765 if (t.countTokens() != 1 && t.countTokens() != 0 && t.countTokens() != 6) {
766 usage();
767 return;
768 }
769 if (t.countTokens() == 1) {
770 Type type = agent.getTypeDataBase().lookupType(t.nextToken());
771 dumpFields(type);
772 } else if (t.countTokens() == 0) {
773 Iterator i = agent.getTypeDataBase().getTypes();
774 while (i.hasNext()) {
775 dumpFields((Type)i.next());
776 }
777 } else {
778 BasicType containingType = (BasicType)agent.getTypeDataBase().lookupType(t.nextToken());
779
780 String fieldName = t.nextToken();
781
782 // The field's Type must already be in the database -- no exceptions
1294 if (debugger.isAttached()) {
1295 postAttach();
1296 }
1297 }
1298
1299
1300 public void run(boolean prompt) {
1301 // Process interactive commands.
1302 while (true) {
1303 if (prompt) printPrompt();
1304 String ln = null;
1305 try {
1306 ln = in.readLine();
1307 } catch (IOException e) {
1308 }
1309 if (ln == null) {
1310 if (prompt) err.println("Input stream closed.");
1311 return;
1312 }
1313
1314 executeCommand(ln);
1315 }
1316 }
1317
1318 static Pattern historyPattern = Pattern.compile("((!\\*)|(!\\$)|(!!-?)|(!-?[0-9][0-9]*)|(![a-zA-Z][^ ]*))");
1319
1320 public void executeCommand(String ln) {
1321 if (ln.indexOf('!') != -1) {
1322 int size = history.size();
1323 if (size == 0) {
1324 ln = "";
1325 err.println("History is empty");
1326 } else {
1327 StringBuffer result = new StringBuffer();
1328 Matcher m = historyPattern.matcher(ln);
1329 int start = 0;
1330 while (m.find()) {
1331 if (m.start() > start) {
1332 result.append(ln.substring(start, m.start() - start));
1333 }
1334 start = m.end();
1335
1336 String cmd = m.group();
1337 if (cmd.equals("!!")) {
1338 result.append((String)history.get(history.size() - 1));
1339 } else if (cmd.equals("!!-")) {
1340 Tokens item = new Tokens((String)history.get(history.size() - 1));
1389 } else {
1390 if (start < ln.length()) {
1391 result.append(ln.substring(start));
1392 }
1393 ln = result.toString();
1394 if (!doEcho) {
1395 out.println(ln);
1396 }
1397 }
1398 }
1399 }
1400
1401 if (doEcho) {
1402 out.println("+ " + ln);
1403 }
1404
1405 PrintStream redirect = null;
1406 Tokens t = new Tokens(ln);
1407 if (t.hasMoreTokens()) {
1408 boolean error = false;
1409 history.add(ln);
1410 int len = t.countTokens();
1411 if (len > 2) {
1412 String r = t.at(len - 2);
1413 if (r.equals(">") || r.equals(">>")) {
1414 boolean append = r.length() == 2;
1415 String file = t.at(len - 1);
1416 try {
1417 redirect = new PrintStream(new BufferedOutputStream(new FileOutputStream(file, append)));
1418 t.trim(2);
1419 } catch (Exception e) {
1420 out.println("Error: " + e);
1421 if (verboseExceptions) {
1422 e.printStackTrace(out);
1423 }
1424 error = true;
1425 }
1426 }
1427 }
1428 if (!error) {
1429 PrintStream savedout = out;
|
23 */
24
25 package sun.jvm.hotspot;
26
27 import java.io.*;
28 import java.math.*;
29 import java.util.*;
30 import java.util.regex.*;
31
32 import sun.jvm.hotspot.types.Type;
33 import sun.jvm.hotspot.types.Field;
34 import sun.jvm.hotspot.HotSpotTypeDataBase;
35 import sun.jvm.hotspot.types.basic.BasicType;
36 import sun.jvm.hotspot.types.CIntegerType;
37 import sun.jvm.hotspot.code.*;
38 import sun.jvm.hotspot.compiler.*;
39 import sun.jvm.hotspot.debugger.*;
40 import sun.jvm.hotspot.interpreter.*;
41 import sun.jvm.hotspot.memory.*;
42 import sun.jvm.hotspot.oops.*;
43 import sun.jvm.hotspot.opto.*;
44 import sun.jvm.hotspot.ci.*;
45 import sun.jvm.hotspot.runtime.*;
46 import sun.jvm.hotspot.utilities.*;
47 import sun.jvm.hotspot.utilities.soql.*;
48 import sun.jvm.hotspot.ui.classbrowser.*;
49 import sun.jvm.hotspot.ui.tree.*;
50 import sun.jvm.hotspot.tools.*;
51 import sun.jvm.hotspot.tools.ObjectHistogram;
52 import sun.jvm.hotspot.tools.StackTrace;
53 import sun.jvm.hotspot.tools.jcore.ClassDump;
54 import sun.jvm.hotspot.tools.jcore.ClassFilter;
55
56 public class CommandProcessor {
57 public abstract static class DebuggerInterface {
58 public abstract HotSpotAgent getAgent();
59 public abstract boolean isAttached();
60 public abstract void attach(String pid);
61 public abstract void attach(String java, String core);
62 public abstract void detach();
63 public abstract void reattach();
64 }
65
66 public static class BootFilter implements ClassFilter {
67 public boolean canInclude(InstanceKlass kls) {
68 return kls.getClassLoader() == null;
69 }
70 }
71
72 public static class NonBootFilter implements ClassFilter {
73 private HashMap emitted = new HashMap();
74 public boolean canInclude(InstanceKlass kls) {
75 if (kls.getClassLoader() == null) return false;
76 if (emitted.get(kls.getName()) != null) {
77 // Since multiple class loaders are being shoved
78 // together duplicate classes are a possibilty. For
79 // now just ignore them.
80 return false;
81 }
82 emitted.put(kls.getName(), kls);
83 return true;
84 }
85 }
86
87 static class Tokens {
88 final String input;
89 int i;
90 String[] tokens;
91 int length;
92
93 String[] splitWhitespace(String cmd) {
94 String[] t = cmd.split("\\s");
95 if (t.length == 1 && t[0].length() == 0) {
96 return new String[0];
97 }
98 return t;
99 }
100
101 void add(String s, ArrayList t) {
102 if (s.length() > 0) {
103 t.add(s);
104 }
105 }
106
266 if (type.getSuperclass() != null) {
267 quote(type.getSuperclass().getName());
268 out.print(" ");
269 } else {
270 out.print("null ");
271 }
272 out.print(type.isOopType());
273 out.print(" ");
274 if (type.isCIntegerType()) {
275 out.print("true ");
276 out.print(((CIntegerType)type).isUnsigned());
277 out.print(" ");
278 } else {
279 out.print("false false ");
280 }
281 out.print(type.getSize());
282 out.println();
283 }
284
285 void dumpFields(Type type) {
286 dumpFields(type, true);
287 }
288
289 void dumpFields(Type type, boolean allowStatic) {
290 Iterator i = type.getFields();
291 while (i.hasNext()) {
292 Field f = (Field) i.next();
293 if (!allowStatic && f.isStatic()) continue;
294 out.print("field ");
295 quote(type.getName());
296 out.print(" ");
297 out.print(f.getName());
298 out.print(" ");
299 quote(f.getType().getName());
300 out.print(" ");
301 out.print(f.isStatic());
302 out.print(" ");
303 if (f.isStatic()) {
304 out.print("0 ");
305 out.print(f.getStaticFieldAddress());
306 } else {
307 out.print(f.getOffset());
308 out.print(" 0x0");
309 }
310 out.println();
311 }
312 }
313
471 },
472 new Command("symboltable", "symboltable name", false) {
473 public void doit(Tokens t) {
474 if (t.countTokens() != 1) {
475 usage();
476 } else {
477 out.println(SymbolTable.getTheTable().probe(t.nextToken()));
478 }
479 }
480 },
481 new Command("symboldump", "symboldump", false) {
482 public void doit(Tokens t) {
483 SymbolTable.getTheTable().symbolsDo(new SymbolTable.SymbolVisitor() {
484 public void visit(Symbol sym) {
485 sym.printValueOn(out);
486 out.println();
487 }
488 });
489 }
490 },
491 new Command("flags", "flags [ flag | -nd ]", false) {
492 public void doit(Tokens t) {
493 int tokens = t.countTokens();
494 if (tokens != 0 && tokens != 1) {
495 usage();
496 } else {
497 String name = tokens > 0 ? t.nextToken() : null;
498 boolean nonDefault = false;
499 if (name != null && name.equals("-nd")) {
500 name = null;
501 nonDefault = true;
502 }
503
504 VM.Flag[] flags = VM.getVM().getCommandLineFlags();
505 if (flags == null) {
506 out.println("Command Flag info not available (use 1.4.1_03 or later)!");
507 } else {
508 boolean printed = false;
509 for (int f = 0; f < flags.length; f++) {
510 VM.Flag flag = flags[f];
511 if (name == null || flag.getName().equals(name)) {
512
513 if (nonDefault && flag.getOrigin() == 0) {
514 // only print flags which aren't their defaults
515 continue;
516 }
517 out.println(flag.getName() + " = " + flag.getValue() + " " + flag.getOrigin());
518 printed = true;
519 }
520 }
521 if (name != null && !printed) {
522 out.println("Couldn't find flag: " + name);
523 }
524 }
525 }
526 }
527 },
528 new Command("help", "help [ command ]", true) {
529 public void doit(Tokens t) {
530 int tokens = t.countTokens();
531 Command cmd = null;
532 if (tokens == 1) {
533 cmd = findCommand(t.nextToken());
534 }
535
536 if (cmd != null) {
537 cmd.usage();
609 while (ptrs.size() == 1) {
610 LivenessPathElement e = (LivenessPathElement)ptrs.get(0);
611 ByteArrayOutputStream bos = new ByteArrayOutputStream();
612 Oop.printOopValueOn(e.getObj(), new PrintStream(bos));
613 out.println(bos.toString());
614 ptrs = revptrs.get(e.getObj());
615 }
616 } else {
617 for (int i = 0; i < ptrs.size(); i++) {
618 LivenessPathElement e = (LivenessPathElement)ptrs.get(i);
619 ByteArrayOutputStream bos = new ByteArrayOutputStream();
620 Oop.printOopValueOn(e.getObj(), new PrintStream(bos));
621 out.println(bos.toString());
622 oop = e.getObj();
623 }
624 }
625 }
626 }
627 }
628 },
629 new Command("printmdo", "printmdo [ -a | expression ]", false) {
630 // Print every MDO in the heap or the one referenced by expression.
631 public void doit(Tokens t) {
632 if (t.countTokens() != 1) {
633 usage();
634 } else {
635 String s = t.nextToken();
636 if (s.equals("-a")) {
637 HeapVisitor iterator = new DefaultHeapVisitor() {
638 public boolean doObj(Oop obj) {
639 if (obj instanceof MethodData) {
640 Method m = ((MethodData)obj).getMethod();
641 out.println("MethodData " + obj.getHandle() + " for " +
642 "method " + m.getMethodHolder().getName().asString() + "." +
643 m.getName().asString() +
644 m.getSignature().asString() + "@" + m.getHandle());
645 ((MethodData)obj).printDataOn(out);
646 }
647 return false;
648 }
649 };
650 VM.getVM().getObjectHeap().iteratePerm(iterator);
651 } else {
652 Address a = VM.getVM().getDebugger().parseAddress(s);
653 OopHandle handle = a.addOffsetToAsOopHandle(0);
654 MethodData mdo = (MethodData)VM.getVM().getObjectHeap().newOop(handle);
655 mdo.printDataOn(out);
656 }
657 }
658 }
659 },
660 new Command("dumpideal", "dumpideal { -a | id }", false) {
661 // Do a full dump of the nodes reachabile from root in each compiler thread.
662 public void doit(Tokens t) {
663 if (t.countTokens() != 1) {
664 usage();
665 } else {
666 String name = t.nextToken();
667 boolean all = name.equals("-a");
668 Threads threads = VM.getVM().getThreads();
669 for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
670 ByteArrayOutputStream bos = new ByteArrayOutputStream();
671 thread.printThreadIDOn(new PrintStream(bos));
672 if (all || bos.toString().equals(name)) {
673 if (thread instanceof CompilerThread) {
674 CompilerThread ct = (CompilerThread)thread;
675 out.println(ct);
676 ciEnv env = ct.env();
677 if (env != null) {
678 Compile c = env.compilerData();
679 c.root().dump(9999, out);
680 } else {
681 out.println(" not compiling");
682 }
683 }
684 }
685 }
686 }
687 }
688 },
689 new Command("dumpcfg", "dumpcfg { -a | id }", false) {
690 // Dump the PhaseCFG for every compiler thread that has one live.
691 public void doit(Tokens t) {
692 if (t.countTokens() != 1) {
693 usage();
694 } else {
695 String name = t.nextToken();
696 boolean all = name.equals("-a");
697 Threads threads = VM.getVM().getThreads();
698 for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
699 ByteArrayOutputStream bos = new ByteArrayOutputStream();
700 thread.printThreadIDOn(new PrintStream(bos));
701 if (all || bos.toString().equals(name)) {
702 if (thread instanceof CompilerThread) {
703 CompilerThread ct = (CompilerThread)thread;
704 out.println(ct);
705 ciEnv env = ct.env();
706 if (env != null) {
707 Compile c = env.compilerData();
708 c.cfg().dump(out);
709 }
710 }
711 }
712 }
713 }
714 }
715 },
716 new Command("dumpilt", "dumpilt { -a | id }", false) {
717 // dumps the InlineTree of a C2 compile
718 public void doit(Tokens t) {
719 if (t.countTokens() != 1) {
720 usage();
721 } else {
722 String name = t.nextToken();
723 boolean all = name.equals("-a");
724 Threads threads = VM.getVM().getThreads();
725 for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
726 ByteArrayOutputStream bos = new ByteArrayOutputStream();
727 thread.printThreadIDOn(new PrintStream(bos));
728 if (all || bos.toString().equals(name)) {
729 if (thread instanceof CompilerThread) {
730 CompilerThread ct = (CompilerThread)thread;
731 ciEnv env = ct.env();
732 if (env != null) {
733 Compile c = env.compilerData();
734 InlineTree ilt = c.ilt();
735 if (ilt != null) {
736 ilt.print(out);
737 }
738 }
739 }
740 }
741 }
742 }
743 }
744 },
745 new Command("vmstructsdump", "vmstructsdump", false) {
746 public void doit(Tokens t) {
747 if (t.countTokens() != 0) {
748 usage();
749 return;
750 }
751
752 // Dump a copy of the type database in a form that can
753 // be read back.
754 Iterator i = agent.getTypeDataBase().getTypes();
755 // Make sure the types are emitted in an order than can be read back in
756 HashSet emitted = new HashSet();
757 Stack pending = new Stack();
758 while (i.hasNext()) {
759 Type n = (Type)i.next();
760 if (emitted.contains(n.getName())) {
761 continue;
762 }
763
764 while (n != null && !emitted.contains(n.getName())) {
765 pending.push(n);
766 n = n.getSuperclass();
767 }
768 while (!pending.empty()) {
769 n = (Type)pending.pop();
770 dumpType(n);
771 emitted.add(n.getName());
772 }
773 }
774 i = agent.getTypeDataBase().getTypes();
775 while (i.hasNext()) {
776 dumpFields((Type)i.next(), false);
777 }
778 }
779 },
780
781 new Command("inspect", "inspect expression", false) {
782 public void doit(Tokens t) {
783 if (t.countTokens() != 1) {
784 usage();
785 } else {
786 Address a = VM.getVM().getDebugger().parseAddress(t.nextToken());
787 SimpleTreeNode node = null;
788 if (VM.getVM().getUniverse().heap().isInReserved(a)) {
789 OopHandle handle = a.addOffsetToAsOopHandle(0);
790 Oop oop = VM.getVM().getObjectHeap().newOop(handle);
791 node = new OopTreeNodeAdapter(oop, null);
792
793 out.println("instance of " + node.getValue() + " @ " + a +
794 " (size = " + oop.getObjectSize() + ")");
795 } else if (VM.getVM().getCodeCache().contains(a)) {
796 CodeBlob blob = VM.getVM().getCodeCache().findBlobUnsafe(a);
797 a = blob.headerBegin();
798 }
799 if (node == null) {
800 Type type = VM.getVM().getTypeDataBase().guessTypeForAddress(a);
935 while (base != null && base.lessThan(end)) {
936 long step = stride;
937 OopHandle handle = base.addOffsetToAsOopHandle(0);
938 if (RobustOopDeterminator.oopLooksValid(handle)) {
939 try {
940 Oop oop = VM.getVM().getObjectHeap().newOop(handle);
941 if (klass == null || oop.getKlass().isSubtypeOf(klass))
942 out.println(handle.toString() + " " + oop.getKlass().getName().asString());
943 step = oop.getObjectSize();
944 } catch (UnknownOopException ex) {
945 // ok
946 } catch (RuntimeException ex) {
947 ex.printStackTrace();
948 }
949 }
950 base = base.addOffsetTo(step);
951 }
952 }
953 }
954 },
955 new Command("intConstant", "intConstant [ name [ value ] ]", true) {
956 public void doit(Tokens t) {
957 if (t.countTokens() != 1 && t.countTokens() != 0 && t.countTokens() != 2) {
958 usage();
959 return;
960 }
961 HotSpotTypeDataBase db = (HotSpotTypeDataBase)agent.getTypeDataBase();
962 if (t.countTokens() == 1) {
963 out.println("intConstant " + name + " " + db.lookupIntConstant(name));
964 } else if (t.countTokens() == 0) {
965 Iterator i = db.getIntConstants();
966 while (i.hasNext()) {
967 String name = (String)i.next();
968 out.println("intConstant " + name + " " + db.lookupIntConstant(name));
969 }
970 } else if (t.countTokens() == 2) {
971 String name = t.nextToken();
972 Integer value = Integer.valueOf(t.nextToken());
973 db.addIntConstant(name, value);
974 }
975 }
976 },
977 new Command("longConstant", "longConstant [ name [ value ] ]", true) {
978 public void doit(Tokens t) {
979 if (t.countTokens() != 1 && t.countTokens() != 0 && t.countTokens() != 2) {
980 usage();
981 return;
982 }
983 HotSpotTypeDataBase db = (HotSpotTypeDataBase)agent.getTypeDataBase();
984 if (t.countTokens() == 1) {
985 out.println("longConstant " + name + " " + db.lookupLongConstant(name));
986 } else if (t.countTokens() == 0) {
987 Iterator i = db.getLongConstants();
988 while (i.hasNext()) {
989 String name = (String)i.next();
990 out.println("longConstant " + name + " " + db.lookupLongConstant(name));
991 }
992 } else if (t.countTokens() == 2) {
993 String name = t.nextToken();
994 Long value = Long.valueOf(t.nextToken());
995 db.addLongConstant(name, value);
996 }
997 }
998 },
999 new Command("field", "field [ type [ name fieldtype isStatic offset address ] ]", true) {
1000 public void doit(Tokens t) {
1001 if (t.countTokens() != 1 && t.countTokens() != 0 && t.countTokens() != 6) {
1002 usage();
1003 return;
1004 }
1005 if (t.countTokens() == 1) {
1006 Type type = agent.getTypeDataBase().lookupType(t.nextToken());
1007 dumpFields(type);
1008 } else if (t.countTokens() == 0) {
1009 Iterator i = agent.getTypeDataBase().getTypes();
1010 while (i.hasNext()) {
1011 dumpFields((Type)i.next());
1012 }
1013 } else {
1014 BasicType containingType = (BasicType)agent.getTypeDataBase().lookupType(t.nextToken());
1015
1016 String fieldName = t.nextToken();
1017
1018 // The field's Type must already be in the database -- no exceptions
1530 if (debugger.isAttached()) {
1531 postAttach();
1532 }
1533 }
1534
1535
1536 public void run(boolean prompt) {
1537 // Process interactive commands.
1538 while (true) {
1539 if (prompt) printPrompt();
1540 String ln = null;
1541 try {
1542 ln = in.readLine();
1543 } catch (IOException e) {
1544 }
1545 if (ln == null) {
1546 if (prompt) err.println("Input stream closed.");
1547 return;
1548 }
1549
1550 executeCommand(ln, prompt);
1551 }
1552 }
1553
1554 static Pattern historyPattern = Pattern.compile("((!\\*)|(!\\$)|(!!-?)|(!-?[0-9][0-9]*)|(![a-zA-Z][^ ]*))");
1555
1556 public void executeCommand(String ln, boolean putInHistory) {
1557 if (ln.indexOf('!') != -1) {
1558 int size = history.size();
1559 if (size == 0) {
1560 ln = "";
1561 err.println("History is empty");
1562 } else {
1563 StringBuffer result = new StringBuffer();
1564 Matcher m = historyPattern.matcher(ln);
1565 int start = 0;
1566 while (m.find()) {
1567 if (m.start() > start) {
1568 result.append(ln.substring(start, m.start() - start));
1569 }
1570 start = m.end();
1571
1572 String cmd = m.group();
1573 if (cmd.equals("!!")) {
1574 result.append((String)history.get(history.size() - 1));
1575 } else if (cmd.equals("!!-")) {
1576 Tokens item = new Tokens((String)history.get(history.size() - 1));
1625 } else {
1626 if (start < ln.length()) {
1627 result.append(ln.substring(start));
1628 }
1629 ln = result.toString();
1630 if (!doEcho) {
1631 out.println(ln);
1632 }
1633 }
1634 }
1635 }
1636
1637 if (doEcho) {
1638 out.println("+ " + ln);
1639 }
1640
1641 PrintStream redirect = null;
1642 Tokens t = new Tokens(ln);
1643 if (t.hasMoreTokens()) {
1644 boolean error = false;
1645 if (putInHistory) history.add(ln);
1646 int len = t.countTokens();
1647 if (len > 2) {
1648 String r = t.at(len - 2);
1649 if (r.equals(">") || r.equals(">>")) {
1650 boolean append = r.length() == 2;
1651 String file = t.at(len - 1);
1652 try {
1653 redirect = new PrintStream(new BufferedOutputStream(new FileOutputStream(file, append)));
1654 t.trim(2);
1655 } catch (Exception e) {
1656 out.println("Error: " + e);
1657 if (verboseExceptions) {
1658 e.printStackTrace(out);
1659 }
1660 error = true;
1661 }
1662 }
1663 }
1664 if (!error) {
1665 PrintStream savedout = out;
|