feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is provided to illustrate the usage of a given feature
|
||||
* or technique and has been deliberately simplified. Additional steps
|
||||
* required for a production-quality application, such as security checks,
|
||||
* input validation and proper error handling, might not be present in
|
||||
* this sample code.
|
||||
*/
|
||||
|
||||
|
||||
package com.sun.tools.example.debug.tty;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.request.*;
|
||||
|
||||
class AccessWatchpointSpec extends WatchpointSpec {
|
||||
|
||||
AccessWatchpointSpec(ReferenceTypeSpec refSpec, String fieldId)
|
||||
throws MalformedMemberNameException {
|
||||
super(refSpec, fieldId);
|
||||
}
|
||||
|
||||
/**
|
||||
* The 'refType' is known to match, return the EventRequest.
|
||||
*/
|
||||
@Override
|
||||
EventRequest resolveEventRequest(ReferenceType refType)
|
||||
throws NoSuchFieldException {
|
||||
Field field = refType.fieldByName(fieldId);
|
||||
EventRequestManager em = refType.virtualMachine().eventRequestManager();
|
||||
EventRequest wp = em.createAccessWatchpointRequest(field);
|
||||
wp.setSuspendPolicy(suspendPolicy);
|
||||
wp.enable();
|
||||
return wp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return MessageOutput.format("watch accesses of",
|
||||
new Object [] {refSpec.toString(),
|
||||
fieldId});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is provided to illustrate the usage of a given feature
|
||||
* or technique and has been deliberately simplified. Additional steps
|
||||
* required for a production-quality application, such as security checks,
|
||||
* input validation and proper error handling, might not be present in
|
||||
* this sample code.
|
||||
*/
|
||||
|
||||
|
||||
package com.sun.tools.example.debug.tty;
|
||||
|
||||
public class AmbiguousMethodException extends Exception
|
||||
{
|
||||
private static final long serialVersionUID = -5372629264936918654L;
|
||||
|
||||
public AmbiguousMethodException()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public AmbiguousMethodException(String s)
|
||||
{
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
391
jdkSrc/jdk8/com/sun/tools/example/debug/tty/BreakpointSpec.java
Normal file
391
jdkSrc/jdk8/com/sun/tools/example/debug/tty/BreakpointSpec.java
Normal file
@@ -0,0 +1,391 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is provided to illustrate the usage of a given feature
|
||||
* or technique and has been deliberately simplified. Additional steps
|
||||
* required for a production-quality application, such as security checks,
|
||||
* input validation and proper error handling, might not be present in
|
||||
* this sample code.
|
||||
*/
|
||||
|
||||
|
||||
package com.sun.tools.example.debug.tty;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.request.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class BreakpointSpec extends EventRequestSpec {
|
||||
String methodId;
|
||||
List<String> methodArgs;
|
||||
int lineNumber;
|
||||
|
||||
BreakpointSpec(ReferenceTypeSpec refSpec, int lineNumber) {
|
||||
super(refSpec);
|
||||
this.methodId = null;
|
||||
this.methodArgs = null;
|
||||
this.lineNumber = lineNumber;
|
||||
}
|
||||
|
||||
BreakpointSpec(ReferenceTypeSpec refSpec, String methodId,
|
||||
List<String> methodArgs) throws MalformedMemberNameException {
|
||||
super(refSpec);
|
||||
this.methodId = methodId;
|
||||
this.methodArgs = methodArgs;
|
||||
this.lineNumber = 0;
|
||||
if (!isValidMethodName(methodId)) {
|
||||
throw new MalformedMemberNameException(methodId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The 'refType' is known to match, return the EventRequest.
|
||||
*/
|
||||
@Override
|
||||
EventRequest resolveEventRequest(ReferenceType refType)
|
||||
throws AmbiguousMethodException,
|
||||
AbsentInformationException,
|
||||
InvalidTypeException,
|
||||
NoSuchMethodException,
|
||||
LineNotFoundException {
|
||||
Location location = location(refType);
|
||||
if (location == null) {
|
||||
throw new InvalidTypeException();
|
||||
}
|
||||
EventRequestManager em = refType.virtualMachine().eventRequestManager();
|
||||
EventRequest bp = em.createBreakpointRequest(location);
|
||||
bp.setSuspendPolicy(suspendPolicy);
|
||||
bp.enable();
|
||||
return bp;
|
||||
}
|
||||
|
||||
String methodName() {
|
||||
return methodId;
|
||||
}
|
||||
|
||||
int lineNumber() {
|
||||
return lineNumber;
|
||||
}
|
||||
|
||||
List<String> methodArgs() {
|
||||
return methodArgs;
|
||||
}
|
||||
|
||||
boolean isMethodBreakpoint() {
|
||||
return (methodId != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return refSpec.hashCode() + lineNumber +
|
||||
((methodId != null) ? methodId.hashCode() : 0) +
|
||||
((methodArgs != null) ? methodArgs.hashCode() : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof BreakpointSpec) {
|
||||
BreakpointSpec breakpoint = (BreakpointSpec)obj;
|
||||
|
||||
return ((methodId != null) ?
|
||||
methodId.equals(breakpoint.methodId)
|
||||
: methodId == breakpoint.methodId) &&
|
||||
((methodArgs != null) ?
|
||||
methodArgs.equals(breakpoint.methodArgs)
|
||||
: methodArgs == breakpoint.methodArgs) &&
|
||||
refSpec.equals(breakpoint.refSpec) &&
|
||||
(lineNumber == breakpoint.lineNumber);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
String errorMessageFor(Exception e) {
|
||||
if (e instanceof AmbiguousMethodException) {
|
||||
return (MessageOutput.format("Method is overloaded; specify arguments",
|
||||
methodName()));
|
||||
/*
|
||||
* TO DO: list the methods here
|
||||
*/
|
||||
} else if (e instanceof NoSuchMethodException) {
|
||||
return (MessageOutput.format("No method in",
|
||||
new Object [] {methodName(),
|
||||
refSpec.toString()}));
|
||||
} else if (e instanceof AbsentInformationException) {
|
||||
return (MessageOutput.format("No linenumber information for",
|
||||
refSpec.toString()));
|
||||
} else if (e instanceof LineNotFoundException) {
|
||||
return (MessageOutput.format("No code at line",
|
||||
new Object [] {new Long (lineNumber()),
|
||||
refSpec.toString()}));
|
||||
} else if (e instanceof InvalidTypeException) {
|
||||
return (MessageOutput.format("Breakpoints can be located only in classes.",
|
||||
refSpec.toString()));
|
||||
} else {
|
||||
return super.errorMessageFor( e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer(refSpec.toString());
|
||||
if (isMethodBreakpoint()) {
|
||||
buffer.append('.');
|
||||
buffer.append(methodId);
|
||||
if (methodArgs != null) {
|
||||
boolean first = true;
|
||||
buffer.append('(');
|
||||
for (String arg : methodArgs) {
|
||||
if (!first) {
|
||||
buffer.append(',');
|
||||
}
|
||||
buffer.append(arg);
|
||||
first = false;
|
||||
}
|
||||
buffer.append(")");
|
||||
}
|
||||
} else {
|
||||
buffer.append(':');
|
||||
buffer.append(lineNumber);
|
||||
}
|
||||
return MessageOutput.format("breakpoint", buffer.toString());
|
||||
}
|
||||
|
||||
private Location location(ReferenceType refType) throws
|
||||
AmbiguousMethodException,
|
||||
AbsentInformationException,
|
||||
NoSuchMethodException,
|
||||
LineNotFoundException {
|
||||
Location location = null;
|
||||
if (isMethodBreakpoint()) {
|
||||
Method method = findMatchingMethod(refType);
|
||||
location = method.location();
|
||||
} else {
|
||||
// let AbsentInformationException be thrown
|
||||
List<Location> locs = refType.locationsOfLine(lineNumber());
|
||||
if (locs.size() == 0) {
|
||||
throw new LineNotFoundException();
|
||||
}
|
||||
// TO DO: handle multiple locations
|
||||
location = locs.get(0);
|
||||
if (location.method() == null) {
|
||||
throw new LineNotFoundException();
|
||||
}
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
private boolean isValidMethodName(String s) {
|
||||
return isJavaIdentifier(s) ||
|
||||
s.equals("<init>") ||
|
||||
s.equals("<clinit>");
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare a method's argument types with a Vector of type names.
|
||||
* Return true if each argument type has a name identical to the
|
||||
* corresponding string in the vector (allowing for varars)
|
||||
* and if the number of arguments in the method matches the
|
||||
* number of names passed
|
||||
*/
|
||||
private boolean compareArgTypes(Method method, List<String> nameList) {
|
||||
List<String> argTypeNames = method.argumentTypeNames();
|
||||
|
||||
// If argument counts differ, we can stop here
|
||||
if (argTypeNames.size() != nameList.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compare each argument type's name
|
||||
int nTypes = argTypeNames.size();
|
||||
for (int i = 0; i < nTypes; ++i) {
|
||||
String comp1 = argTypeNames.get(i);
|
||||
String comp2 = nameList.get(i);
|
||||
if (! comp1.equals(comp2)) {
|
||||
/*
|
||||
* We have to handle varargs. EG, the
|
||||
* method's last arg type is xxx[]
|
||||
* while the nameList contains xxx...
|
||||
* Note that the nameList can also contain
|
||||
* xxx[] in which case we don't get here.
|
||||
*/
|
||||
if (i != nTypes - 1 ||
|
||||
!method.isVarArgs() ||
|
||||
!comp2.endsWith("...")) {
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
* The last types differ, it is a varargs
|
||||
* method and the nameList item is varargs.
|
||||
* We just have to compare the type names, eg,
|
||||
* make sure we don't have xxx[] for the method
|
||||
* arg type and yyy... for the nameList item.
|
||||
*/
|
||||
int comp1Length = comp1.length();
|
||||
if (comp1Length + 1 != comp2.length()) {
|
||||
// The type names are different lengths
|
||||
return false;
|
||||
}
|
||||
// We know the two type names are the same length
|
||||
if (!comp1.regionMatches(0, comp2, 0, comp1Length - 2)) {
|
||||
return false;
|
||||
}
|
||||
// We do have xxx[] and xxx... as the last param type
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Remove unneeded spaces and expand class names to fully
|
||||
* qualified names, if necessary and possible.
|
||||
*/
|
||||
private String normalizeArgTypeName(String name) {
|
||||
/*
|
||||
* Separate the type name from any array modifiers,
|
||||
* stripping whitespace after the name ends
|
||||
*/
|
||||
int i = 0;
|
||||
StringBuffer typePart = new StringBuffer();
|
||||
StringBuffer arrayPart = new StringBuffer();
|
||||
name = name.trim();
|
||||
int nameLength = name.length();
|
||||
/*
|
||||
* For varargs, there can be spaces before the ... but not
|
||||
* within the ... So, we will just ignore the ...
|
||||
* while stripping blanks.
|
||||
*/
|
||||
boolean isVarArgs = name.endsWith("...");
|
||||
if (isVarArgs) {
|
||||
nameLength -= 3;
|
||||
}
|
||||
while (i < nameLength) {
|
||||
char c = name.charAt(i);
|
||||
if (Character.isWhitespace(c) || c == '[') {
|
||||
break; // name is complete
|
||||
}
|
||||
typePart.append(c);
|
||||
i++;
|
||||
}
|
||||
while (i < nameLength) {
|
||||
char c = name.charAt(i);
|
||||
if ( (c == '[') || (c == ']')) {
|
||||
arrayPart.append(c);
|
||||
} else if (!Character.isWhitespace(c)) {
|
||||
throw new IllegalArgumentException
|
||||
(MessageOutput.format("Invalid argument type name"));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
name = typePart.toString();
|
||||
|
||||
/*
|
||||
* When there's no sign of a package name already, try to expand the
|
||||
* the name to a fully qualified class name
|
||||
*/
|
||||
if ((name.indexOf('.') == -1) || name.startsWith("*.")) {
|
||||
try {
|
||||
ReferenceType argClass = Env.getReferenceTypeFromToken(name);
|
||||
if (argClass != null) {
|
||||
name = argClass.name();
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
// We'll try the name as is
|
||||
}
|
||||
}
|
||||
name += arrayPart.toString();
|
||||
if (isVarArgs) {
|
||||
name += "...";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt an unambiguous match of the method name and
|
||||
* argument specification to a method. If no arguments
|
||||
* are specified, the method must not be overloaded.
|
||||
* Otherwise, the argument types much match exactly
|
||||
*/
|
||||
private Method findMatchingMethod(ReferenceType refType)
|
||||
throws AmbiguousMethodException,
|
||||
NoSuchMethodException {
|
||||
|
||||
// Normalize the argument string once before looping below.
|
||||
List<String> argTypeNames = null;
|
||||
if (methodArgs() != null) {
|
||||
argTypeNames = new ArrayList<String>(methodArgs().size());
|
||||
for (String name : methodArgs()) {
|
||||
name = normalizeArgTypeName(name);
|
||||
argTypeNames.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
// Check each method in the class for matches
|
||||
Method firstMatch = null; // first method with matching name
|
||||
Method exactMatch = null; // (only) method with same name & sig
|
||||
int matchCount = 0; // > 1 implies overload
|
||||
for (Method candidate : refType.methods()) {
|
||||
if (candidate.name().equals(methodName())) {
|
||||
matchCount++;
|
||||
|
||||
// Remember the first match in case it is the only one
|
||||
if (matchCount == 1) {
|
||||
firstMatch = candidate;
|
||||
}
|
||||
|
||||
// If argument types were specified, check against candidate
|
||||
if ((argTypeNames != null)
|
||||
&& compareArgTypes(candidate, argTypeNames) == true) {
|
||||
exactMatch = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Determine method for breakpoint
|
||||
Method method = null;
|
||||
if (exactMatch != null) {
|
||||
// Name and signature match
|
||||
method = exactMatch;
|
||||
} else if ((argTypeNames == null) && (matchCount > 0)) {
|
||||
// At least one name matched and no arg types were specified
|
||||
if (matchCount == 1) {
|
||||
method = firstMatch; // Only one match; safe to use it
|
||||
} else {
|
||||
throw new AmbiguousMethodException();
|
||||
}
|
||||
} else {
|
||||
throw new NoSuchMethodException(methodName());
|
||||
}
|
||||
return method;
|
||||
}
|
||||
}
|
||||
2107
jdkSrc/jdk8/com/sun/tools/example/debug/tty/Commands.java
Normal file
2107
jdkSrc/jdk8/com/sun/tools/example/debug/tty/Commands.java
Normal file
File diff suppressed because it is too large
Load Diff
331
jdkSrc/jdk8/com/sun/tools/example/debug/tty/Env.java
Normal file
331
jdkSrc/jdk8/com/sun/tools/example/debug/tty/Env.java
Normal file
@@ -0,0 +1,331 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is provided to illustrate the usage of a given feature
|
||||
* or technique and has been deliberately simplified. Additional steps
|
||||
* required for a production-quality application, such as security checks,
|
||||
* input validation and proper error handling, might not be present in
|
||||
* this sample code.
|
||||
*/
|
||||
|
||||
|
||||
package com.sun.tools.example.debug.tty;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.request.StepRequest;
|
||||
import com.sun.jdi.request.MethodEntryRequest;
|
||||
import com.sun.jdi.request.MethodExitRequest;
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
|
||||
class Env {
|
||||
|
||||
static EventRequestSpecList specList = new EventRequestSpecList();
|
||||
|
||||
private static VMConnection connection;
|
||||
|
||||
private static SourceMapper sourceMapper = new SourceMapper("");
|
||||
private static List<String> excludes;
|
||||
|
||||
private static final int SOURCE_CACHE_SIZE = 5;
|
||||
private static List<SourceCode> sourceCache = new LinkedList<SourceCode>();
|
||||
|
||||
private static HashMap<String, Value> savedValues = new HashMap<String, Value>();
|
||||
private static Method atExitMethod;
|
||||
|
||||
static void init(String connectSpec, boolean openNow, int flags) {
|
||||
connection = new VMConnection(connectSpec, flags);
|
||||
if (!connection.isLaunch() || openNow) {
|
||||
connection.open();
|
||||
}
|
||||
}
|
||||
|
||||
static VMConnection connection() {
|
||||
return connection;
|
||||
}
|
||||
|
||||
static VirtualMachine vm() {
|
||||
return connection.vm();
|
||||
}
|
||||
|
||||
static void shutdown() {
|
||||
shutdown(null);
|
||||
}
|
||||
|
||||
static void shutdown(String message) {
|
||||
if (connection != null) {
|
||||
try {
|
||||
connection.disposeVM();
|
||||
} catch (VMDisconnectedException e) {
|
||||
// Shutting down after the VM has gone away. This is
|
||||
// not an error, and we just ignore it.
|
||||
}
|
||||
}
|
||||
if (message != null) {
|
||||
MessageOutput.lnprint(message);
|
||||
MessageOutput.println();
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
static void setSourcePath(String srcPath) {
|
||||
sourceMapper = new SourceMapper(srcPath);
|
||||
sourceCache.clear();
|
||||
}
|
||||
|
||||
static void setSourcePath(List<String> srcList) {
|
||||
sourceMapper = new SourceMapper(srcList);
|
||||
sourceCache.clear();
|
||||
}
|
||||
|
||||
static String getSourcePath() {
|
||||
return sourceMapper.getSourcePath();
|
||||
}
|
||||
|
||||
static private List<String> excludes() {
|
||||
if (excludes == null) {
|
||||
setExcludes("java.*, javax.*, sun.*, com.sun.*");
|
||||
}
|
||||
return excludes;
|
||||
}
|
||||
|
||||
static String excludesString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
for (String pattern : excludes()) {
|
||||
buffer.append(pattern);
|
||||
buffer.append(",");
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
static void addExcludes(StepRequest request) {
|
||||
for (String pattern : excludes()) {
|
||||
request.addClassExclusionFilter(pattern);
|
||||
}
|
||||
}
|
||||
|
||||
static void addExcludes(MethodEntryRequest request) {
|
||||
for (String pattern : excludes()) {
|
||||
request.addClassExclusionFilter(pattern);
|
||||
}
|
||||
}
|
||||
|
||||
static void addExcludes(MethodExitRequest request) {
|
||||
for (String pattern : excludes()) {
|
||||
request.addClassExclusionFilter(pattern);
|
||||
}
|
||||
}
|
||||
|
||||
static void setExcludes(String excludeString) {
|
||||
StringTokenizer t = new StringTokenizer(excludeString, " ,;");
|
||||
List<String> list = new ArrayList<String>();
|
||||
while (t.hasMoreTokens()) {
|
||||
list.add(t.nextToken());
|
||||
}
|
||||
excludes = list;
|
||||
}
|
||||
|
||||
static Method atExitMethod() {
|
||||
return atExitMethod;
|
||||
}
|
||||
|
||||
static void setAtExitMethod(Method mmm) {
|
||||
atExitMethod = mmm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a Reader cooresponding to the source of this location.
|
||||
* Return null if not available.
|
||||
* Note: returned reader must be closed.
|
||||
*/
|
||||
static BufferedReader sourceReader(Location location) {
|
||||
return sourceMapper.sourceReader(location);
|
||||
}
|
||||
|
||||
static synchronized String sourceLine(Location location, int lineNumber)
|
||||
throws IOException {
|
||||
if (lineNumber == -1) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
try {
|
||||
String fileName = location.sourceName();
|
||||
|
||||
Iterator<SourceCode> iter = sourceCache.iterator();
|
||||
SourceCode code = null;
|
||||
while (iter.hasNext()) {
|
||||
SourceCode candidate = iter.next();
|
||||
if (candidate.fileName().equals(fileName)) {
|
||||
code = candidate;
|
||||
iter.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (code == null) {
|
||||
BufferedReader reader = sourceReader(location);
|
||||
if (reader == null) {
|
||||
throw new FileNotFoundException(fileName);
|
||||
}
|
||||
code = new SourceCode(fileName, reader);
|
||||
if (sourceCache.size() == SOURCE_CACHE_SIZE) {
|
||||
sourceCache.remove(sourceCache.size() - 1);
|
||||
}
|
||||
}
|
||||
sourceCache.add(0, code);
|
||||
return code.sourceLine(lineNumber);
|
||||
} catch (AbsentInformationException e) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
/** Return a description of an object. */
|
||||
static String description(ObjectReference ref) {
|
||||
ReferenceType clazz = ref.referenceType();
|
||||
long id = ref.uniqueID();
|
||||
if (clazz == null) {
|
||||
return toHex(id);
|
||||
} else {
|
||||
return MessageOutput.format("object description and hex id",
|
||||
new Object [] {clazz.name(),
|
||||
toHex(id)});
|
||||
}
|
||||
}
|
||||
|
||||
/** Convert a long to a hexadecimal string. */
|
||||
static String toHex(long n) {
|
||||
char s1[] = new char[16];
|
||||
char s2[] = new char[18];
|
||||
|
||||
/* Store digits in reverse order. */
|
||||
int i = 0;
|
||||
do {
|
||||
long d = n & 0xf;
|
||||
s1[i++] = (char)((d < 10) ? ('0' + d) : ('a' + d - 10));
|
||||
} while ((n >>>= 4) > 0);
|
||||
|
||||
/* Now reverse the array. */
|
||||
s2[0] = '0';
|
||||
s2[1] = 'x';
|
||||
int j = 2;
|
||||
while (--i >= 0) {
|
||||
s2[j++] = s1[i];
|
||||
}
|
||||
return new String(s2, 0, j);
|
||||
}
|
||||
|
||||
/** Convert hexadecimal strings to longs. */
|
||||
static long fromHex(String hexStr) {
|
||||
String str = hexStr.startsWith("0x") ?
|
||||
hexStr.substring(2).toLowerCase() : hexStr.toLowerCase();
|
||||
if (hexStr.length() == 0) {
|
||||
throw new NumberFormatException();
|
||||
}
|
||||
|
||||
long ret = 0;
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
int c = str.charAt(i);
|
||||
if (c >= '0' && c <= '9') {
|
||||
ret = (ret * 16) + (c - '0');
|
||||
} else if (c >= 'a' && c <= 'f') {
|
||||
ret = (ret * 16) + (c - 'a' + 10);
|
||||
} else {
|
||||
throw new NumberFormatException();
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ReferenceType getReferenceTypeFromToken(String idToken) {
|
||||
ReferenceType cls = null;
|
||||
if (Character.isDigit(idToken.charAt(0))) {
|
||||
cls = null;
|
||||
} else if (idToken.startsWith("*.")) {
|
||||
// This notation saves typing by letting the user omit leading
|
||||
// package names. The first
|
||||
// loaded class whose name matches this limited regular
|
||||
// expression is selected.
|
||||
idToken = idToken.substring(1);
|
||||
for (ReferenceType type : Env.vm().allClasses()) {
|
||||
if (type.name().endsWith(idToken)) {
|
||||
cls = type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// It's a class name
|
||||
List<ReferenceType> classes = Env.vm().classesByName(idToken);
|
||||
if (classes.size() > 0) {
|
||||
// TO DO: handle multiples
|
||||
cls = classes.get(0);
|
||||
}
|
||||
}
|
||||
return cls;
|
||||
}
|
||||
|
||||
static Set<String> getSaveKeys() {
|
||||
return savedValues.keySet();
|
||||
}
|
||||
|
||||
static Value getSavedValue(String key) {
|
||||
return savedValues.get(key);
|
||||
}
|
||||
|
||||
static void setSavedValue(String key, Value value) {
|
||||
savedValues.put(key, value);
|
||||
}
|
||||
|
||||
static class SourceCode {
|
||||
private String fileName;
|
||||
private List<String> sourceLines = new ArrayList<String>();
|
||||
|
||||
SourceCode(String fileName, BufferedReader reader) throws IOException {
|
||||
this.fileName = fileName;
|
||||
try {
|
||||
String line = reader.readLine();
|
||||
while (line != null) {
|
||||
sourceLines.add(line);
|
||||
line = reader.readLine();
|
||||
}
|
||||
} finally {
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
|
||||
String fileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
String sourceLine(int number) {
|
||||
int index = number - 1; // list is 0-indexed
|
||||
if (index >= sourceLines.size()) {
|
||||
return null;
|
||||
} else {
|
||||
return sourceLines.get(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
290
jdkSrc/jdk8/com/sun/tools/example/debug/tty/EventHandler.java
Normal file
290
jdkSrc/jdk8/com/sun/tools/example/debug/tty/EventHandler.java
Normal file
@@ -0,0 +1,290 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is provided to illustrate the usage of a given feature
|
||||
* or technique and has been deliberately simplified. Additional steps
|
||||
* required for a production-quality application, such as security checks,
|
||||
* input validation and proper error handling, might not be present in
|
||||
* this sample code.
|
||||
*/
|
||||
|
||||
|
||||
package com.sun.tools.example.debug.tty;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.event.*;
|
||||
import com.sun.jdi.request.EventRequest;
|
||||
|
||||
public class EventHandler implements Runnable {
|
||||
|
||||
EventNotifier notifier;
|
||||
Thread thread;
|
||||
volatile boolean connected = true;
|
||||
boolean completed = false;
|
||||
String shutdownMessageKey;
|
||||
boolean stopOnVMStart;
|
||||
|
||||
EventHandler(EventNotifier notifier, boolean stopOnVMStart) {
|
||||
this.notifier = notifier;
|
||||
this.stopOnVMStart = stopOnVMStart;
|
||||
this.thread = new Thread(this, "event-handler");
|
||||
this.thread.start();
|
||||
}
|
||||
|
||||
synchronized void shutdown() {
|
||||
connected = false; // force run() loop termination
|
||||
thread.interrupt();
|
||||
while (!completed) {
|
||||
try {wait();} catch (InterruptedException exc) {}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
EventQueue queue = Env.vm().eventQueue();
|
||||
while (connected) {
|
||||
try {
|
||||
EventSet eventSet = queue.remove();
|
||||
boolean resumeStoppedApp = false;
|
||||
EventIterator it = eventSet.eventIterator();
|
||||
while (it.hasNext()) {
|
||||
resumeStoppedApp |= !handleEvent(it.nextEvent());
|
||||
}
|
||||
|
||||
if (resumeStoppedApp) {
|
||||
eventSet.resume();
|
||||
} else if (eventSet.suspendPolicy() == EventRequest.SUSPEND_ALL) {
|
||||
setCurrentThread(eventSet);
|
||||
notifier.vmInterrupted();
|
||||
}
|
||||
} catch (InterruptedException exc) {
|
||||
// Do nothing. Any changes will be seen at top of loop.
|
||||
} catch (VMDisconnectedException discExc) {
|
||||
handleDisconnectedException();
|
||||
break;
|
||||
}
|
||||
}
|
||||
synchronized (this) {
|
||||
completed = true;
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean handleEvent(Event event) {
|
||||
notifier.receivedEvent(event);
|
||||
|
||||
if (event instanceof ExceptionEvent) {
|
||||
return exceptionEvent(event);
|
||||
} else if (event instanceof BreakpointEvent) {
|
||||
return breakpointEvent(event);
|
||||
} else if (event instanceof WatchpointEvent) {
|
||||
return fieldWatchEvent(event);
|
||||
} else if (event instanceof StepEvent) {
|
||||
return stepEvent(event);
|
||||
} else if (event instanceof MethodEntryEvent) {
|
||||
return methodEntryEvent(event);
|
||||
} else if (event instanceof MethodExitEvent) {
|
||||
return methodExitEvent(event);
|
||||
} else if (event instanceof ClassPrepareEvent) {
|
||||
return classPrepareEvent(event);
|
||||
} else if (event instanceof ClassUnloadEvent) {
|
||||
return classUnloadEvent(event);
|
||||
} else if (event instanceof ThreadStartEvent) {
|
||||
return threadStartEvent(event);
|
||||
} else if (event instanceof ThreadDeathEvent) {
|
||||
return threadDeathEvent(event);
|
||||
} else if (event instanceof VMStartEvent) {
|
||||
return vmStartEvent(event);
|
||||
} else {
|
||||
return handleExitEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean vmDied = false;
|
||||
private boolean handleExitEvent(Event event) {
|
||||
if (event instanceof VMDeathEvent) {
|
||||
vmDied = true;
|
||||
return vmDeathEvent(event);
|
||||
} else if (event instanceof VMDisconnectEvent) {
|
||||
connected = false;
|
||||
if (!vmDied) {
|
||||
vmDisconnectEvent(event);
|
||||
}
|
||||
/*
|
||||
* Inform jdb command line processor that jdb is being shutdown. JDK-8154144.
|
||||
*/
|
||||
((TTY)notifier).setShuttingDown(true);
|
||||
Env.shutdown(shutdownMessageKey);
|
||||
return false;
|
||||
} else {
|
||||
throw new InternalError(MessageOutput.format("Unexpected event type",
|
||||
new Object[] {event.getClass()}));
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void handleDisconnectedException() {
|
||||
/*
|
||||
* A VMDisconnectedException has happened while dealing with
|
||||
* another event. We need to flush the event queue, dealing only
|
||||
* with exit events (VMDeath, VMDisconnect) so that we terminate
|
||||
* correctly.
|
||||
*/
|
||||
EventQueue queue = Env.vm().eventQueue();
|
||||
while (connected) {
|
||||
try {
|
||||
EventSet eventSet = queue.remove();
|
||||
EventIterator iter = eventSet.eventIterator();
|
||||
while (iter.hasNext()) {
|
||||
handleExitEvent(iter.next());
|
||||
}
|
||||
} catch (InterruptedException exc) {
|
||||
// ignore
|
||||
} catch (InternalError exc) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ThreadReference eventThread(Event event) {
|
||||
if (event instanceof ClassPrepareEvent) {
|
||||
return ((ClassPrepareEvent)event).thread();
|
||||
} else if (event instanceof LocatableEvent) {
|
||||
return ((LocatableEvent)event).thread();
|
||||
} else if (event instanceof ThreadStartEvent) {
|
||||
return ((ThreadStartEvent)event).thread();
|
||||
} else if (event instanceof ThreadDeathEvent) {
|
||||
return ((ThreadDeathEvent)event).thread();
|
||||
} else if (event instanceof VMStartEvent) {
|
||||
return ((VMStartEvent)event).thread();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void setCurrentThread(EventSet set) {
|
||||
ThreadReference thread;
|
||||
if (set.size() > 0) {
|
||||
/*
|
||||
* If any event in the set has a thread associated with it,
|
||||
* they all will, so just grab the first one.
|
||||
*/
|
||||
Event event = set.iterator().next(); // Is there a better way?
|
||||
thread = eventThread(event);
|
||||
} else {
|
||||
thread = null;
|
||||
}
|
||||
setCurrentThread(thread);
|
||||
}
|
||||
|
||||
private void setCurrentThread(ThreadReference thread) {
|
||||
ThreadInfo.invalidateAll();
|
||||
ThreadInfo.setCurrentThread(thread);
|
||||
}
|
||||
|
||||
private boolean vmStartEvent(Event event) {
|
||||
VMStartEvent se = (VMStartEvent)event;
|
||||
notifier.vmStartEvent(se);
|
||||
return stopOnVMStart;
|
||||
}
|
||||
|
||||
private boolean breakpointEvent(Event event) {
|
||||
BreakpointEvent be = (BreakpointEvent)event;
|
||||
notifier.breakpointEvent(be);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean methodEntryEvent(Event event) {
|
||||
MethodEntryEvent me = (MethodEntryEvent)event;
|
||||
notifier.methodEntryEvent(me);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean methodExitEvent(Event event) {
|
||||
MethodExitEvent me = (MethodExitEvent)event;
|
||||
return notifier.methodExitEvent(me);
|
||||
}
|
||||
|
||||
private boolean fieldWatchEvent(Event event) {
|
||||
WatchpointEvent fwe = (WatchpointEvent)event;
|
||||
notifier.fieldWatchEvent(fwe);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean stepEvent(Event event) {
|
||||
StepEvent se = (StepEvent)event;
|
||||
notifier.stepEvent(se);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean classPrepareEvent(Event event) {
|
||||
ClassPrepareEvent cle = (ClassPrepareEvent)event;
|
||||
notifier.classPrepareEvent(cle);
|
||||
|
||||
if (!Env.specList.resolve(cle)) {
|
||||
MessageOutput.lnprint("Stopping due to deferred breakpoint errors.");
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean classUnloadEvent(Event event) {
|
||||
ClassUnloadEvent cue = (ClassUnloadEvent)event;
|
||||
notifier.classUnloadEvent(cue);
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean exceptionEvent(Event event) {
|
||||
ExceptionEvent ee = (ExceptionEvent)event;
|
||||
notifier.exceptionEvent(ee);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean threadDeathEvent(Event event) {
|
||||
ThreadDeathEvent tee = (ThreadDeathEvent)event;
|
||||
ThreadInfo.removeThread(tee.thread());
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean threadStartEvent(Event event) {
|
||||
ThreadStartEvent tse = (ThreadStartEvent)event;
|
||||
ThreadInfo.addThread(tse.thread());
|
||||
notifier.threadStartEvent(tse);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean vmDeathEvent(Event event) {
|
||||
shutdownMessageKey = "The application exited";
|
||||
notifier.vmDeathEvent((VMDeathEvent)event);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean vmDisconnectEvent(Event event) {
|
||||
shutdownMessageKey = "The application has been disconnected";
|
||||
notifier.vmDisconnectEvent((VMDisconnectEvent)event);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is provided to illustrate the usage of a given feature
|
||||
* or technique and has been deliberately simplified. Additional steps
|
||||
* required for a production-quality application, such as security checks,
|
||||
* input validation and proper error handling, might not be present in
|
||||
* this sample code.
|
||||
*/
|
||||
|
||||
|
||||
package com.sun.tools.example.debug.tty;
|
||||
|
||||
import com.sun.jdi.event.*;
|
||||
|
||||
interface EventNotifier {
|
||||
void vmStartEvent(VMStartEvent e);
|
||||
void vmDeathEvent(VMDeathEvent e);
|
||||
void vmDisconnectEvent(VMDisconnectEvent e);
|
||||
|
||||
void threadStartEvent(ThreadStartEvent e);
|
||||
void threadDeathEvent(ThreadDeathEvent e);
|
||||
|
||||
void classPrepareEvent(ClassPrepareEvent e);
|
||||
void classUnloadEvent(ClassUnloadEvent e);
|
||||
|
||||
void breakpointEvent(BreakpointEvent e);
|
||||
void fieldWatchEvent(WatchpointEvent e);
|
||||
void stepEvent(StepEvent e);
|
||||
void exceptionEvent(ExceptionEvent e);
|
||||
void methodEntryEvent(MethodEntryEvent e);
|
||||
boolean methodExitEvent(MethodExitEvent e);
|
||||
|
||||
void vmInterrupted();
|
||||
void receivedEvent(Event event);
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is provided to illustrate the usage of a given feature
|
||||
* or technique and has been deliberately simplified. Additional steps
|
||||
* required for a production-quality application, such as security checks,
|
||||
* input validation and proper error handling, might not be present in
|
||||
* this sample code.
|
||||
*/
|
||||
|
||||
|
||||
package com.sun.tools.example.debug.tty;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.request.EventRequest;
|
||||
import com.sun.jdi.request.ExceptionRequest;
|
||||
import com.sun.jdi.request.ClassPrepareRequest;
|
||||
import com.sun.jdi.event.ClassPrepareEvent;
|
||||
import java.util.ArrayList;
|
||||
|
||||
abstract class EventRequestSpec {
|
||||
|
||||
final ReferenceTypeSpec refSpec;
|
||||
|
||||
int suspendPolicy = EventRequest.SUSPEND_ALL;
|
||||
|
||||
EventRequest resolved = null;
|
||||
ClassPrepareRequest prepareRequest = null;
|
||||
|
||||
EventRequestSpec(ReferenceTypeSpec refSpec) {
|
||||
this.refSpec = refSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* The 'refType' is known to match, return the EventRequest.
|
||||
*/
|
||||
abstract EventRequest resolveEventRequest(ReferenceType refType)
|
||||
throws Exception;
|
||||
|
||||
/**
|
||||
* @return If this EventRequestSpec matches the 'refType'
|
||||
* return the cooresponding EventRequest. Otherwise
|
||||
* return null.
|
||||
*/
|
||||
synchronized EventRequest resolve(ClassPrepareEvent event) throws Exception {
|
||||
if ((resolved == null) &&
|
||||
(prepareRequest != null) &&
|
||||
prepareRequest.equals(event.request())) {
|
||||
|
||||
resolved = resolveEventRequest(event.referenceType());
|
||||
prepareRequest.disable();
|
||||
Env.vm().eventRequestManager().deleteEventRequest(prepareRequest);
|
||||
prepareRequest = null;
|
||||
|
||||
if (refSpec instanceof PatternReferenceTypeSpec) {
|
||||
PatternReferenceTypeSpec prs = (PatternReferenceTypeSpec)refSpec;
|
||||
if (! prs.isUnique()){
|
||||
/*
|
||||
* Class pattern event requests are never
|
||||
* considered "resolved", since future class loads
|
||||
* might also match.
|
||||
* Create and enable a new ClassPrepareRequest to
|
||||
* keep trying to resolve.
|
||||
*/
|
||||
resolved = null;
|
||||
prepareRequest = refSpec.createPrepareRequest();
|
||||
prepareRequest.enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
|
||||
synchronized void remove() {
|
||||
if (isResolved()) {
|
||||
Env.vm().eventRequestManager().deleteEventRequest(resolved());
|
||||
}
|
||||
if (refSpec instanceof PatternReferenceTypeSpec) {
|
||||
PatternReferenceTypeSpec prs = (PatternReferenceTypeSpec)refSpec;
|
||||
if (! prs.isUnique()){
|
||||
/*
|
||||
* This is a class pattern. Track down and delete
|
||||
* all EventRequests matching this spec.
|
||||
* Note: Class patterns apply only to ExceptionRequests,
|
||||
* so that is all we need to examine.
|
||||
*/
|
||||
ArrayList<ExceptionRequest> deleteList = new ArrayList<ExceptionRequest>();
|
||||
for (ExceptionRequest er :
|
||||
Env.vm().eventRequestManager().exceptionRequests()) {
|
||||
if (prs.matches(er.exception())) {
|
||||
deleteList.add (er);
|
||||
}
|
||||
}
|
||||
Env.vm().eventRequestManager().deleteEventRequests(deleteList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private EventRequest resolveAgainstPreparedClasses() throws Exception {
|
||||
for (ReferenceType refType : Env.vm().allClasses()) {
|
||||
if (refType.isPrepared() && refSpec.matches(refType)) {
|
||||
resolved = resolveEventRequest(refType);
|
||||
}
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
|
||||
synchronized EventRequest resolveEagerly() throws Exception {
|
||||
try {
|
||||
if (resolved == null) {
|
||||
/*
|
||||
* Not resolved. Schedule a prepare request so we
|
||||
* can resolve later.
|
||||
*/
|
||||
prepareRequest = refSpec.createPrepareRequest();
|
||||
prepareRequest.enable();
|
||||
|
||||
// Try to resolve in case the class is already loaded.
|
||||
resolveAgainstPreparedClasses();
|
||||
if (resolved != null) {
|
||||
prepareRequest.disable();
|
||||
Env.vm().eventRequestManager().deleteEventRequest(prepareRequest);
|
||||
prepareRequest = null;
|
||||
}
|
||||
}
|
||||
if (refSpec instanceof PatternReferenceTypeSpec) {
|
||||
PatternReferenceTypeSpec prs = (PatternReferenceTypeSpec)refSpec;
|
||||
if (! prs.isUnique()){
|
||||
/*
|
||||
* Class pattern event requests are never
|
||||
* considered "resolved", since future class loads
|
||||
* might also match. Create a new
|
||||
* ClassPrepareRequest if necessary and keep
|
||||
* trying to resolve.
|
||||
*/
|
||||
resolved = null;
|
||||
if (prepareRequest == null) {
|
||||
prepareRequest = refSpec.createPrepareRequest();
|
||||
prepareRequest.enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (VMNotConnectedException e) {
|
||||
// Do nothing. Another resolve will be attempted when the
|
||||
// VM is started.
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the eventRequest this spec has been resolved to,
|
||||
* null if so far unresolved.
|
||||
*/
|
||||
EventRequest resolved() {
|
||||
return resolved;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this spec has been resolved.
|
||||
*/
|
||||
boolean isResolved() {
|
||||
return resolved != null;
|
||||
}
|
||||
|
||||
protected boolean isJavaIdentifier(String s) {
|
||||
if (s.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int cp = s.codePointAt(0);
|
||||
if (! Character.isJavaIdentifierStart(cp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = Character.charCount(cp); i < s.length(); i += Character.charCount(cp)) {
|
||||
cp = s.codePointAt(i);
|
||||
if (! Character.isJavaIdentifierPart(cp)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
String errorMessageFor(Exception e) {
|
||||
if (e instanceof IllegalArgumentException) {
|
||||
return (MessageOutput.format("Invalid command syntax"));
|
||||
} else if (e instanceof RuntimeException) {
|
||||
// A runtime exception that we were not expecting
|
||||
throw (RuntimeException)e;
|
||||
} else {
|
||||
return (MessageOutput.format("Internal error; unable to set",
|
||||
this.refSpec.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is provided to illustrate the usage of a given feature
|
||||
* or technique and has been deliberately simplified. Additional steps
|
||||
* required for a production-quality application, such as security checks,
|
||||
* input validation and proper error handling, might not be present in
|
||||
* this sample code.
|
||||
*/
|
||||
|
||||
|
||||
package com.sun.tools.example.debug.tty;
|
||||
|
||||
import com.sun.jdi.request.EventRequest;
|
||||
import com.sun.jdi.event.ClassPrepareEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
class EventRequestSpecList {
|
||||
|
||||
private static final int statusResolved = 1;
|
||||
private static final int statusUnresolved = 2;
|
||||
private static final int statusError = 3;
|
||||
|
||||
// all specs
|
||||
private List<EventRequestSpec> eventRequestSpecs = Collections.synchronizedList(
|
||||
new ArrayList<EventRequestSpec>());
|
||||
|
||||
EventRequestSpecList() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve all deferred eventRequests waiting for 'refType'.
|
||||
* @return true if it completes successfully, false on error.
|
||||
*/
|
||||
boolean resolve(ClassPrepareEvent event) {
|
||||
boolean failure = false;
|
||||
synchronized(eventRequestSpecs) {
|
||||
for (EventRequestSpec spec : eventRequestSpecs) {
|
||||
if (!spec.isResolved()) {
|
||||
try {
|
||||
EventRequest eventRequest = spec.resolve(event);
|
||||
if (eventRequest != null) {
|
||||
MessageOutput.println("Set deferred", spec.toString());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
MessageOutput.println("Unable to set deferred",
|
||||
new Object [] {spec.toString(),
|
||||
spec.errorMessageFor(e)});
|
||||
failure = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return !failure;
|
||||
}
|
||||
|
||||
void resolveAll() {
|
||||
for (EventRequestSpec spec : eventRequestSpecs) {
|
||||
try {
|
||||
EventRequest eventRequest = spec.resolveEagerly();
|
||||
if (eventRequest != null) {
|
||||
MessageOutput.println("Set deferred", spec.toString());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean addEagerlyResolve(EventRequestSpec spec) {
|
||||
try {
|
||||
eventRequestSpecs.add(spec);
|
||||
EventRequest eventRequest = spec.resolveEagerly();
|
||||
if (eventRequest != null) {
|
||||
MessageOutput.println("Set", spec.toString());
|
||||
}
|
||||
return true;
|
||||
} catch (Exception exc) {
|
||||
MessageOutput.println("Unable to set",
|
||||
new Object [] {spec.toString(),
|
||||
spec.errorMessageFor(exc)});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
BreakpointSpec createBreakpoint(String classPattern, int line)
|
||||
throws ClassNotFoundException {
|
||||
ReferenceTypeSpec refSpec =
|
||||
new PatternReferenceTypeSpec(classPattern);
|
||||
return new BreakpointSpec(refSpec, line);
|
||||
}
|
||||
|
||||
BreakpointSpec createBreakpoint(String classPattern,
|
||||
String methodId,
|
||||
List<String> methodArgs)
|
||||
throws MalformedMemberNameException,
|
||||
ClassNotFoundException {
|
||||
ReferenceTypeSpec refSpec =
|
||||
new PatternReferenceTypeSpec(classPattern);
|
||||
return new BreakpointSpec(refSpec, methodId, methodArgs);
|
||||
}
|
||||
|
||||
EventRequestSpec createExceptionCatch(String classPattern,
|
||||
boolean notifyCaught,
|
||||
boolean notifyUncaught)
|
||||
throws ClassNotFoundException {
|
||||
ReferenceTypeSpec refSpec =
|
||||
new PatternReferenceTypeSpec(classPattern);
|
||||
return new ExceptionSpec(refSpec, notifyCaught, notifyUncaught);
|
||||
}
|
||||
|
||||
WatchpointSpec createAccessWatchpoint(String classPattern,
|
||||
String fieldId)
|
||||
throws MalformedMemberNameException,
|
||||
ClassNotFoundException {
|
||||
ReferenceTypeSpec refSpec =
|
||||
new PatternReferenceTypeSpec(classPattern);
|
||||
return new AccessWatchpointSpec(refSpec, fieldId);
|
||||
}
|
||||
|
||||
WatchpointSpec createModificationWatchpoint(String classPattern,
|
||||
String fieldId)
|
||||
throws MalformedMemberNameException,
|
||||
ClassNotFoundException {
|
||||
ReferenceTypeSpec refSpec =
|
||||
new PatternReferenceTypeSpec(classPattern);
|
||||
return new ModificationWatchpointSpec(refSpec, fieldId);
|
||||
}
|
||||
|
||||
boolean delete(EventRequestSpec proto) {
|
||||
synchronized (eventRequestSpecs) {
|
||||
int inx = eventRequestSpecs.indexOf(proto);
|
||||
if (inx != -1) {
|
||||
EventRequestSpec spec = eventRequestSpecs.get(inx);
|
||||
spec.remove();
|
||||
eventRequestSpecs.remove(inx);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<EventRequestSpec> eventRequestSpecs() {
|
||||
// We need to make a copy to avoid synchronization problems
|
||||
synchronized (eventRequestSpecs) {
|
||||
return new ArrayList<EventRequestSpec>(eventRequestSpecs);
|
||||
}
|
||||
}
|
||||
}
|
||||
116
jdkSrc/jdk8/com/sun/tools/example/debug/tty/ExceptionSpec.java
Normal file
116
jdkSrc/jdk8/com/sun/tools/example/debug/tty/ExceptionSpec.java
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is provided to illustrate the usage of a given feature
|
||||
* or technique and has been deliberately simplified. Additional steps
|
||||
* required for a production-quality application, such as security checks,
|
||||
* input validation and proper error handling, might not be present in
|
||||
* this sample code.
|
||||
*/
|
||||
|
||||
|
||||
package com.sun.tools.example.debug.tty;
|
||||
|
||||
import com.sun.jdi.ReferenceType;
|
||||
import com.sun.jdi.request.*;
|
||||
|
||||
class ExceptionSpec extends EventRequestSpec {
|
||||
private boolean notifyCaught;
|
||||
private boolean notifyUncaught;
|
||||
|
||||
private ExceptionSpec(ReferenceTypeSpec refSpec) {
|
||||
this(refSpec, true, true);
|
||||
}
|
||||
|
||||
ExceptionSpec(ReferenceTypeSpec refSpec,
|
||||
boolean notifyCaught,
|
||||
boolean notifyUncaught) {
|
||||
super(refSpec);
|
||||
this.notifyCaught = notifyCaught;
|
||||
this.notifyUncaught = notifyUncaught;
|
||||
}
|
||||
|
||||
/**
|
||||
* The 'refType' is known to match, return the EventRequest.
|
||||
*/
|
||||
@Override
|
||||
EventRequest resolveEventRequest(ReferenceType refType) {
|
||||
EventRequestManager em = refType.virtualMachine().eventRequestManager();
|
||||
ExceptionRequest excReq = em.createExceptionRequest(refType,
|
||||
notifyCaught,
|
||||
notifyUncaught);
|
||||
excReq.enable();
|
||||
return excReq;
|
||||
}
|
||||
|
||||
public boolean notifyCaught() {
|
||||
return notifyCaught;
|
||||
}
|
||||
|
||||
public boolean notifyUncaught() {
|
||||
return notifyUncaught;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
//Reference: Effective Java[tm] (Bloch, 2001), Item 8
|
||||
int result = 17;
|
||||
result = (37 * result) + (notifyCaught() ? 0: 1);
|
||||
result = (37 * result) + (notifyUncaught() ? 0: 1);
|
||||
result = (37 * result) + refSpec.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof ExceptionSpec) {
|
||||
ExceptionSpec es = (ExceptionSpec)obj;
|
||||
|
||||
if (refSpec.equals(es.refSpec) &&
|
||||
(this.notifyCaught() == es.notifyCaught()) &&
|
||||
(this.notifyUncaught() == es.notifyUncaught())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String s;
|
||||
if (notifyCaught && !notifyUncaught) {
|
||||
s = MessageOutput.format("exceptionSpec caught",
|
||||
refSpec.toString());
|
||||
} else if (notifyUncaught && !notifyCaught) {
|
||||
s = MessageOutput.format("exceptionSpec uncaught",
|
||||
refSpec.toString());
|
||||
} else {
|
||||
s = MessageOutput.format("exceptionSpec all",
|
||||
refSpec.toString());
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is provided to illustrate the usage of a given feature
|
||||
* or technique and has been deliberately simplified. Additional steps
|
||||
* required for a production-quality application, such as security checks,
|
||||
* input validation and proper error handling, might not be present in
|
||||
* this sample code.
|
||||
*/
|
||||
|
||||
|
||||
package com.sun.tools.example.debug.tty;
|
||||
|
||||
public class LineNotFoundException extends Exception
|
||||
{
|
||||
private static final long serialVersionUID = 3748297722519448995L;
|
||||
|
||||
public LineNotFoundException()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public LineNotFoundException(String s)
|
||||
{
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is provided to illustrate the usage of a given feature
|
||||
* or technique and has been deliberately simplified. Additional steps
|
||||
* required for a production-quality application, such as security checks,
|
||||
* input validation and proper error handling, might not be present in
|
||||
* this sample code.
|
||||
*/
|
||||
|
||||
|
||||
package com.sun.tools.example.debug.tty;
|
||||
|
||||
class MalformedMemberNameException extends Exception {
|
||||
private static final long serialVersionUID = 7759071468833196630L;
|
||||
|
||||
public MalformedMemberNameException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public MalformedMemberNameException(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
205
jdkSrc/jdk8/com/sun/tools/example/debug/tty/MessageOutput.java
Normal file
205
jdkSrc/jdk8/com/sun/tools/example/debug/tty/MessageOutput.java
Normal file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is provided to illustrate the usage of a given feature
|
||||
* or technique and has been deliberately simplified. Additional steps
|
||||
* required for a production-quality application, such as security checks,
|
||||
* input validation and proper error handling, might not be present in
|
||||
* this sample code.
|
||||
*/
|
||||
|
||||
package com.sun.tools.example.debug.tty;
|
||||
|
||||
import java.util.*;
|
||||
import java.text.MessageFormat;
|
||||
/**
|
||||
* Internationalization (i18n) convenience methods for jdb.
|
||||
*
|
||||
* All program output should flow through these methods, and this is
|
||||
* the only class that should be printing directly or otherwise
|
||||
* accessing System.[out,err].
|
||||
*
|
||||
* @bug 4348376
|
||||
* @author Tim Bell
|
||||
*/
|
||||
public class MessageOutput {
|
||||
/**
|
||||
* The resource bundle containing localizable message content.
|
||||
* This is loaded by TTY.main() at start-up
|
||||
*/
|
||||
static ResourceBundle textResources;
|
||||
|
||||
/** Our message formatter. Allocated once, used many times */
|
||||
private static MessageFormat messageFormat;
|
||||
|
||||
/**
|
||||
* Fatal shutdown notification. This is sent to System.err
|
||||
* instead of System.out
|
||||
*/
|
||||
static void fatalError(String messageKey) {
|
||||
System.err.println();
|
||||
System.err.println(format("Fatal error"));
|
||||
System.err.println(format(messageKey));
|
||||
Env.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* "Format" a string by doing a simple key lookup.
|
||||
*/
|
||||
static String format(String key) {
|
||||
return (textResources.getString(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch and format a message with one string argument.
|
||||
* This is the most common usage.
|
||||
*/
|
||||
static String format(String key, String argument) {
|
||||
return format(key, new Object [] {argument});
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a string by key lookup and format in the arguments.
|
||||
*/
|
||||
static synchronized String format(String key, Object [] arguments) {
|
||||
if (messageFormat == null) {
|
||||
messageFormat = new MessageFormat (textResources.getString(key));
|
||||
} else {
|
||||
messageFormat.applyPattern (textResources.getString(key));
|
||||
}
|
||||
return (messageFormat.format (arguments));
|
||||
}
|
||||
|
||||
/**
|
||||
* Print directly to System.out.
|
||||
* Every rule has a few exceptions.
|
||||
* The exceptions to "must use the MessageOutput formatters" are:
|
||||
* VMConnection.dumpStream()
|
||||
* TTY.monitorCommand()
|
||||
* TTY.TTY() (for the '!!' command only)
|
||||
* Commands.java (multiple locations)
|
||||
* These are the only sites that should be calling this
|
||||
* method.
|
||||
*/
|
||||
static void printDirectln(String line) {
|
||||
System.out.println(line);
|
||||
}
|
||||
static void printDirect(String line) {
|
||||
System.out.print(line);
|
||||
}
|
||||
static void printDirect(char c) {
|
||||
System.out.print(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a newline.
|
||||
* Use this instead of '\n'
|
||||
*/
|
||||
static void println() {
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* Format and print a simple string.
|
||||
*/
|
||||
static void print(String key) {
|
||||
System.out.print(format(key));
|
||||
}
|
||||
/**
|
||||
* Format and print a simple string.
|
||||
*/
|
||||
static void println(String key) {
|
||||
System.out.println(format(key));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fetch, format and print a message with one string argument.
|
||||
* This is the most common usage.
|
||||
*/
|
||||
static void print(String key, String argument) {
|
||||
System.out.print(format(key, argument));
|
||||
}
|
||||
static void println(String key, String argument) {
|
||||
System.out.println(format(key, argument));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch, format and print a message with an arbitrary
|
||||
* number of message arguments.
|
||||
*/
|
||||
static void println(String key, Object [] arguments) {
|
||||
System.out.println(format(key, arguments));
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a newline, followed by the string.
|
||||
*/
|
||||
static void lnprint(String key) {
|
||||
System.out.println();
|
||||
System.out.print(textResources.getString(key));
|
||||
}
|
||||
|
||||
static void lnprint(String key, String argument) {
|
||||
System.out.println();
|
||||
System.out.print(format(key, argument));
|
||||
}
|
||||
|
||||
static void lnprint(String key, Object [] arguments) {
|
||||
System.out.println();
|
||||
System.out.print(format(key, arguments));
|
||||
}
|
||||
|
||||
/**
|
||||
* Print an exception message with a stack trace.
|
||||
*/
|
||||
static void printException(String key, Exception e) {
|
||||
if (key != null) {
|
||||
try {
|
||||
println(key);
|
||||
} catch (MissingResourceException mex) {
|
||||
printDirectln(key);
|
||||
}
|
||||
}
|
||||
System.out.flush();
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
static void printPrompt() {
|
||||
ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo();
|
||||
if (threadInfo == null) {
|
||||
System.out.print
|
||||
(MessageOutput.format("jdb prompt with no current thread"));
|
||||
} else {
|
||||
System.out.print
|
||||
(MessageOutput.format("jdb prompt thread name and current stack frame",
|
||||
new Object [] {
|
||||
threadInfo.getThread().name(),
|
||||
new Integer (threadInfo.getCurrentFrameIndex() + 1)}));
|
||||
}
|
||||
System.out.flush();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is provided to illustrate the usage of a given feature
|
||||
* or technique and has been deliberately simplified. Additional steps
|
||||
* required for a production-quality application, such as security checks,
|
||||
* input validation and proper error handling, might not be present in
|
||||
* this sample code.
|
||||
*/
|
||||
|
||||
|
||||
package com.sun.tools.example.debug.tty;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.request.EventRequestManager;
|
||||
import com.sun.jdi.request.EventRequest;
|
||||
|
||||
class ModificationWatchpointSpec extends WatchpointSpec {
|
||||
ModificationWatchpointSpec(ReferenceTypeSpec refSpec, String fieldId)
|
||||
throws MalformedMemberNameException {
|
||||
super(refSpec, fieldId);
|
||||
}
|
||||
|
||||
/**
|
||||
* The 'refType' is known to match, return the EventRequest.
|
||||
*/
|
||||
@Override
|
||||
EventRequest resolveEventRequest(ReferenceType refType)
|
||||
throws NoSuchFieldException {
|
||||
Field field = refType.fieldByName(fieldId);
|
||||
EventRequestManager em = refType.virtualMachine().eventRequestManager();
|
||||
EventRequest wp = em.createModificationWatchpointRequest(field);
|
||||
wp.setSuspendPolicy(suspendPolicy);
|
||||
wp.enable();
|
||||
return wp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return MessageOutput.format("watch modification of",
|
||||
new Object [] {refSpec.toString(),
|
||||
fieldId});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is provided to illustrate the usage of a given feature
|
||||
* or technique and has been deliberately simplified. Additional steps
|
||||
* required for a production-quality application, such as security checks,
|
||||
* input validation and proper error handling, might not be present in
|
||||
* this sample code.
|
||||
*/
|
||||
|
||||
|
||||
package com.sun.tools.example.debug.tty;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.request.ClassPrepareRequest;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
|
||||
class PatternReferenceTypeSpec implements ReferenceTypeSpec {
|
||||
final String classId;
|
||||
String stem;
|
||||
|
||||
PatternReferenceTypeSpec(String classId) throws ClassNotFoundException {
|
||||
this.classId = classId;
|
||||
stem = classId;
|
||||
if (classId.startsWith("*")) {
|
||||
stem = stem.substring(1);
|
||||
} else if (classId.endsWith("*")) {
|
||||
stem = stem.substring(0, classId.length() - 1);
|
||||
}
|
||||
checkClassName(stem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this spec unique or is it a class pattern?
|
||||
*/
|
||||
public boolean isUnique() {
|
||||
return classId.equals(stem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the specified ReferenceType match this spec.
|
||||
*/
|
||||
@Override
|
||||
public boolean matches(ReferenceType refType) {
|
||||
if (classId.startsWith("*")) {
|
||||
return refType.name().endsWith(stem);
|
||||
} else if (classId.endsWith("*")) {
|
||||
return refType.name().startsWith(stem);
|
||||
} else {
|
||||
return refType.name().equals(classId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassPrepareRequest createPrepareRequest() {
|
||||
ClassPrepareRequest request =
|
||||
Env.vm().eventRequestManager().createClassPrepareRequest();
|
||||
request.addClassFilter(classId);
|
||||
request.addCountFilter(1);
|
||||
return request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return classId.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof PatternReferenceTypeSpec) {
|
||||
PatternReferenceTypeSpec spec = (PatternReferenceTypeSpec)obj;
|
||||
|
||||
return classId.equals(spec.classId);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void checkClassName(String className) throws ClassNotFoundException {
|
||||
// Do stricter checking of class name validity on deferred
|
||||
// because if the name is invalid, it will
|
||||
// never match a future loaded class, and we'll be silent
|
||||
// about it.
|
||||
StringTokenizer tokenizer = new StringTokenizer(className, ".");
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
String token = tokenizer.nextToken();
|
||||
// Each dot-separated piece must be a valid identifier
|
||||
// and the first token can also be "*". (Note that
|
||||
// numeric class ids are not permitted. They must
|
||||
// match a loaded class.)
|
||||
if (!isJavaIdentifier(token)) {
|
||||
throw new ClassNotFoundException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isJavaIdentifier(String s) {
|
||||
if (s.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int cp = s.codePointAt(0);
|
||||
if (! Character.isJavaIdentifierStart(cp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = Character.charCount(cp); i < s.length(); i += Character.charCount(cp)) {
|
||||
cp = s.codePointAt(i);
|
||||
if (! Character.isJavaIdentifierPart(cp)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return classId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is provided to illustrate the usage of a given feature
|
||||
* or technique and has been deliberately simplified. Additional steps
|
||||
* required for a production-quality application, such as security checks,
|
||||
* input validation and proper error handling, might not be present in
|
||||
* this sample code.
|
||||
*/
|
||||
|
||||
|
||||
package com.sun.tools.example.debug.tty;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.request.ClassPrepareRequest;
|
||||
|
||||
interface ReferenceTypeSpec {
|
||||
/**
|
||||
* Does the specified ReferenceType match this spec.
|
||||
*/
|
||||
boolean matches(ReferenceType refType);
|
||||
ClassPrepareRequest createPrepareRequest();
|
||||
|
||||
@Override
|
||||
int hashCode();
|
||||
|
||||
@Override
|
||||
boolean equals(Object obj);
|
||||
}
|
||||
147
jdkSrc/jdk8/com/sun/tools/example/debug/tty/SourceMapper.java
Normal file
147
jdkSrc/jdk8/com/sun/tools/example/debug/tty/SourceMapper.java
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is provided to illustrate the usage of a given feature
|
||||
* or technique and has been deliberately simplified. Additional steps
|
||||
* required for a production-quality application, such as security checks,
|
||||
* input validation and proper error handling, might not be present in
|
||||
* this sample code.
|
||||
*/
|
||||
|
||||
|
||||
package com.sun.tools.example.debug.tty;
|
||||
|
||||
import com.sun.jdi.Location;
|
||||
import com.sun.jdi.AbsentInformationException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.StringTokenizer;
|
||||
import java.io.*;
|
||||
|
||||
class SourceMapper {
|
||||
|
||||
private final String[] dirs;
|
||||
|
||||
SourceMapper(List<String> sourcepath) {
|
||||
/*
|
||||
* sourcepath can arrive from the debugee as a List.
|
||||
* (via PathSearchingVirtualMachine.classPath())
|
||||
*/
|
||||
List<String> dirList = new ArrayList<String>();
|
||||
for (String element : sourcepath) {
|
||||
//XXX remove .jar and .zip files; we want only directories on
|
||||
//the source path. (Bug ID 4186582)
|
||||
if ( ! (element.endsWith(".jar") ||
|
||||
element.endsWith(".zip"))) {
|
||||
dirList.add(element);
|
||||
}
|
||||
}
|
||||
dirs = dirList.toArray(new String[0]);
|
||||
}
|
||||
|
||||
SourceMapper(String sourcepath) {
|
||||
/*
|
||||
* sourcepath can also arrive from the command line
|
||||
* as a String. (via "-sourcepath")
|
||||
*
|
||||
* Using File.pathSeparator as delimiter below is OK
|
||||
* because we are on the same machine as the command
|
||||
* line originiated.
|
||||
*/
|
||||
StringTokenizer st = new StringTokenizer(sourcepath,
|
||||
File.pathSeparator);
|
||||
List<String> dirList = new ArrayList<String>();
|
||||
while (st.hasMoreTokens()) {
|
||||
String s = st.nextToken();
|
||||
//XXX remove .jar and .zip files; we want only directories on
|
||||
//the source path. (Bug ID 4186582)
|
||||
if ( ! (s.endsWith(".jar") ||
|
||||
s.endsWith(".zip"))) {
|
||||
dirList.add(s);
|
||||
}
|
||||
}
|
||||
dirs = dirList.toArray(new String[0]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the current sourcePath as a String.
|
||||
*/
|
||||
String getSourcePath() {
|
||||
int i = 0;
|
||||
StringBuffer sp;
|
||||
if (dirs.length < 1) {
|
||||
return ""; //The source path is empty.
|
||||
} else {
|
||||
sp = new StringBuffer(dirs[i++]);
|
||||
}
|
||||
for (; i < dirs.length; i++) {
|
||||
sp.append(File.pathSeparator);
|
||||
sp.append(dirs[i]);
|
||||
}
|
||||
return sp.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a File cooresponding to the source of this location.
|
||||
* Return null if not available.
|
||||
*/
|
||||
File sourceFile(Location loc) {
|
||||
try {
|
||||
String filename = loc.sourceName();
|
||||
String refName = loc.declaringType().name();
|
||||
int iDot = refName.lastIndexOf('.');
|
||||
String pkgName = (iDot >= 0)? refName.substring(0, iDot+1) : "";
|
||||
String full = pkgName.replace('.', File.separatorChar) + filename;
|
||||
for (int i= 0; i < dirs.length; ++i) {
|
||||
File path = new File(dirs[i], full);
|
||||
if (path.exists()) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
} catch (AbsentInformationException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a BufferedReader cooresponding to the source
|
||||
* of this location.
|
||||
* Return null if not available.
|
||||
* Note: returned reader must be closed.
|
||||
*/
|
||||
BufferedReader sourceReader(Location loc) {
|
||||
File sourceFile = sourceFile(loc);
|
||||
if (sourceFile == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return new BufferedReader(new FileReader(sourceFile));
|
||||
} catch(IOException exc) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
1089
jdkSrc/jdk8/com/sun/tools/example/debug/tty/TTY.java
Normal file
1089
jdkSrc/jdk8/com/sun/tools/example/debug/tty/TTY.java
Normal file
File diff suppressed because it is too large
Load Diff
465
jdkSrc/jdk8/com/sun/tools/example/debug/tty/TTYResources.java
Normal file
465
jdkSrc/jdk8/com/sun/tools/example/debug/tty/TTYResources.java
Normal file
@@ -0,0 +1,465 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is provided to illustrate the usage of a given feature
|
||||
* or technique and has been deliberately simplified. Additional steps
|
||||
* required for a production-quality application, such as security checks,
|
||||
* input validation and proper error handling, might not be present in
|
||||
* this sample code.
|
||||
*/
|
||||
|
||||
|
||||
package com.sun.tools.example.debug.tty;
|
||||
|
||||
/**
|
||||
* <p> This class represents the <code>ResourceBundle</code>
|
||||
* for the following package(s):
|
||||
*
|
||||
* <ol>
|
||||
* <li> com.sun.tools.example.debug.tty
|
||||
* </ol>
|
||||
*
|
||||
*/
|
||||
public class TTYResources extends java.util.ListResourceBundle {
|
||||
|
||||
|
||||
/**
|
||||
* Returns the contents of this <code>ResourceBundle</code>.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the contents of this <code>ResourceBundle</code>.
|
||||
*/
|
||||
@Override
|
||||
public Object[][] getContents() {
|
||||
Object[][] temp = new Object[][] {
|
||||
// NOTE: The value strings in this file containing "{0}" are
|
||||
// processed by the java.text.MessageFormat class. Any
|
||||
// single quotes appearing in these strings need to be
|
||||
// doubled up.
|
||||
//
|
||||
// LOCALIZE THIS
|
||||
{"** classes list **", "** classes list **\n{0}"},
|
||||
{"** fields list **", "** fields list **\n{0}"},
|
||||
{"** methods list **", "** methods list **\n{0}"},
|
||||
{"*** Reading commands from", "*** Reading commands from {0}"},
|
||||
{"All threads resumed.", "All threads resumed."},
|
||||
{"All threads suspended.", "All threads suspended."},
|
||||
{"Argument is not defined for connector:", "Argument {0} is not defined for connector: {1}"},
|
||||
{"Arguments match no method", "Arguments match no method"},
|
||||
{"Array:", "Array: {0}"},
|
||||
{"Array element is not a method", "Array element is not a method"},
|
||||
{"Array index must be a integer type", "Array index must be a integer type"},
|
||||
{"base directory:", "base directory: {0}"},
|
||||
{"bootclasspath:", "bootclasspath: {0}"},
|
||||
{"Breakpoint hit:", "Breakpoint hit: "},
|
||||
{"breakpoint", "breakpoint {0}"},
|
||||
{"Breakpoints set:", "Breakpoints set:"},
|
||||
{"Breakpoints can be located only in classes.", "Breakpoints can be located only in classes. {0} is an interface or array."},
|
||||
{"Can only trace", "Can only trace 'methods' or 'method exit' or 'method exits'"},
|
||||
{"cannot redefine existing connection", "{0} cannot redefine existing connection"},
|
||||
{"Cannot assign to a method invocation", "Cannot assign to a method invocation"},
|
||||
{"Cannot specify command line with connector:", "Cannot specify command line with connector: {0}"},
|
||||
{"Cannot specify target vm arguments with connector:", "Cannot specify target VM arguments with connector: {0}"},
|
||||
{"Class containing field must be specified.", "Class containing field must be specified."},
|
||||
{"Class:", "Class: {0}"},
|
||||
{"Classic VM no longer supported.", "Classic VM no longer supported."},
|
||||
{"classpath:", "classpath: {0}"},
|
||||
{"colon mark", ":"},
|
||||
{"colon space", ": "},
|
||||
{"Command is not supported on the target VM", "Command ''{0}'' is not supported on the target VM"},
|
||||
{"Command is not supported on a read-only VM connection", "Command ''{0}'' is not supported on a read-only VM connection"},
|
||||
{"Command not valid until the VM is started with the run command", "Command ''{0}'' is not valid until the VM is started with the ''run'' command"},
|
||||
{"Condition must be boolean", "Condition must be boolean"},
|
||||
{"Connector and Transport name", " Connector: {0} Transport: {1}"},
|
||||
{"Connector argument nodefault", " Argument: {0} (no default)"},
|
||||
{"Connector argument default", " Argument: {0} Default value: {1}"},
|
||||
{"Connector description", " description: {0}"},
|
||||
{"Connector required argument nodefault", " Required Argument: {0} (no default)"},
|
||||
{"Connector required argument default", " Required Argument: {0} Default value: {1}"},
|
||||
{"Connectors available", "Available connectors are:"},
|
||||
{"Constant is not a method", "Constant is not a method"},
|
||||
{"Could not open:", "Could not open: {0}"},
|
||||
{"Current method is native", "Current method is native"},
|
||||
{"Current thread died. Execution continuing...", "Current thread {0} died. Execution continuing..."},
|
||||
{"Current thread isnt suspended.", "Current thread isn't suspended."},
|
||||
{"Current thread not set.", "Current thread not set."},
|
||||
{"dbgtrace flag value must be an integer:", "dbgtrace flag value must be an integer: {0}"},
|
||||
{"Deferring.", "Deferring {0}.\nIt will be set after the class is loaded."},
|
||||
{"End of stack.", "End of stack."},
|
||||
{"Error popping frame", "Error popping frame - {0}"},
|
||||
{"Error reading file", "Error reading ''{0}'' - {1}"},
|
||||
{"Error redefining class to file", "Error redefining {0} to {1} - {2}"},
|
||||
{"exceptionSpec all", "all {0}"},
|
||||
{"exceptionSpec caught", "caught {0}"},
|
||||
{"exceptionSpec uncaught", "uncaught {0}"},
|
||||
{"Exception in expression:", "Exception in expression: {0}"},
|
||||
{"Exception occurred caught", "Exception occurred: {0} (to be caught at: {1})"},
|
||||
{"Exception occurred uncaught", "Exception occurred: {0} (uncaught)"},
|
||||
{"Exceptions caught:", "Break when these exceptions occur:"},
|
||||
{"expr is null", "{0} = null"},
|
||||
{"expr is value", "{0} = {1}"},
|
||||
{"expr is value <collected>", " {0} = {1} <collected>"},
|
||||
{"Expression cannot be void", "Expression cannot be void"},
|
||||
{"Expression must evaluate to an object", "Expression must evaluate to an object"},
|
||||
{"extends:", "extends: {0}"},
|
||||
{"Failed reading output", "Failed reading output of child java interpreter."},
|
||||
{"Fatal error", "Fatal error:"},
|
||||
{"Field access encountered before after", "Field ({0}) is {1}, will be {2}: "},
|
||||
{"Field access encountered", "Field ({0}) access encountered: "},
|
||||
{"Field to unwatch not specified", "Field to unwatch not specified."},
|
||||
{"Field to watch not specified", "Field to watch not specified."},
|
||||
{"GC Disabled for", "GC Disabled for {0}:"},
|
||||
{"GC Enabled for", "GC Enabled for {0}:"},
|
||||
{"grouping begin character", "{"},
|
||||
{"grouping end character", "}"},
|
||||
{"Illegal Argument Exception", "Illegal Argument Exception"},
|
||||
{"Illegal connector argument", "Illegal connector argument: {0}"},
|
||||
{"implementor:", "implementor: {0}"},
|
||||
{"implements:", "implements: {0}"},
|
||||
{"Initializing progname", "Initializing {0} ..."},
|
||||
{"Input stream closed.", "Input stream closed."},
|
||||
{"Interface:", "Interface: {0}"},
|
||||
{"Internal debugger error.", "Internal debugger error."},
|
||||
{"Internal error: null ThreadInfo created", "Internal error: null ThreadInfo created"},
|
||||
{"Internal error; unable to set", "Internal error; unable to set {0}"},
|
||||
{"Internal exception during operation:", "Internal exception during operation:\n {0}"},
|
||||
{"Internal exception:", "Internal exception:"},
|
||||
{"Invalid argument type name", "Invalid argument type name"},
|
||||
{"Invalid assignment syntax", "Invalid assignment syntax"},
|
||||
{"Invalid command syntax", "Invalid command syntax"},
|
||||
{"Invalid connect type", "Invalid connect type"},
|
||||
{"Invalid consecutive invocations", "Invalid consecutive invocations"},
|
||||
{"Invalid exception object", "Invalid exception object"},
|
||||
{"Invalid method specification:", "Invalid method specification: {0}"},
|
||||
{"Invalid option on class command", "Invalid option on class command"},
|
||||
{"invalid option", "invalid option: {0}"},
|
||||
{"Invalid thread status.", "Invalid thread status."},
|
||||
{"Invalid transport name:", "Invalid transport name: {0}"},
|
||||
{"I/O exception occurred:", "I/O Exception occurred: {0}"},
|
||||
{"is an ambiguous method name in", "\"{0}\" is an ambiguous method name in \"{1}\""},
|
||||
{"is an invalid line number for", "{0,number,integer} is an invalid line number for {1}"},
|
||||
{"is not a valid class name", "\"{0}\" is not a valid class name."},
|
||||
{"is not a valid field name", "\"{0}\" is not a valid field name."},
|
||||
{"is not a valid id or class name", "\"{0}\" is not a valid id or class name."},
|
||||
{"is not a valid line number or method name for", "\"{0}\" is not a valid line number or method name for class \"{1}\""},
|
||||
{"is not a valid method name", "\"{0}\" is not a valid method name."},
|
||||
{"is not a valid thread id", "\"{0}\" is not a valid thread id."},
|
||||
{"is not a valid threadgroup name", "\"{0}\" is not a valid threadgroup name."},
|
||||
{"jdb prompt with no current thread", "> "},
|
||||
{"jdb prompt thread name and current stack frame", "{0}[{1,number,integer}] "},
|
||||
{"killed", "{0} killed"},
|
||||
{"killing thread:", "killing thread: {0}"},
|
||||
{"Line number information not available for", "Source line numbers not available for this location."},
|
||||
{"line number", ":{0,number,integer}"},
|
||||
{"list field typename and name", "{0} {1}\n"},
|
||||
{"list field typename and name inherited", "{0} {1} (inherited from {2})\n"},
|
||||
{"list field typename and name hidden", "{0} {1} (hidden)\n"},
|
||||
{"Listening at address:", "Listening at address: {0}"},
|
||||
{"Local variable information not available.", "Local variable information not available. Compile with -g to generate variable information"},
|
||||
{"Local variables:", "Local variables:"},
|
||||
{"<location unavailable>", "<location unavailable>"},
|
||||
{"location", "\"thread={0}\", {1}"},
|
||||
{"locationString", "{0}.{1}(), line={2,number,integer} bci={3,number,integer}"},
|
||||
{"Main class and arguments must be specified", "Main class and arguments must be specified"},
|
||||
{"Method arguments:", "Method arguments:"},
|
||||
{"Method entered:", "Method entered: "},
|
||||
{"Method exited:", "Method exited"},
|
||||
{"Method exitedValue:", "Method exited: return value = {0}, "},
|
||||
{"Method is overloaded; specify arguments", "Method {0} is overloaded; specify arguments"},
|
||||
{"minus version", "This is {0} version {1,number,integer}.{2,number,integer} (Java SE version {3})"},
|
||||
{"Monitor information for thread", "Monitor information for thread {0}:"},
|
||||
{"Monitor information for expr", "Monitor information for {0} ({1}):"},
|
||||
{"More than one class named", "More than one class named: ''{0}''"},
|
||||
{"native method", "native method"},
|
||||
{"nested:", "nested: {0}"},
|
||||
{"No attach address specified.", "No attach address specified."},
|
||||
{"No breakpoints set.", "No breakpoints set."},
|
||||
{"No class named", "No class named ''{0}''"},
|
||||
{"No class specified.", "No class specified."},
|
||||
{"No classpath specified.", "No classpath specified."},
|
||||
{"No code at line", "No code at line {0,number,integer} in {1}"},
|
||||
{"No connect specification.", "No connect specification."},
|
||||
{"No connector named:", "No connector named: {0}"},
|
||||
{"No current thread", "No current thread"},
|
||||
{"No default thread specified:", "No default thread specified: use the \"thread\" command first."},
|
||||
{"No exception object specified.", "No exception object specified."},
|
||||
{"No exceptions caught.", "No exceptions caught."},
|
||||
{"No expression specified.", "No expression specified."},
|
||||
{"No field in", "No field {0} in {1}"},
|
||||
{"No frames on the current call stack", "No frames on the current call stack"},
|
||||
{"No linenumber information for", "No linenumber information for {0}. Try compiling with debugging on."},
|
||||
{"No local variables", "No local variables"},
|
||||
{"No method in", "No method {0} in {1}"},
|
||||
{"No method specified.", "No method specified."},
|
||||
{"No monitor numbered:", "No monitor numbered: {0}"},
|
||||
{"No monitors owned", " No monitors owned"},
|
||||
{"No object specified.", "No object specified."},
|
||||
{"No objects specified.", "No objects specified."},
|
||||
{"No save index specified.", "No save index specified."},
|
||||
{"No saved values", "No saved values"},
|
||||
{"No source information available for:", "No source information available for: {0}"},
|
||||
{"No sourcedebugextension specified", "No SourceDebugExtension specified"},
|
||||
{"No sourcepath specified.", "No sourcepath specified."},
|
||||
{"No thread specified.", "No thread specified."},
|
||||
{"No VM connected", "No VM connected"},
|
||||
{"No waiters", " No waiters"},
|
||||
{"not a class", "{0} is not a class"},
|
||||
{"Not a monitor number:", "Not a monitor number: ''{0}''"},
|
||||
{"not found (try the full name)", "{0} not found (try the full name)"},
|
||||
{"Not found:", "Not found: {0}"},
|
||||
{"not found", "{0} not found"},
|
||||
{"Not owned", " Not owned"},
|
||||
{"Not waiting for a monitor", " Not waiting for a monitor"},
|
||||
{"Nothing suspended.", "Nothing suspended."},
|
||||
{"object description and hex id", "({0}){1}"},
|
||||
{"Operation is not supported on the target VM", "Operation is not supported on the target VM"},
|
||||
{"operation not yet supported", "operation not yet supported"},
|
||||
{"Owned by:", " Owned by: {0}, entry count: {1,number,integer}"},
|
||||
{"Owned monitor:", " Owned monitor: {0}"},
|
||||
{"Parse exception:", "Parse Exception: {0}"},
|
||||
{"printbreakpointcommandusage", "Usage: {0} <class>:<line_number> or\n {1} <class>.<method_name>[(argument_type,...)]"},
|
||||
{"Removed:", "Removed: {0}"},
|
||||
{"Requested stack frame is no longer active:", "Requested stack frame is no longer active: {0,number,integer}"},
|
||||
{"run <args> command is valid only with launched VMs", "'run <args>' command is valid only with launched VMs"},
|
||||
{"run", "run {0}"},
|
||||
{"saved", "{0} saved"},
|
||||
{"Set deferred", "Set deferred {0}"},
|
||||
{"Set", "Set {0}"},
|
||||
{"Source file not found:", "Source file not found: {0}"},
|
||||
{"source line number and line", "{0,number,integer} {1}"},
|
||||
{"source line number current line and line", "{0,number,integer} => {1}"},
|
||||
{"sourcedebugextension", "SourceDebugExtension -- {0}"},
|
||||
{"Specify class and method", "Specify class and method"},
|
||||
{"Specify classes to redefine", "Specify classes to redefine"},
|
||||
{"Specify file name for class", "Specify file name for class {0}"},
|
||||
{"stack frame dump with pc", " [{0,number,integer}] {1}.{2} ({3}), pc = {4}"},
|
||||
{"stack frame dump", " [{0,number,integer}] {1}.{2} ({3})"},
|
||||
{"Step completed:", "Step completed: "},
|
||||
{"Stopping due to deferred breakpoint errors.", "Stopping due to deferred breakpoint errors.\n"},
|
||||
{"subclass:", "subclass: {0}"},
|
||||
{"subinterface:", "subinterface: {0}"},
|
||||
{"tab", "\t{0}"},
|
||||
{"Target VM failed to initialize.", "Target VM failed to initialize."},
|
||||
{"The application exited", "The application exited"},
|
||||
{"The application has been disconnected", "The application has been disconnected"},
|
||||
{"The gc command is no longer necessary.", "The 'gc' command is no longer necessary.\n" +
|
||||
"All objects are garbage collected as usual. Use 'enablegc' and 'disablegc'\n" +
|
||||
"commands to control garbage collection of individual objects."},
|
||||
{"The load command is no longer supported.", "The 'load' command is no longer supported."},
|
||||
{"The memory command is no longer supported.", "The 'memory' command is no longer supported."},
|
||||
{"The VM does not use paths", "The VM does not use paths"},
|
||||
{"Thread is not running (no stack).", "Thread is not running (no stack)."},
|
||||
{"Thread number not specified.", "Thread number not specified."},
|
||||
{"Thread:", "{0}:"},
|
||||
{"Thread Group:", "Group {0}:"},
|
||||
{"Thread description name unknownStatus BP", " {0} {1} unknown (at breakpoint)"},
|
||||
{"Thread description name unknownStatus", " {0} {1} unknown"},
|
||||
{"Thread description name zombieStatus BP", " {0} {1} zombie (at breakpoint)"},
|
||||
{"Thread description name zombieStatus", " {0} {1} zombie"},
|
||||
{"Thread description name runningStatus BP", " {0} {1} running (at breakpoint)"},
|
||||
{"Thread description name runningStatus", " {0} {1} running"},
|
||||
{"Thread description name sleepingStatus BP", " {0} {1} sleeping (at breakpoint)"},
|
||||
{"Thread description name sleepingStatus", " {0} {1} sleeping"},
|
||||
{"Thread description name waitingStatus BP", " {0} {1} waiting in a monitor (at breakpoint)"},
|
||||
{"Thread description name waitingStatus", " {0} {1} waiting in a monitor"},
|
||||
{"Thread description name condWaitstatus BP", " {0} {1} cond. waiting (at breakpoint)"},
|
||||
{"Thread description name condWaitstatus", " {0} {1} cond. waiting"},
|
||||
{"Thread has been resumed", "Thread has been resumed"},
|
||||
{"Thread not suspended", "Thread not suspended"},
|
||||
{"thread group number description name", "{0,number,integer}. {1} {2}"},
|
||||
{"Threadgroup name not specified.", "Threadgroup name not specified."},
|
||||
{"Threads must be suspended", "Threads must be suspended"},
|
||||
{"trace method exit in effect for", "trace method exit in effect for {0}"},
|
||||
{"trace method exits in effect", "trace method exits in effect"},
|
||||
{"trace methods in effect", "trace methods in effect"},
|
||||
{"trace go method exit in effect for", "trace go method exit in effect for {0}"},
|
||||
{"trace go method exits in effect", "trace go method exits in effect"},
|
||||
{"trace go methods in effect", "trace go methods in effect"},
|
||||
{"trace not in effect", "trace not in effect"},
|
||||
{"Unable to attach to target VM.", "Unable to attach to target VM."},
|
||||
{"Unable to display process output:", "Unable to display process output: {0}"},
|
||||
{"Unable to launch target VM.", "Unable to launch target VM."},
|
||||
{"Unable to set deferred", "Unable to set deferred {0} : {1}"},
|
||||
{"Unable to set main class and arguments", "Unable to set main class and arguments"},
|
||||
{"Unable to set", "Unable to set {0} : {1}"},
|
||||
{"Unexpected event type", "Unexpected event type: {0}"},
|
||||
{"unknown", "unknown"},
|
||||
{"Unmonitoring", "Unmonitoring {0} "},
|
||||
{"Unrecognized command. Try help...", "Unrecognized command: ''{0}''. Try help..."},
|
||||
{"Usage: catch exception", "Usage: catch [uncaught|caught|all] <class id>|<class pattern>"},
|
||||
{"Usage: ignore exception", "Usage: ignore [uncaught|caught|all] <class id>|<class pattern>"},
|
||||
{"Usage: down [n frames]", "Usage: down [n frames]"},
|
||||
{"Usage: kill <thread id> <throwable>", "Usage: kill <thread id> <throwable>"},
|
||||
{"Usage: read <command-filename>", "Usage: read <command-filename>"},
|
||||
{"Usage: unmonitor <monitor#>", "Usage: unmonitor <monitor#>"},
|
||||
{"Usage: up [n frames]", "Usage: up [n frames]"},
|
||||
{"Use java minus X to see", "Use 'java -X' to see the available non-standard options"},
|
||||
{"Use stop at to set a breakpoint at a line number", "Use 'stop at' to set a breakpoint at a line number"},
|
||||
{"VM already running. use cont to continue after events.", "VM already running. Use 'cont' to continue after events."},
|
||||
{"VM Started:", "VM Started: "},
|
||||
{"vmstartexception", "VM start exception: {0}"},
|
||||
{"Waiting for monitor:", " Waiting for monitor: {0}"},
|
||||
{"Waiting thread:", " Waiting thread: {0}"},
|
||||
{"watch accesses of", "watch accesses of {0}.{1}"},
|
||||
{"watch modification of", "watch modification of {0}.{1}"},
|
||||
{"zz help text",
|
||||
"** command list **\n" +
|
||||
"connectors -- list available connectors and transports in this VM\n" +
|
||||
"\n" +
|
||||
"run [class [args]] -- start execution of application's main class\n" +
|
||||
"\n" +
|
||||
"threads [threadgroup] -- list threads\n" +
|
||||
"thread <thread id> -- set default thread\n" +
|
||||
"suspend [thread id(s)] -- suspend threads (default: all)\n" +
|
||||
"resume [thread id(s)] -- resume threads (default: all)\n" +
|
||||
"where [<thread id> | all] -- dump a thread's stack\n" +
|
||||
"wherei [<thread id> | all]-- dump a thread's stack, with pc info\n" +
|
||||
"up [n frames] -- move up a thread's stack\n" +
|
||||
"down [n frames] -- move down a thread's stack\n" +
|
||||
"kill <thread id> <expr> -- kill a thread with the given exception object\n" +
|
||||
"interrupt <thread id> -- interrupt a thread\n" +
|
||||
"\n" +
|
||||
"print <expr> -- print value of expression\n" +
|
||||
"dump <expr> -- print all object information\n" +
|
||||
"eval <expr> -- evaluate expression (same as print)\n" +
|
||||
"set <lvalue> = <expr> -- assign new value to field/variable/array element\n" +
|
||||
"locals -- print all local variables in current stack frame\n" +
|
||||
"\n" +
|
||||
"classes -- list currently known classes\n" +
|
||||
"class <class id> -- show details of named class\n" +
|
||||
"methods <class id> -- list a class's methods\n" +
|
||||
"fields <class id> -- list a class's fields\n" +
|
||||
"\n" +
|
||||
"threadgroups -- list threadgroups\n" +
|
||||
"threadgroup <name> -- set current threadgroup\n" +
|
||||
"\n" +
|
||||
"stop in <class id>.<method>[(argument_type,...)]\n" +
|
||||
" -- set a breakpoint in a method\n" +
|
||||
"stop at <class id>:<line> -- set a breakpoint at a line\n" +
|
||||
"clear <class id>.<method>[(argument_type,...)]\n" +
|
||||
" -- clear a breakpoint in a method\n" +
|
||||
"clear <class id>:<line> -- clear a breakpoint at a line\n" +
|
||||
"clear -- list breakpoints\n" +
|
||||
"catch [uncaught|caught|all] <class id>|<class pattern>\n" +
|
||||
" -- break when specified exception occurs\n" +
|
||||
"ignore [uncaught|caught|all] <class id>|<class pattern>\n" +
|
||||
" -- cancel 'catch' for the specified exception\n" +
|
||||
"watch [access|all] <class id>.<field name>\n" +
|
||||
" -- watch access/modifications to a field\n" +
|
||||
"unwatch [access|all] <class id>.<field name>\n" +
|
||||
" -- discontinue watching access/modifications to a field\n" +
|
||||
"trace [go] methods [thread]\n" +
|
||||
" -- trace method entries and exits.\n" +
|
||||
" -- All threads are suspended unless 'go' is specified\n" +
|
||||
"trace [go] method exit | exits [thread]\n" +
|
||||
" -- trace the current method's exit, or all methods' exits\n" +
|
||||
" -- All threads are suspended unless 'go' is specified\n" +
|
||||
"untrace [methods] -- stop tracing method entrys and/or exits\n" +
|
||||
"step -- execute current line\n" +
|
||||
"step up -- execute until the current method returns to its caller\n" +
|
||||
"stepi -- execute current instruction\n" +
|
||||
"next -- step one line (step OVER calls)\n" +
|
||||
"cont -- continue execution from breakpoint\n" +
|
||||
"\n" +
|
||||
"list [line number|method] -- print source code\n" +
|
||||
"use (or sourcepath) [source file path]\n" +
|
||||
" -- display or change the source path\n" +
|
||||
"exclude [<class pattern>, ... | \"none\"]\n" +
|
||||
" -- do not report step or method events for specified classes\n" +
|
||||
"classpath -- print classpath info from target VM\n" +
|
||||
"\n" +
|
||||
"monitor <command> -- execute command each time the program stops\n" +
|
||||
"monitor -- list monitors\n" +
|
||||
"unmonitor <monitor#> -- delete a monitor\n" +
|
||||
"read <filename> -- read and execute a command file\n" +
|
||||
"\n" +
|
||||
"lock <expr> -- print lock info for an object\n" +
|
||||
"threadlocks [thread id] -- print lock info for a thread\n" +
|
||||
"\n" +
|
||||
"pop -- pop the stack through and including the current frame\n" +
|
||||
"reenter -- same as pop, but current frame is reentered\n" +
|
||||
"redefine <class id> <class file name>\n" +
|
||||
" -- redefine the code for a class\n" +
|
||||
"\n" +
|
||||
"disablegc <expr> -- prevent garbage collection of an object\n" +
|
||||
"enablegc <expr> -- permit garbage collection of an object\n" +
|
||||
"\n" +
|
||||
"!! -- repeat last command\n" +
|
||||
"<n> <command> -- repeat command n times\n" +
|
||||
"# <command> -- discard (no-op)\n" +
|
||||
"help (or ?) -- list commands\n" +
|
||||
"version -- print version information\n" +
|
||||
"exit (or quit) -- exit debugger\n" +
|
||||
"\n" +
|
||||
"<class id>: a full class name with package qualifiers\n" +
|
||||
"<class pattern>: a class name with a leading or trailing wildcard ('*')\n" +
|
||||
"<thread id>: thread number as reported in the 'threads' command\n" +
|
||||
"<expr>: a Java(TM) Programming Language expression.\n" +
|
||||
"Most common syntax is supported.\n" +
|
||||
"\n" +
|
||||
"Startup commands can be placed in either \"jdb.ini\" or \".jdbrc\"\n" +
|
||||
"in user.home or user.dir"},
|
||||
{"zz usage text",
|
||||
"Usage: {0} <options> <class> <arguments>\n" +
|
||||
"\n" +
|
||||
"where options include:\n" +
|
||||
" -help print out this message and exit\n" +
|
||||
" -sourcepath <directories separated by \"{1}\">\n" +
|
||||
" directories in which to look for source files\n" +
|
||||
" -attach <address>\n" +
|
||||
" attach to a running VM at the specified address using standard connector\n" +
|
||||
" -listen <address>\n" +
|
||||
" wait for a running VM to connect at the specified address using standard connector\n" +
|
||||
" -listenany\n" +
|
||||
" wait for a running VM to connect at any available address using standard connector\n" +
|
||||
" -launch\n" +
|
||||
" launch VM immediately instead of waiting for ''run'' command\n" +
|
||||
" -listconnectors list the connectors available in this VM\n" +
|
||||
" -connect <connector-name>:<name1>=<value1>,...\n" +
|
||||
" connect to target VM using named connector with listed argument values\n" +
|
||||
" -dbgtrace [flags] print info for debugging {0}\n" +
|
||||
" -tclient run the application in the HotSpot(TM) Client Compiler\n" +
|
||||
" -tserver run the application in the HotSpot(TM) Server Compiler\n" +
|
||||
"\n" +
|
||||
"options forwarded to debuggee process:\n" +
|
||||
" -v -verbose[:class|gc|jni]\n" +
|
||||
" turn on verbose mode\n" +
|
||||
" -D<name>=<value> set a system property\n" +
|
||||
" -classpath <directories separated by \"{1}\">\n" +
|
||||
" list directories in which to look for classes\n" +
|
||||
" -X<option> non-standard target VM option\n" +
|
||||
"\n" +
|
||||
"<class> is the name of the class to begin debugging\n" +
|
||||
"<arguments> are the arguments passed to the main() method of <class>\n" +
|
||||
"\n" +
|
||||
"For command help type ''help'' at {0} prompt"},
|
||||
// END OF MATERIAL TO LOCALIZE
|
||||
};
|
||||
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
336
jdkSrc/jdk8/com/sun/tools/example/debug/tty/TTYResources_ja.java
Normal file
336
jdkSrc/jdk8/com/sun/tools/example/debug/tty/TTYResources_ja.java
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is provided to illustrate the usage of a given feature
|
||||
* or technique and has been deliberately simplified. Additional steps
|
||||
* required for a production-quality application, such as security checks,
|
||||
* input validation and proper error handling, might not be present in
|
||||
* this sample code.
|
||||
*/
|
||||
|
||||
|
||||
package com.sun.tools.example.debug.tty;
|
||||
|
||||
import com.sun.jdi.ThreadGroupReference;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Descend the tree of thread groups.
|
||||
* @author Robert G. Field
|
||||
*/
|
||||
class ThreadGroupIterator implements Iterator<ThreadGroupReference> {
|
||||
private final Stack<Iterator<ThreadGroupReference>> stack = new Stack<Iterator<ThreadGroupReference>>();
|
||||
|
||||
ThreadGroupIterator(List<ThreadGroupReference> tgl) {
|
||||
push(tgl);
|
||||
}
|
||||
|
||||
ThreadGroupIterator(ThreadGroupReference tg) {
|
||||
List<ThreadGroupReference> tgl = new ArrayList<ThreadGroupReference>();
|
||||
tgl.add(tg);
|
||||
push(tgl);
|
||||
}
|
||||
|
||||
ThreadGroupIterator() {
|
||||
this(Env.vm().topLevelThreadGroups());
|
||||
}
|
||||
|
||||
private Iterator<ThreadGroupReference> top() {
|
||||
return stack.peek();
|
||||
}
|
||||
|
||||
/**
|
||||
* The invariant in this class is that the top iterator
|
||||
* on the stack has more elements. If the stack is
|
||||
* empty, there is no top. This method assures
|
||||
* this invariant.
|
||||
*/
|
||||
private void push(List<ThreadGroupReference> tgl) {
|
||||
stack.push(tgl.iterator());
|
||||
while (!stack.isEmpty() && !top().hasNext()) {
|
||||
stack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return !stack.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThreadGroupReference next() {
|
||||
return nextThreadGroup();
|
||||
}
|
||||
|
||||
public ThreadGroupReference nextThreadGroup() {
|
||||
ThreadGroupReference tg = top().next();
|
||||
push(tg.threadGroups());
|
||||
return tg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
static ThreadGroupReference find(String name) {
|
||||
ThreadGroupIterator tgi = new ThreadGroupIterator();
|
||||
while (tgi.hasNext()) {
|
||||
ThreadGroupReference tg = tgi.nextThreadGroup();
|
||||
if (tg.name().equals(name)) {
|
||||
return tg;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
296
jdkSrc/jdk8/com/sun/tools/example/debug/tty/ThreadInfo.java
Normal file
296
jdkSrc/jdk8/com/sun/tools/example/debug/tty/ThreadInfo.java
Normal file
@@ -0,0 +1,296 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is provided to illustrate the usage of a given feature
|
||||
* or technique and has been deliberately simplified. Additional steps
|
||||
* required for a production-quality application, such as security checks,
|
||||
* input validation and proper error handling, might not be present in
|
||||
* this sample code.
|
||||
*/
|
||||
|
||||
|
||||
package com.sun.tools.example.debug.tty;
|
||||
|
||||
import com.sun.jdi.ThreadReference;
|
||||
import com.sun.jdi.ThreadGroupReference;
|
||||
import com.sun.jdi.IncompatibleThreadStateException;
|
||||
import com.sun.jdi.StackFrame;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
class ThreadInfo {
|
||||
// This is a list of all known ThreadInfo objects. It survives
|
||||
// ThreadInfo.invalidateAll, unlike the other static fields below.
|
||||
private static List<ThreadInfo> threads = Collections.synchronizedList(new ArrayList<ThreadInfo>());
|
||||
private static boolean gotInitialThreads = false;
|
||||
|
||||
private static ThreadInfo current = null;
|
||||
private static ThreadGroupReference group = null;
|
||||
|
||||
private final ThreadReference thread;
|
||||
private int currentFrameIndex = 0;
|
||||
|
||||
private ThreadInfo(ThreadReference thread) {
|
||||
this.thread = thread;
|
||||
if (thread == null) {
|
||||
MessageOutput.fatalError("Internal error: null ThreadInfo created");
|
||||
}
|
||||
}
|
||||
|
||||
private static void initThreads() {
|
||||
if (!gotInitialThreads) {
|
||||
for (ThreadReference thread : Env.vm().allThreads()) {
|
||||
threads.add(new ThreadInfo(thread));
|
||||
}
|
||||
gotInitialThreads = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void addThread(ThreadReference thread) {
|
||||
synchronized (threads) {
|
||||
initThreads();
|
||||
ThreadInfo ti = new ThreadInfo(thread);
|
||||
// Guard against duplicates. Duplicates can happen during
|
||||
// initialization when a particular thread might be added both
|
||||
// by a thread start event and by the initial call to threads()
|
||||
if (getThreadInfo(thread) == null) {
|
||||
threads.add(ti);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void removeThread(ThreadReference thread) {
|
||||
if (thread.equals(ThreadInfo.current)) {
|
||||
// Current thread has died.
|
||||
|
||||
// Be careful getting the thread name. If its death happens
|
||||
// as part of VM termination, it may be too late to get the
|
||||
// information, and an exception will be thrown.
|
||||
String currentThreadName;
|
||||
try {
|
||||
currentThreadName = "\"" + thread.name() + "\"";
|
||||
} catch (Exception e) {
|
||||
currentThreadName = "";
|
||||
}
|
||||
|
||||
setCurrentThread(null);
|
||||
|
||||
MessageOutput.println();
|
||||
MessageOutput.println("Current thread died. Execution continuing...",
|
||||
currentThreadName);
|
||||
}
|
||||
threads.remove(getThreadInfo(thread));
|
||||
}
|
||||
|
||||
static List<ThreadInfo> threads() {
|
||||
synchronized(threads) {
|
||||
initThreads();
|
||||
// Make a copy to allow iteration without synchronization
|
||||
return new ArrayList<ThreadInfo>(threads);
|
||||
}
|
||||
}
|
||||
|
||||
static void invalidateAll() {
|
||||
current = null;
|
||||
group = null;
|
||||
synchronized (threads) {
|
||||
for (ThreadInfo ti : threads()) {
|
||||
ti.invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void setThreadGroup(ThreadGroupReference tg) {
|
||||
group = tg;
|
||||
}
|
||||
|
||||
static void setCurrentThread(ThreadReference tr) {
|
||||
if (tr == null) {
|
||||
setCurrentThreadInfo(null);
|
||||
} else {
|
||||
ThreadInfo tinfo = getThreadInfo(tr);
|
||||
setCurrentThreadInfo(tinfo);
|
||||
}
|
||||
}
|
||||
|
||||
static void setCurrentThreadInfo(ThreadInfo tinfo) {
|
||||
current = tinfo;
|
||||
if (current != null) {
|
||||
current.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current ThreadInfo object.
|
||||
*
|
||||
* @return the ThreadInfo for the current thread.
|
||||
*/
|
||||
static ThreadInfo getCurrentThreadInfo() {
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the thread from this ThreadInfo object.
|
||||
*
|
||||
* @return the Thread wrapped by this ThreadInfo.
|
||||
*/
|
||||
ThreadReference getThread() {
|
||||
return thread;
|
||||
}
|
||||
|
||||
static ThreadGroupReference group() {
|
||||
if (group == null) {
|
||||
// Current thread group defaults to the first top level
|
||||
// thread group.
|
||||
setThreadGroup(Env.vm().topLevelThreadGroups().get(0));
|
||||
}
|
||||
return group;
|
||||
}
|
||||
|
||||
static ThreadInfo getThreadInfo(long id) {
|
||||
ThreadInfo retInfo = null;
|
||||
|
||||
synchronized (threads) {
|
||||
for (ThreadInfo ti : threads()) {
|
||||
if (ti.thread.uniqueID() == id) {
|
||||
retInfo = ti;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return retInfo;
|
||||
}
|
||||
|
||||
static ThreadInfo getThreadInfo(ThreadReference tr) {
|
||||
return getThreadInfo(tr.uniqueID());
|
||||
}
|
||||
|
||||
static ThreadInfo getThreadInfo(String idToken) {
|
||||
ThreadInfo tinfo = null;
|
||||
if (idToken.startsWith("t@")) {
|
||||
idToken = idToken.substring(2);
|
||||
}
|
||||
try {
|
||||
long threadId = Long.decode(idToken).longValue();
|
||||
tinfo = getThreadInfo(threadId);
|
||||
} catch (NumberFormatException e) {
|
||||
tinfo = null;
|
||||
}
|
||||
return tinfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the thread stack frames.
|
||||
*
|
||||
* @return a <code>List</code> of the stack frames.
|
||||
*/
|
||||
List<StackFrame> getStack() throws IncompatibleThreadStateException {
|
||||
return thread.frames();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current stackframe.
|
||||
*
|
||||
* @return the current stackframe.
|
||||
*/
|
||||
StackFrame getCurrentFrame() throws IncompatibleThreadStateException {
|
||||
if (thread.frameCount() == 0) {
|
||||
return null;
|
||||
}
|
||||
return thread.frame(currentFrameIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate the current stackframe index.
|
||||
*/
|
||||
void invalidate() {
|
||||
currentFrameIndex = 0;
|
||||
}
|
||||
|
||||
/* Throw IncompatibleThreadStateException if not suspended */
|
||||
private void assureSuspended() throws IncompatibleThreadStateException {
|
||||
if (!thread.isSuspended()) {
|
||||
throw new IncompatibleThreadStateException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current stackframe index.
|
||||
*
|
||||
* @return the number of the current stackframe. Frame zero is the
|
||||
* closest to the current program counter
|
||||
*/
|
||||
int getCurrentFrameIndex() {
|
||||
return currentFrameIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current stackframe to a specific frame.
|
||||
*
|
||||
* @param nFrame the number of the desired stackframe. Frame zero is the
|
||||
* closest to the current program counter
|
||||
* @exception IllegalAccessError when the thread isn't
|
||||
* suspended or waiting at a breakpoint
|
||||
* @exception ArrayIndexOutOfBoundsException when the
|
||||
* requested frame is beyond the stack boundary
|
||||
*/
|
||||
void setCurrentFrameIndex(int nFrame) throws IncompatibleThreadStateException {
|
||||
assureSuspended();
|
||||
if ((nFrame < 0) || (nFrame >= thread.frameCount())) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
currentFrameIndex = nFrame;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the current stackframe to be one or more frames higher
|
||||
* (as in, away from the current program counter).
|
||||
*
|
||||
* @param nFrames the number of stackframes
|
||||
* @exception IllegalAccessError when the thread isn't
|
||||
* suspended or waiting at a breakpoint
|
||||
* @exception ArrayIndexOutOfBoundsException when the
|
||||
* requested frame is beyond the stack boundary
|
||||
*/
|
||||
void up(int nFrames) throws IncompatibleThreadStateException {
|
||||
setCurrentFrameIndex(currentFrameIndex + nFrames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the current stackframe to be one or more frames lower
|
||||
* (as in, toward the current program counter). *
|
||||
* @param nFrames the number of stackframes
|
||||
* @exception IllegalAccessError when the thread isn't
|
||||
* suspended or waiting at a breakpoint
|
||||
* @exception ArrayIndexOutOfBoundsException when the
|
||||
* requested frame is beyond the stack boundary
|
||||
*/
|
||||
void down(int nFrames) throws IncompatibleThreadStateException {
|
||||
setCurrentFrameIndex(currentFrameIndex - nFrames);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is provided to illustrate the usage of a given feature
|
||||
* or technique and has been deliberately simplified. Additional steps
|
||||
* required for a production-quality application, such as security checks,
|
||||
* input validation and proper error handling, might not be present in
|
||||
* this sample code.
|
||||
*/
|
||||
|
||||
|
||||
package com.sun.tools.example.debug.tty;
|
||||
|
||||
import com.sun.jdi.ThreadGroupReference;
|
||||
import com.sun.jdi.ThreadReference;
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
|
||||
class ThreadIterator implements Iterator<ThreadReference> {
|
||||
Iterator<ThreadReference> it = null;
|
||||
ThreadGroupIterator tgi;
|
||||
|
||||
ThreadIterator(ThreadGroupReference tg) {
|
||||
tgi = new ThreadGroupIterator(tg);
|
||||
}
|
||||
|
||||
ThreadIterator(List<ThreadGroupReference> tgl) {
|
||||
tgi = new ThreadGroupIterator(tgl);
|
||||
}
|
||||
|
||||
ThreadIterator() {
|
||||
tgi = new ThreadGroupIterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
while (it == null || !it.hasNext()) {
|
||||
if (!tgi.hasNext()) {
|
||||
return false; // no more
|
||||
}
|
||||
it = tgi.nextThreadGroup().threads().iterator();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThreadReference next() {
|
||||
return it.next();
|
||||
}
|
||||
|
||||
public ThreadReference nextThread() {
|
||||
return next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
548
jdkSrc/jdk8/com/sun/tools/example/debug/tty/VMConnection.java
Normal file
548
jdkSrc/jdk8/com/sun/tools/example/debug/tty/VMConnection.java
Normal file
@@ -0,0 +1,548 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is provided to illustrate the usage of a given feature
|
||||
* or technique and has been deliberately simplified. Additional steps
|
||||
* required for a production-quality application, such as security checks,
|
||||
* input validation and proper error handling, might not be present in
|
||||
* this sample code.
|
||||
*/
|
||||
|
||||
|
||||
package com.sun.tools.example.debug.tty;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.connect.*;
|
||||
import com.sun.jdi.request.EventRequestManager;
|
||||
import com.sun.jdi.request.ThreadStartRequest;
|
||||
import com.sun.jdi.request.ThreadDeathRequest;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.*;
|
||||
import java.io.*;
|
||||
|
||||
class VMConnection {
|
||||
|
||||
private VirtualMachine vm;
|
||||
private Process process = null;
|
||||
private int outputCompleteCount = 0;
|
||||
|
||||
private final Connector connector;
|
||||
private final Map<String, com.sun.jdi.connect.Connector.Argument> connectorArgs;
|
||||
private final int traceFlags;
|
||||
|
||||
synchronized void notifyOutputComplete() {
|
||||
outputCompleteCount++;
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
synchronized void waitOutputComplete() {
|
||||
// Wait for stderr and stdout
|
||||
if (process != null) {
|
||||
while (outputCompleteCount < 2) {
|
||||
try {wait();} catch (InterruptedException e) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Connector findConnector(String name) {
|
||||
for (Connector connector :
|
||||
Bootstrap.virtualMachineManager().allConnectors()) {
|
||||
if (connector.name().equals(name)) {
|
||||
return connector;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Map <String, com.sun.jdi.connect.Connector.Argument> parseConnectorArgs(Connector connector, String argString) {
|
||||
Map<String, com.sun.jdi.connect.Connector.Argument> arguments = connector.defaultArguments();
|
||||
|
||||
/*
|
||||
* We are parsing strings of the form:
|
||||
* name1=value1,[name2=value2,...]
|
||||
* However, the value1...valuen substrings may contain
|
||||
* embedded comma(s), so make provision for quoting inside
|
||||
* the value substrings. (Bug ID 4285874)
|
||||
*/
|
||||
String regexPattern =
|
||||
"(quote=[^,]+,)|" + // special case for quote=.,
|
||||
"(\\w+=)" + // name=
|
||||
"(((\"[^\"]*\")|" + // ( "l , ue"
|
||||
"('[^']*')|" + // 'l , ue'
|
||||
"([^,'\"]+))+,)"; // v a l u e )+ ,
|
||||
Pattern p = Pattern.compile(regexPattern);
|
||||
Matcher m = p.matcher(argString);
|
||||
while (m.find()) {
|
||||
int startPosition = m.start();
|
||||
int endPosition = m.end();
|
||||
if (startPosition > 0) {
|
||||
/*
|
||||
* It is an error if parsing skips over any part of argString.
|
||||
*/
|
||||
throw new IllegalArgumentException
|
||||
(MessageOutput.format("Illegal connector argument",
|
||||
argString));
|
||||
}
|
||||
|
||||
String token = argString.substring(startPosition, endPosition);
|
||||
int index = token.indexOf('=');
|
||||
String name = token.substring(0, index);
|
||||
String value = token.substring(index + 1,
|
||||
token.length() - 1); // Remove comma delimiter
|
||||
|
||||
/*
|
||||
* for values enclosed in quotes (single and/or double quotes)
|
||||
* strip off enclosing quote chars
|
||||
* needed for quote enclosed delimited substrings
|
||||
*/
|
||||
if (name.equals("options")) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String s : splitStringAtNonEnclosedWhiteSpace(value)) {
|
||||
while (isEnclosed(s, "\"") || isEnclosed(s, "'")) {
|
||||
s = s.substring(1, s.length() - 1);
|
||||
}
|
||||
sb.append(s);
|
||||
sb.append(" ");
|
||||
}
|
||||
value = sb.toString();
|
||||
}
|
||||
|
||||
Connector.Argument argument = arguments.get(name);
|
||||
if (argument == null) {
|
||||
throw new IllegalArgumentException
|
||||
(MessageOutput.format("Argument is not defined for connector:",
|
||||
new Object [] {name, connector.name()}));
|
||||
}
|
||||
argument.setValue(value);
|
||||
|
||||
argString = argString.substring(endPosition); // Remove what was just parsed...
|
||||
m = p.matcher(argString); // and parse again on what is left.
|
||||
}
|
||||
if ((! argString.equals(",")) && (argString.length() > 0)) {
|
||||
/*
|
||||
* It is an error if any part of argString is left over,
|
||||
* unless it was empty to begin with.
|
||||
*/
|
||||
throw new IllegalArgumentException
|
||||
(MessageOutput.format("Illegal connector argument", argString));
|
||||
}
|
||||
return arguments;
|
||||
}
|
||||
|
||||
private static boolean isEnclosed(String value, String enclosingChar) {
|
||||
if (value.indexOf(enclosingChar) == 0) {
|
||||
int lastIndex = value.lastIndexOf(enclosingChar);
|
||||
if (lastIndex > 0 && lastIndex == value.length() - 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static List<String> splitStringAtNonEnclosedWhiteSpace(String value) throws IllegalArgumentException {
|
||||
List<String> al = new ArrayList<String>();
|
||||
char[] arr;
|
||||
int startPosition = 0;
|
||||
int endPosition = 0;
|
||||
final char SPACE = ' ';
|
||||
final char DOUBLEQ = '"';
|
||||
final char SINGLEQ = '\'';
|
||||
|
||||
/*
|
||||
* An "open" or "active" enclosing state is where
|
||||
* the first valid start quote qualifier is found,
|
||||
* and there is a search in progress for the
|
||||
* relevant end matching quote
|
||||
*
|
||||
* enclosingTargetChar set to SPACE
|
||||
* is used to signal a non open enclosing state
|
||||
*/
|
||||
char enclosingTargetChar = SPACE;
|
||||
|
||||
if (value == null) {
|
||||
throw new IllegalArgumentException
|
||||
(MessageOutput.format("value string is null"));
|
||||
}
|
||||
|
||||
// split parameter string into individual chars
|
||||
arr = value.toCharArray();
|
||||
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
switch (arr[i]) {
|
||||
case SPACE: {
|
||||
// do nothing for spaces
|
||||
// unless last in array
|
||||
if (isLastChar(arr, i)) {
|
||||
endPosition = i;
|
||||
// break for substring creation
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
case DOUBLEQ:
|
||||
case SINGLEQ: {
|
||||
if (enclosingTargetChar == arr[i]) {
|
||||
// potential match to close open enclosing
|
||||
if (isNextCharWhitespace(arr, i)) {
|
||||
// if peek next is whitespace
|
||||
// then enclosing is a valid substring
|
||||
endPosition = i;
|
||||
// reset enclosing target char
|
||||
enclosingTargetChar = SPACE;
|
||||
// break for substring creation
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (enclosingTargetChar == SPACE) {
|
||||
// no open enclosing state
|
||||
// handle as normal char
|
||||
if (isPreviousCharWhitespace(arr, i)) {
|
||||
startPosition = i;
|
||||
// peek forward for end candidates
|
||||
if (value.indexOf(arr[i], i + 1) >= 0) {
|
||||
// set open enclosing state by
|
||||
// setting up the target char
|
||||
enclosingTargetChar = arr[i];
|
||||
} else {
|
||||
// no more target chars left to match
|
||||
// end enclosing, handle as normal char
|
||||
if (isNextCharWhitespace(arr, i)) {
|
||||
endPosition = i;
|
||||
// break for substring creation
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
default: {
|
||||
// normal non-space, non-" and non-' chars
|
||||
if (enclosingTargetChar == SPACE) {
|
||||
// no open enclosing state
|
||||
if (isPreviousCharWhitespace(arr, i)) {
|
||||
// start of space delim substring
|
||||
startPosition = i;
|
||||
}
|
||||
if (isNextCharWhitespace(arr, i)) {
|
||||
// end of space delim substring
|
||||
endPosition = i;
|
||||
// break for substring creation
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// break's end up here
|
||||
if (startPosition > endPosition) {
|
||||
throw new IllegalArgumentException
|
||||
(MessageOutput.format("Illegal option values"));
|
||||
}
|
||||
|
||||
// extract substring and add to List<String>
|
||||
al.add(value.substring(startPosition, ++endPosition));
|
||||
|
||||
// set new start position
|
||||
i = startPosition = endPosition;
|
||||
|
||||
} // for loop
|
||||
|
||||
return al;
|
||||
}
|
||||
|
||||
static private boolean isPreviousCharWhitespace(char[] arr, int curr_pos) {
|
||||
return isCharWhitespace(arr, curr_pos - 1);
|
||||
}
|
||||
|
||||
static private boolean isNextCharWhitespace(char[] arr, int curr_pos) {
|
||||
return isCharWhitespace(arr, curr_pos + 1);
|
||||
}
|
||||
|
||||
static private boolean isCharWhitespace(char[] arr, int pos) {
|
||||
if (pos < 0 || pos >= arr.length) {
|
||||
// outside arraybounds is considered an implicit space
|
||||
return true;
|
||||
}
|
||||
if (arr[pos] == ' ') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static private boolean isLastChar(char[] arr, int pos) {
|
||||
return (pos + 1 == arr.length);
|
||||
}
|
||||
|
||||
VMConnection(String connectSpec, int traceFlags) {
|
||||
String nameString;
|
||||
String argString;
|
||||
int index = connectSpec.indexOf(':');
|
||||
if (index == -1) {
|
||||
nameString = connectSpec;
|
||||
argString = "";
|
||||
} else {
|
||||
nameString = connectSpec.substring(0, index);
|
||||
argString = connectSpec.substring(index + 1);
|
||||
}
|
||||
|
||||
connector = findConnector(nameString);
|
||||
if (connector == null) {
|
||||
throw new IllegalArgumentException
|
||||
(MessageOutput.format("No connector named:", nameString));
|
||||
}
|
||||
|
||||
connectorArgs = parseConnectorArgs(connector, argString);
|
||||
this.traceFlags = traceFlags;
|
||||
}
|
||||
|
||||
synchronized VirtualMachine open() {
|
||||
if (connector instanceof LaunchingConnector) {
|
||||
vm = launchTarget();
|
||||
} else if (connector instanceof AttachingConnector) {
|
||||
vm = attachTarget();
|
||||
} else if (connector instanceof ListeningConnector) {
|
||||
vm = listenTarget();
|
||||
} else {
|
||||
throw new InternalError
|
||||
(MessageOutput.format("Invalid connect type"));
|
||||
}
|
||||
vm.setDebugTraceMode(traceFlags);
|
||||
if (vm.canBeModified()){
|
||||
setEventRequests(vm);
|
||||
resolveEventRequests();
|
||||
}
|
||||
/*
|
||||
* Now that the vm connection is open, fetch the debugee
|
||||
* classpath and set up a default sourcepath.
|
||||
* (Unless user supplied a sourcepath on the command line)
|
||||
* (Bug ID 4186582)
|
||||
*/
|
||||
if (Env.getSourcePath().length() == 0) {
|
||||
if (vm instanceof PathSearchingVirtualMachine) {
|
||||
PathSearchingVirtualMachine psvm =
|
||||
(PathSearchingVirtualMachine) vm;
|
||||
Env.setSourcePath(psvm.classPath());
|
||||
} else {
|
||||
Env.setSourcePath(".");
|
||||
}
|
||||
}
|
||||
|
||||
return vm;
|
||||
}
|
||||
|
||||
boolean setConnectorArg(String name, String value) {
|
||||
/*
|
||||
* Too late if the connection already made
|
||||
*/
|
||||
if (vm != null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Connector.Argument argument = connectorArgs.get(name);
|
||||
if (argument == null) {
|
||||
return false;
|
||||
}
|
||||
argument.setValue(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
String connectorArg(String name) {
|
||||
Connector.Argument argument = connectorArgs.get(name);
|
||||
if (argument == null) {
|
||||
return "";
|
||||
}
|
||||
return argument.value();
|
||||
}
|
||||
|
||||
public synchronized VirtualMachine vm() {
|
||||
if (vm == null) {
|
||||
throw new VMNotConnectedException();
|
||||
} else {
|
||||
return vm;
|
||||
}
|
||||
}
|
||||
|
||||
boolean isOpen() {
|
||||
return (vm != null);
|
||||
}
|
||||
|
||||
boolean isLaunch() {
|
||||
return (connector instanceof LaunchingConnector);
|
||||
}
|
||||
|
||||
public void disposeVM() {
|
||||
try {
|
||||
if (vm != null) {
|
||||
vm.dispose();
|
||||
vm = null;
|
||||
}
|
||||
} finally {
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
process = null;
|
||||
}
|
||||
waitOutputComplete();
|
||||
}
|
||||
}
|
||||
|
||||
private void setEventRequests(VirtualMachine vm) {
|
||||
EventRequestManager erm = vm.eventRequestManager();
|
||||
|
||||
// Normally, we want all uncaught exceptions. We request them
|
||||
// via the same mechanism as Commands.commandCatchException()
|
||||
// so the user can ignore them later if they are not
|
||||
// interested.
|
||||
// FIXME: this works but generates spurious messages on stdout
|
||||
// during startup:
|
||||
// Set uncaught java.lang.Throwable
|
||||
// Set deferred uncaught java.lang.Throwable
|
||||
Commands evaluator = new Commands();
|
||||
evaluator.commandCatchException
|
||||
(new StringTokenizer("uncaught java.lang.Throwable"));
|
||||
|
||||
ThreadStartRequest tsr = erm.createThreadStartRequest();
|
||||
tsr.enable();
|
||||
ThreadDeathRequest tdr = erm.createThreadDeathRequest();
|
||||
tdr.enable();
|
||||
}
|
||||
|
||||
private void resolveEventRequests() {
|
||||
Env.specList.resolveAll();
|
||||
}
|
||||
|
||||
private void dumpStream(InputStream stream) throws IOException {
|
||||
BufferedReader in =
|
||||
new BufferedReader(new InputStreamReader(stream));
|
||||
int i;
|
||||
try {
|
||||
while ((i = in.read()) != -1) {
|
||||
MessageOutput.printDirect((char)i);// Special case: use
|
||||
// printDirect()
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
String s = ex.getMessage();
|
||||
if (!s.startsWith("Bad file number")) {
|
||||
throw ex;
|
||||
}
|
||||
// else we got a Bad file number IOException which just means
|
||||
// that the debuggee has gone away. We'll just treat it the
|
||||
// same as if we got an EOF.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Thread that will retrieve and display any output.
|
||||
* Needs to be high priority, else debugger may exit before
|
||||
* it can be displayed.
|
||||
*/
|
||||
private void displayRemoteOutput(final InputStream stream) {
|
||||
Thread thr = new Thread("output reader") {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
dumpStream(stream);
|
||||
} catch (IOException ex) {
|
||||
MessageOutput.fatalError("Failed reading output");
|
||||
} finally {
|
||||
notifyOutputComplete();
|
||||
}
|
||||
}
|
||||
};
|
||||
thr.setPriority(Thread.MAX_PRIORITY-1);
|
||||
thr.start();
|
||||
}
|
||||
|
||||
private void dumpFailedLaunchInfo(Process process) {
|
||||
try {
|
||||
dumpStream(process.getErrorStream());
|
||||
dumpStream(process.getInputStream());
|
||||
} catch (IOException e) {
|
||||
MessageOutput.println("Unable to display process output:",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/* launch child target vm */
|
||||
private VirtualMachine launchTarget() {
|
||||
LaunchingConnector launcher = (LaunchingConnector)connector;
|
||||
try {
|
||||
VirtualMachine vm = launcher.launch(connectorArgs);
|
||||
process = vm.process();
|
||||
displayRemoteOutput(process.getErrorStream());
|
||||
displayRemoteOutput(process.getInputStream());
|
||||
return vm;
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
MessageOutput.fatalError("Unable to launch target VM.");
|
||||
} catch (IllegalConnectorArgumentsException icae) {
|
||||
icae.printStackTrace();
|
||||
MessageOutput.fatalError("Internal debugger error.");
|
||||
} catch (VMStartException vmse) {
|
||||
MessageOutput.println("vmstartexception", vmse.getMessage());
|
||||
MessageOutput.println();
|
||||
dumpFailedLaunchInfo(vmse.process());
|
||||
MessageOutput.fatalError("Target VM failed to initialize.");
|
||||
}
|
||||
return null; // Shuts up the compiler
|
||||
}
|
||||
|
||||
/* attach to running target vm */
|
||||
private VirtualMachine attachTarget() {
|
||||
AttachingConnector attacher = (AttachingConnector)connector;
|
||||
try {
|
||||
return attacher.attach(connectorArgs);
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
MessageOutput.fatalError("Unable to attach to target VM.");
|
||||
} catch (IllegalConnectorArgumentsException icae) {
|
||||
icae.printStackTrace();
|
||||
MessageOutput.fatalError("Internal debugger error.");
|
||||
}
|
||||
return null; // Shuts up the compiler
|
||||
}
|
||||
|
||||
/* listen for connection from target vm */
|
||||
private VirtualMachine listenTarget() {
|
||||
ListeningConnector listener = (ListeningConnector)connector;
|
||||
try {
|
||||
String retAddress = listener.startListening(connectorArgs);
|
||||
MessageOutput.println("Listening at address:", retAddress);
|
||||
vm = listener.accept(connectorArgs);
|
||||
listener.stopListening(connectorArgs);
|
||||
return vm;
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
MessageOutput.fatalError("Unable to attach to target VM.");
|
||||
} catch (IllegalConnectorArgumentsException icae) {
|
||||
icae.printStackTrace();
|
||||
MessageOutput.fatalError("Internal debugger error.");
|
||||
}
|
||||
return null; // Shuts up the compiler
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is provided to illustrate the usage of a given feature
|
||||
* or technique and has been deliberately simplified. Additional steps
|
||||
* required for a production-quality application, such as security checks,
|
||||
* input validation and proper error handling, might not be present in
|
||||
* this sample code.
|
||||
*/
|
||||
|
||||
|
||||
package com.sun.tools.example.debug.tty;
|
||||
|
||||
public class VMNotConnectedException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = -7433430494903950165L;
|
||||
|
||||
public VMNotConnectedException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public VMNotConnectedException(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is provided to illustrate the usage of a given feature
|
||||
* or technique and has been deliberately simplified. Additional steps
|
||||
* required for a production-quality application, such as security checks,
|
||||
* input validation and proper error handling, might not be present in
|
||||
* this sample code.
|
||||
*/
|
||||
|
||||
|
||||
package com.sun.tools.example.debug.tty;
|
||||
|
||||
abstract class WatchpointSpec extends EventRequestSpec {
|
||||
final String fieldId;
|
||||
|
||||
WatchpointSpec(ReferenceTypeSpec refSpec, String fieldId)
|
||||
throws MalformedMemberNameException {
|
||||
super(refSpec);
|
||||
this.fieldId = fieldId;
|
||||
if (!isJavaIdentifier(fieldId)) {
|
||||
throw new MalformedMemberNameException(fieldId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return refSpec.hashCode() + fieldId.hashCode() +
|
||||
getClass().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof WatchpointSpec) {
|
||||
WatchpointSpec watchpoint = (WatchpointSpec)obj;
|
||||
|
||||
return fieldId.equals(watchpoint.fieldId) &&
|
||||
refSpec.equals(watchpoint.refSpec) &&
|
||||
getClass().equals(watchpoint.getClass());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
String errorMessageFor(Exception e) {
|
||||
if (e instanceof NoSuchFieldException) {
|
||||
return (MessageOutput.format("No field in",
|
||||
new Object [] {fieldId, refSpec.toString()}));
|
||||
} else {
|
||||
return super.errorMessageFor(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user