📄 tty.java
字号:
/*
* @(#)TTY.java 1.80 98/07/01
*
* Copyright 1995-1998 by Sun Microsystems, Inc.,
* 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
* All rights reserved.
*
* This software is the confidential and proprietary information
* of Sun Microsystems, Inc. ("Confidential Information"). You
* shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement
* you entered into with Sun.
*/
package sun.tools.ttydebug;
import sun.tools.debug.*;
import java.util.*;
import java.io.*;
import java.net.*;
public class TTY implements DebuggerCallback {
RemoteDebugger debugger;
RemoteThread currentThread;
RemoteThreadGroup currentThreadGroup;
PrintStream out = null;
PrintStream console = null;
private static final String progname = "jdb";
private static final String version = "98/07/01";
private String lastArgs = null;
private RemoteThread indexToThread(int index) throws Exception {
setDefaultThreadGroup();
RemoteThread list[] = currentThreadGroup.listThreads(true);
if (index == 0 || index > list.length) {
return null;
}
return list[index-1];
}
private int parseThreadId(String idToken) throws Exception {
if (idToken.startsWith("t@")) {
idToken = idToken.substring(2);
}
int threadId;
try {
threadId = Integer.valueOf(idToken).intValue();
} catch (NumberFormatException e) {
threadId = 0;
}
if (indexToThread(threadId) == null) {
out.println("\"" + idToken +
"\" is not a valid thread id.");
return 0;
}
return threadId;
}
private void printPrompt() throws Exception {
if (currentThread == null) {
out.print("> ");
} else {
out.print(currentThread.getName() + "[" +
(currentThread.getCurrentFrameIndex() + 1)
+ "] ");
}
out.flush();
}
public synchronized void printToConsole(String text) throws Exception {
console.print(text);
console.flush();
}
public void breakpointEvent(RemoteThread t) throws Exception {
out.print("\nBreakpoint hit: ");
RemoteStackFrame[] stack = t.dumpStack();
if (stack.length > 0) {
out.println(stack[0].toString());
currentThread = t;
} else {
out.println("Invalid thread specified in breakpoint.");
}
printPrompt();
}
public void exceptionEvent(RemoteThread t, String errorText)
throws Exception {
out.println("\n" + errorText);
t.setCurrentFrameIndex(0);
currentThread = t;
printPrompt();
}
public void threadDeathEvent(RemoteThread t) throws Exception {
out.println("\n" + t.getName() + " died.");
if (t == currentThread) {
currentThread = null;
}
printPrompt();
}
public void quitEvent() throws Exception {
String msg = null;
if (lastArgs != null) {
StringTokenizer t = new StringTokenizer(lastArgs);
if (t.hasMoreTokens()) {
msg = new String("\n" + t.nextToken() + " exited");
}
}
if (msg == null) {
msg = new String("\nThe application exited");
}
out.println(msg);
currentThread = null;
System.exit(0);
}
void classes() throws Exception {
RemoteClass list[] = debugger.listClasses();
out.println("** classes list **");
for (int i = 0 ; i < list.length ; i++) {
out.println(list[i].description());
}
}
void methods(StringTokenizer t) throws Exception {
if (!t.hasMoreTokens()) {
out.println("No class specified.");
return;
}
String idClass = t.nextToken();
try {
RemoteClass cls = getClassFromToken(idClass);
RemoteField methods[] = cls.getMethods();
for (int i = 0; i < methods.length; i++) {
out.println(methods[i].getTypedName());
}
} catch (IllegalArgumentException e) {
out.println("\"" + idClass +
"\" is not a valid id or class name.");
}
}
int printThreadGroup(RemoteThreadGroup tg, int iThread) throws Exception {
out.println("Group " + tg.getName() + ":");
RemoteThread tlist[] = tg.listThreads(false);
int maxId = 0;
int maxName = 0;
for (int i = 0 ; i < tlist.length ; i++) {
int len = tlist[i].description().length();
if (len > maxId)
maxId = len;
String name = tlist[i].getName();
int iDot = name.lastIndexOf('.');
if (iDot >= 0 && name.length() > iDot) {
name = name.substring(iDot + 1);
}
if (name.length() > maxName)
maxName = name.length();
}
String maxNumString = String.valueOf(iThread + tlist.length);
int maxNumDigits = maxNumString.length();
for (int i = 0 ; i < tlist.length ; i++) {
char buf[] = new char[80];
for (int j = 0; j < 79; j++) {
buf[j] = ' ';
}
buf[79] = '\0';
StringBuffer sbOut = new StringBuffer();
sbOut.append(buf);
// Right-justify the thread number at start of output string
String numString = String.valueOf(iThread + i + 1);
sbOut.insert(maxNumDigits - numString.length(),
numString);
sbOut.insert(maxNumDigits, ".");
int iBuf = maxNumDigits + 2;
sbOut.insert(iBuf, tlist[i].description());
iBuf += maxId + 1;
String name = tlist[i].getName();
int iDot = name.lastIndexOf('.');
if (iDot >= 0 && name.length() > iDot) {
name = name.substring(iDot + 1);
}
sbOut.insert(iBuf, name);
iBuf += maxName + 1;
sbOut.insert(iBuf, tlist[i].getStatus());
sbOut.setLength(79);
out.println(sbOut.toString());
}
RemoteThreadGroup tglist[] = debugger.listThreadGroups(tg);
for (int ig = 0; ig < tglist.length; ig++) {
if (tg != tglist[ig]) {
iThread += printThreadGroup(tglist[ig], iThread + tlist.length);
}
}
return tlist.length;
}
private void setDefaultThreadGroup() throws Exception {
if (currentThreadGroup == null) {
RemoteThreadGroup tglist[] = debugger.listThreadGroups(null);
currentThreadGroup = tglist[0]; // system threadgroup
}
}
void threads(StringTokenizer t) throws Exception {
if (!t.hasMoreTokens()) {
setDefaultThreadGroup();
printThreadGroup(currentThreadGroup, 0);
return;
}
String name = t.nextToken();
RemoteThreadGroup tglist[] = debugger.listThreadGroups(null);
for (int i = 0; i < tglist.length; i++) {
if (name.equals(tglist[i].getName())) {
printThreadGroup(tglist[i], 0);
return;
}
}
out.println(name + " is not a valid threadgroup name.");
}
void threadGroups() throws Exception {
RemoteThreadGroup tglist[] = debugger.listThreadGroups(null);
for (int i = 0; i < tglist.length; i++) {
out.println(new Integer(i+1).toString() + ". " +
tglist[i].description() + " " +
tglist[i].getName());
}
}
void setThread(int threadId) throws Exception {
setDefaultThreadGroup();
RemoteThread thread = indexToThread(threadId);
if (thread == null) {
out.println("\"" + threadId +
"\" is not a valid thread id.");
return;
}
currentThread = thread;
}
void thread(StringTokenizer t) throws Exception {
if (!t.hasMoreTokens()) {
out.println("Thread number not specified.");
return;
}
int threadId = parseThreadId(t.nextToken());
if (threadId == 0) {
return;
}
setThread(threadId);
}
void threadGroup(StringTokenizer t) throws Exception {
if (!t.hasMoreTokens()) {
out.println("Threadgroup name not specified.");
return;
}
String name = t.nextToken();
RemoteThreadGroup tglist[] = debugger.listThreadGroups(null);
for (int i = 0; i < tglist.length; i++) {
if (name.equals(tglist[i].getName())) {
currentThreadGroup = tglist[i];
return;
}
}
out.println(name + " is not a valid threadgroup name.");
}
void run(StringTokenizer t) throws Exception {
String argv[] = new String[100];
int argc = 0;
if (!t.hasMoreTokens() && lastArgs != null) {
t = new StringTokenizer(lastArgs);
out.println("run " + lastArgs);
}
while (t.hasMoreTokens()) {
argv[argc++] = t.nextToken();
if (argc == 1) {
// Expand name, if necessary.
RemoteClass cls = debugger.findClass(argv[0]);
if (cls == null) {
out.println("Could not load the " + argv[0] + " class.");
return;
}
argv[0] = cls.getName();
}
}
if (argc > 0) {
RemoteThreadGroup newGroup = debugger.run(argc, argv);
if (newGroup != null) {
currentThreadGroup = newGroup;
setThread(1);
out.println("running ...");
} else {
out.println(argv[0] + " failed.");
}
} else {
out.println("No class name specified.");
}
}
void load(StringTokenizer t) throws Exception {
if (!t.hasMoreTokens()) {
out.println("Class name not specified.");
return;
}
String idToken = t.nextToken();
RemoteClass cls = debugger.findClass(idToken);
if (cls == null) {
out.print(idToken + " not found");
out.println((idToken.indexOf('.') > 0) ?
" (try the full name)" : "");
} else {
out.println(cls.toString());
}
}
void suspend(StringTokenizer t) throws Exception {
if (!t.hasMoreTokens()) {
setDefaultThreadGroup();
RemoteThread list[] = currentThreadGroup.listThreads(true);
for (int i = 0; i < list.length; i++) {
list[i].suspend();
}
out.println("All (non-system) threads suspended.");
} else {
while (t.hasMoreTokens()) {
String idToken = t.nextToken();
int threadId;
try {
threadId = Integer.valueOf(idToken).intValue();
} catch (NumberFormatException e) {
threadId = 0;
}
RemoteThread thread = indexToThread(threadId);
if (thread == null) {
out.println("\"" + idToken +
"\" is not a valid thread id.");
continue;
}
thread.suspend();
}
}
}
void resume(StringTokenizer t) throws Exception {
if (!t.hasMoreTokens()) {
setDefaultThreadGroup();
RemoteThread list[] = currentThreadGroup.listThreads(true);
for (int i = 0; i < list.length; i++) {
list[i].resume();
}
if (currentThread != null) {
currentThread.resetCurrentFrameIndex();
}
out.println("All threads resumed.");
} else {
while (t.hasMoreTokens()) {
String idToken = t.nextToken();
int threadId;
try {
threadId = Integer.valueOf(idToken).intValue();
} catch (NumberFormatException e) {
threadId = 0;
}
RemoteThread thread = indexToThread(threadId);
if (thread == null) {
out.println("\"" + idToken +
"\" is not a valid thread id.");
continue;
}
thread.resume();
if (thread == currentThread) {
currentThread.resetCurrentFrameIndex();
}
}
}
}
void cont() throws Exception {
if (currentThread == null) {
out.println("Nothing suspended.");
return;
}
debugger.cont();
}
/* step
*
* step up (out of a function).
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -