feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class AccessWatchpointSpec extends WatchpointSpec {
|
||||
|
||||
AccessWatchpointSpec(EventRequestSpecList specs,
|
||||
ReferenceTypeSpec refSpec, String fieldId) {
|
||||
super(specs, refSpec, fieldId);
|
||||
}
|
||||
|
||||
/**
|
||||
* The 'refType' is known to match.
|
||||
*/
|
||||
@Override
|
||||
void resolve(ReferenceType refType) throws InvalidTypeException,
|
||||
NoSuchFieldException {
|
||||
if (!(refType instanceof ClassType)) {
|
||||
throw new InvalidTypeException();
|
||||
}
|
||||
Field field = refType.fieldByName(fieldId);
|
||||
if (field == null) {
|
||||
throw new NoSuchFieldException(fieldId);
|
||||
}
|
||||
setRequest(refType.virtualMachine().eventRequestManager()
|
||||
.createAccessWatchpointRequest(field));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return (obj instanceof AccessWatchpointSpec) && super.equals(obj);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
public class AmbiguousMethodException extends Exception
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = 7793370943251707514L;
|
||||
|
||||
public AmbiguousMethodException()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public AmbiguousMethodException(String s)
|
||||
{
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
public abstract class BreakpointSpec extends EventRequestSpec {
|
||||
|
||||
BreakpointSpec(EventRequestSpecList specs, ReferenceTypeSpec refSpec) {
|
||||
super(specs, refSpec);
|
||||
}
|
||||
|
||||
@Override
|
||||
void notifySet(SpecListener listener, SpecEvent evt) {
|
||||
listener.breakpointSet(evt);
|
||||
}
|
||||
|
||||
@Override
|
||||
void notifyDeferred(SpecListener listener, SpecEvent evt) {
|
||||
listener.breakpointDeferred(evt);
|
||||
}
|
||||
|
||||
@Override
|
||||
void notifyResolved(SpecListener listener, SpecEvent evt) {
|
||||
listener.breakpointResolved(evt);
|
||||
}
|
||||
|
||||
@Override
|
||||
void notifyDeleted(SpecListener listener, SpecEvent evt) {
|
||||
listener.breakpointDeleted(evt);
|
||||
}
|
||||
|
||||
@Override
|
||||
void notifyError(SpecListener listener, SpecErrorEvent evt) {
|
||||
listener.breakpointError(evt);
|
||||
}
|
||||
}
|
||||
309
jdkSrc/jdk8/com/sun/tools/example/debug/bdi/ChildSession.java
Normal file
309
jdkSrc/jdk8/com/sun/tools/example/debug/bdi/ChildSession.java
Normal file
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.connect.LaunchingConnector;
|
||||
import com.sun.jdi.connect.Connector;
|
||||
import com.sun.jdi.connect.VMStartException;
|
||||
import com.sun.jdi.connect.IllegalConnectorArgumentsException;
|
||||
import java.io.*;
|
||||
import java.util.Map;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
|
||||
class ChildSession extends Session {
|
||||
|
||||
private Process process;
|
||||
|
||||
private PrintWriter in;
|
||||
private BufferedReader out;
|
||||
private BufferedReader err;
|
||||
|
||||
private InputListener input;
|
||||
private OutputListener output;
|
||||
private OutputListener error;
|
||||
|
||||
public ChildSession(ExecutionManager runtime,
|
||||
String userVMArgs, String cmdLine,
|
||||
InputListener input,
|
||||
OutputListener output,
|
||||
OutputListener error,
|
||||
OutputListener diagnostics) {
|
||||
this(runtime, getVM(diagnostics, userVMArgs, cmdLine),
|
||||
input, output, error, diagnostics);
|
||||
}
|
||||
|
||||
public ChildSession(ExecutionManager runtime,
|
||||
LaunchingConnector connector,
|
||||
Map<String, Connector.Argument> arguments,
|
||||
InputListener input,
|
||||
OutputListener output,
|
||||
OutputListener error,
|
||||
OutputListener diagnostics) {
|
||||
this(runtime, generalGetVM(diagnostics, connector, arguments),
|
||||
input, output, error, diagnostics);
|
||||
}
|
||||
|
||||
private ChildSession(ExecutionManager runtime,
|
||||
VirtualMachine vm,
|
||||
InputListener input,
|
||||
OutputListener output,
|
||||
OutputListener error,
|
||||
OutputListener diagnostics) {
|
||||
super(vm, runtime, diagnostics);
|
||||
this.input = input;
|
||||
this.output = output;
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean attach() {
|
||||
|
||||
if (!connectToVMProcess()) {
|
||||
diagnostics.putString("Could not launch VM");
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a Thread that will retrieve and display any output.
|
||||
* Needs to be high priority, else debugger may exit before
|
||||
* it can be displayed.
|
||||
*/
|
||||
|
||||
//### Rename InputWriter and OutputReader classes
|
||||
//### Thread priorities cribbed from ttydebug. Think about them.
|
||||
|
||||
OutputReader outputReader =
|
||||
new OutputReader("output reader", "output",
|
||||
out, output, diagnostics);
|
||||
outputReader.setPriority(Thread.MAX_PRIORITY-1);
|
||||
outputReader.start();
|
||||
|
||||
OutputReader errorReader =
|
||||
new OutputReader("error reader", "error",
|
||||
err, error, diagnostics);
|
||||
errorReader.setPriority(Thread.MAX_PRIORITY-1);
|
||||
errorReader.start();
|
||||
|
||||
InputWriter inputWriter =
|
||||
new InputWriter("input writer", in, input);
|
||||
inputWriter.setPriority(Thread.MAX_PRIORITY-1);
|
||||
inputWriter.start();
|
||||
|
||||
if (!super.attach()) {
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
process = null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//### debug
|
||||
//System.out.println("IO after attach: "+ inputWriter + " " + outputReader + " "+ errorReader);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detach() {
|
||||
|
||||
//### debug
|
||||
//System.out.println("IO before detach: "+ inputWriter + " " + outputReader + " "+ errorReader);
|
||||
|
||||
super.detach();
|
||||
|
||||
/*
|
||||
inputWriter.quit();
|
||||
outputReader.quit();
|
||||
errorReader.quit();
|
||||
*/
|
||||
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
process = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch child java interpreter, return host:port
|
||||
*/
|
||||
|
||||
static private void dumpStream(OutputListener diagnostics,
|
||||
InputStream stream) throws IOException {
|
||||
BufferedReader in =
|
||||
new BufferedReader(new InputStreamReader(stream));
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
diagnostics.putString(line);
|
||||
}
|
||||
}
|
||||
|
||||
static private void dumpFailedLaunchInfo(OutputListener diagnostics,
|
||||
Process process) {
|
||||
try {
|
||||
dumpStream(diagnostics, process.getErrorStream());
|
||||
dumpStream(diagnostics, process.getInputStream());
|
||||
} catch (IOException e) {
|
||||
diagnostics.putString("Unable to display process output: " +
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
static private VirtualMachine getVM(OutputListener diagnostics,
|
||||
String userVMArgs,
|
||||
String cmdLine) {
|
||||
VirtualMachineManager manager = Bootstrap.virtualMachineManager();
|
||||
LaunchingConnector connector = manager.defaultConnector();
|
||||
Map<String, Connector.Argument> arguments = connector.defaultArguments();
|
||||
arguments.get("options").setValue(userVMArgs);
|
||||
arguments.get("main").setValue(cmdLine);
|
||||
return generalGetVM(diagnostics, connector, arguments);
|
||||
}
|
||||
|
||||
static private VirtualMachine generalGetVM(OutputListener diagnostics,
|
||||
LaunchingConnector connector,
|
||||
Map<String, Connector.Argument> arguments) {
|
||||
VirtualMachine vm = null;
|
||||
try {
|
||||
diagnostics.putString("Starting child.");
|
||||
vm = connector.launch(arguments);
|
||||
} catch (IOException ioe) {
|
||||
diagnostics.putString("Unable to start child: " + ioe.getMessage());
|
||||
} catch (IllegalConnectorArgumentsException icae) {
|
||||
diagnostics.putString("Unable to start child: " + icae.getMessage());
|
||||
} catch (VMStartException vmse) {
|
||||
diagnostics.putString("Unable to start child: " + vmse.getMessage() + '\n');
|
||||
dumpFailedLaunchInfo(diagnostics, vmse.process());
|
||||
}
|
||||
return vm;
|
||||
}
|
||||
|
||||
private boolean connectToVMProcess() {
|
||||
if (vm == null) {
|
||||
return false;
|
||||
}
|
||||
process = vm.process();
|
||||
in = new PrintWriter(new OutputStreamWriter(process.getOutputStream()));
|
||||
//### Note small buffer sizes!
|
||||
out = new BufferedReader(new InputStreamReader(process.getInputStream()), 1);
|
||||
err = new BufferedReader(new InputStreamReader(process.getErrorStream()), 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Threads to handle application input/output.
|
||||
*/
|
||||
|
||||
private static class OutputReader extends Thread {
|
||||
|
||||
private String streamName;
|
||||
private BufferedReader stream;
|
||||
private OutputListener output;
|
||||
private OutputListener diagnostics;
|
||||
private boolean running = true;
|
||||
private char[] buffer = new char[512];
|
||||
|
||||
OutputReader(String threadName,
|
||||
String streamName,
|
||||
BufferedReader stream,
|
||||
OutputListener output,
|
||||
OutputListener diagnostics) {
|
||||
super(threadName);
|
||||
this.streamName = streamName;
|
||||
this.stream = stream;
|
||||
this.output = output;
|
||||
this.diagnostics = diagnostics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
int count;
|
||||
while (running && (count = stream.read(buffer, 0, 512)) != -1) {
|
||||
if (count > 0) {
|
||||
// Run in Swing event dispatcher thread.
|
||||
final String chars = new String(buffer, 0, count);
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
output.putString(chars);
|
||||
}
|
||||
});
|
||||
}
|
||||
//### Should we sleep briefly here?
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Run in Swing event dispatcher thread.
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
diagnostics.putString("IO error reading " +
|
||||
streamName +
|
||||
" stream of child java interpreter");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class InputWriter extends Thread {
|
||||
|
||||
private PrintWriter stream;
|
||||
private InputListener input;
|
||||
private boolean running = true;
|
||||
|
||||
InputWriter(String threadName,
|
||||
PrintWriter stream,
|
||||
InputListener input) {
|
||||
super(threadName);
|
||||
this.stream = stream;
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
String line;
|
||||
while (running) {
|
||||
line = input.getLine();
|
||||
stream.println(line);
|
||||
// Should not be needed for println above!
|
||||
stream.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
public class EvaluationException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 4947109680354951694L;
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.request.EventRequest;
|
||||
|
||||
abstract public class EventRequestSpec {
|
||||
|
||||
static final int STATUS_UNRESOLVED = 1;
|
||||
static final int STATUS_RESOLVED = 2;
|
||||
static final int STATUS_ERROR = 3;
|
||||
|
||||
static final Object specPropertyKey = "spec";
|
||||
|
||||
final EventRequestSpecList specs;
|
||||
final ReferenceTypeSpec refSpec;
|
||||
EventRequest request = null;
|
||||
|
||||
int status = STATUS_UNRESOLVED;
|
||||
|
||||
EventRequestSpec(EventRequestSpecList specs, ReferenceTypeSpec refSpec) {
|
||||
this.specs = specs;
|
||||
this.refSpec = refSpec;
|
||||
}
|
||||
|
||||
void setRequest(EventRequest request) {
|
||||
this.request = request;
|
||||
request.putProperty(specPropertyKey, this);
|
||||
request.enable();
|
||||
}
|
||||
|
||||
/**
|
||||
* The 'refType' is known to match.
|
||||
*/
|
||||
abstract void resolve(ReferenceType refType) throws Exception;
|
||||
|
||||
abstract void notifySet(SpecListener listener, SpecEvent evt);
|
||||
abstract void notifyDeferred(SpecListener listener, SpecEvent evt);
|
||||
abstract void notifyResolved(SpecListener listener, SpecEvent evt);
|
||||
abstract void notifyDeleted(SpecListener listener, SpecEvent evt);
|
||||
abstract void notifyError(SpecListener listener, SpecErrorEvent evt);
|
||||
|
||||
/**
|
||||
* The 'refType' is known to match.
|
||||
*/
|
||||
void resolveNotify(ReferenceType refType) {
|
||||
try {
|
||||
resolve(refType);
|
||||
status = STATUS_RESOLVED;
|
||||
specs.notifyResolved(this);
|
||||
} catch(Exception exc) {
|
||||
status = STATUS_ERROR;
|
||||
specs.notifyError(this, exc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See if 'refType' matches and resolve.
|
||||
*/
|
||||
void attemptResolve(ReferenceType refType) {
|
||||
if (!isResolved() && refSpec.matches(refType)) {
|
||||
resolveNotify(refType);
|
||||
}
|
||||
}
|
||||
|
||||
void attemptImmediateResolve(VirtualMachine vm) {
|
||||
// try to resolve immediately
|
||||
for (ReferenceType refType : vm.allClasses()) {
|
||||
if (refSpec.matches(refType)) {
|
||||
try {
|
||||
resolve(refType);
|
||||
status = STATUS_RESOLVED;
|
||||
specs.notifySet(this);
|
||||
} catch(Exception exc) {
|
||||
status = STATUS_ERROR;
|
||||
specs.notifyError(this, exc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
specs.notifyDeferred(this);
|
||||
}
|
||||
|
||||
public EventRequest getEventRequest() {
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this spec has been resolved.
|
||||
*/
|
||||
public boolean isResolved() {
|
||||
return status == STATUS_RESOLVED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this spec has not yet been resolved.
|
||||
*/
|
||||
public boolean isUnresolved() {
|
||||
return status == STATUS_UNRESOLVED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this spec is unresolvable due to error.
|
||||
*/
|
||||
public boolean isErroneous() {
|
||||
return status == STATUS_ERROR;
|
||||
}
|
||||
|
||||
public String getStatusString() {
|
||||
switch (status) {
|
||||
case STATUS_RESOLVED:
|
||||
return "resolved";
|
||||
case STATUS_UNRESOLVED:
|
||||
return "deferred";
|
||||
case STATUS_ERROR:
|
||||
return "erroneous";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
boolean isJavaIdentifier(String s) {
|
||||
return Utils.isJavaIdentifier(s);
|
||||
}
|
||||
|
||||
public String errorMessageFor(Exception e) {
|
||||
if (e instanceof IllegalArgumentException) {
|
||||
return ("Invalid command syntax");
|
||||
} else if (e instanceof RuntimeException) {
|
||||
// A runtime exception that we were not expecting
|
||||
throw (RuntimeException)e;
|
||||
} else {
|
||||
return ("Internal error; unable to set" + this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.request.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
class EventRequestSpecList {
|
||||
|
||||
// all specs
|
||||
private List<EventRequestSpec> eventRequestSpecs = Collections.synchronizedList(
|
||||
new ArrayList<EventRequestSpec>());
|
||||
|
||||
final ExecutionManager runtime;
|
||||
|
||||
EventRequestSpecList(ExecutionManager runtime) {
|
||||
this.runtime = runtime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve all deferred eventRequests waiting for 'refType'.
|
||||
*/
|
||||
void resolve(ReferenceType refType) {
|
||||
synchronized(eventRequestSpecs) {
|
||||
for (EventRequestSpec spec : eventRequestSpecs) {
|
||||
spec.attemptResolve(refType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void install(EventRequestSpec ers, VirtualMachine vm) {
|
||||
synchronized (eventRequestSpecs) {
|
||||
eventRequestSpecs.add(ers);
|
||||
}
|
||||
if (vm != null) {
|
||||
ers.attemptImmediateResolve(vm);
|
||||
}
|
||||
}
|
||||
|
||||
BreakpointSpec
|
||||
createClassLineBreakpoint(String classPattern, int line) {
|
||||
ReferenceTypeSpec refSpec =
|
||||
new PatternReferenceTypeSpec(classPattern);
|
||||
return new LineBreakpointSpec(this, refSpec, line);
|
||||
}
|
||||
|
||||
BreakpointSpec
|
||||
createSourceLineBreakpoint(String sourceName, int line) {
|
||||
ReferenceTypeSpec refSpec =
|
||||
new SourceNameReferenceTypeSpec(sourceName, line);
|
||||
return new LineBreakpointSpec(this, refSpec, line);
|
||||
}
|
||||
|
||||
BreakpointSpec
|
||||
createMethodBreakpoint(String classPattern,
|
||||
String methodId, List<String> methodArgs) {
|
||||
ReferenceTypeSpec refSpec =
|
||||
new PatternReferenceTypeSpec(classPattern);
|
||||
return new MethodBreakpointSpec(this, refSpec,
|
||||
methodId, methodArgs);
|
||||
}
|
||||
|
||||
ExceptionSpec
|
||||
createExceptionIntercept(String classPattern,
|
||||
boolean notifyCaught,
|
||||
boolean notifyUncaught) {
|
||||
ReferenceTypeSpec refSpec =
|
||||
new PatternReferenceTypeSpec(classPattern);
|
||||
return new ExceptionSpec(this, refSpec,
|
||||
notifyCaught, notifyUncaught);
|
||||
}
|
||||
|
||||
AccessWatchpointSpec
|
||||
createAccessWatchpoint(String classPattern, String fieldId) {
|
||||
ReferenceTypeSpec refSpec =
|
||||
new PatternReferenceTypeSpec(classPattern);
|
||||
return new AccessWatchpointSpec(this, refSpec, fieldId);
|
||||
}
|
||||
|
||||
ModificationWatchpointSpec
|
||||
createModificationWatchpoint(String classPattern, String fieldId) {
|
||||
ReferenceTypeSpec refSpec =
|
||||
new PatternReferenceTypeSpec(classPattern);
|
||||
return new ModificationWatchpointSpec(this, refSpec, fieldId);
|
||||
}
|
||||
|
||||
void delete(EventRequestSpec ers) {
|
||||
EventRequest request = ers.getEventRequest();
|
||||
synchronized (eventRequestSpecs) {
|
||||
eventRequestSpecs.remove(ers);
|
||||
}
|
||||
if (request != null) {
|
||||
request.virtualMachine().eventRequestManager()
|
||||
.deleteEventRequest(request);
|
||||
}
|
||||
notifyDeleted(ers);
|
||||
//### notify delete - here?
|
||||
}
|
||||
|
||||
List<EventRequestSpec> eventRequestSpecs() {
|
||||
// We need to make a copy to avoid synchronization problems
|
||||
synchronized (eventRequestSpecs) {
|
||||
return new ArrayList<EventRequestSpec>(eventRequestSpecs);
|
||||
}
|
||||
}
|
||||
|
||||
// -------- notify routines --------------------
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Vector<SpecListener> specListeners() {
|
||||
return (Vector<SpecListener>)runtime.specListeners.clone();
|
||||
}
|
||||
|
||||
void notifySet(EventRequestSpec spec) {
|
||||
Vector<SpecListener> l = specListeners();
|
||||
SpecEvent evt = new SpecEvent(spec);
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
spec.notifySet(l.elementAt(i), evt);
|
||||
}
|
||||
}
|
||||
|
||||
void notifyDeferred(EventRequestSpec spec) {
|
||||
Vector<SpecListener> l = specListeners();
|
||||
SpecEvent evt = new SpecEvent(spec);
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
spec.notifyDeferred(l.elementAt(i), evt);
|
||||
}
|
||||
}
|
||||
|
||||
void notifyDeleted(EventRequestSpec spec) {
|
||||
Vector<SpecListener> l = specListeners();
|
||||
SpecEvent evt = new SpecEvent(spec);
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
spec.notifyDeleted(l.elementAt(i), evt);
|
||||
}
|
||||
}
|
||||
|
||||
void notifyResolved(EventRequestSpec spec) {
|
||||
Vector<SpecListener> l = specListeners();
|
||||
SpecEvent evt = new SpecEvent(spec);
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
spec.notifyResolved(l.elementAt(i), evt);
|
||||
}
|
||||
}
|
||||
|
||||
void notifyError(EventRequestSpec spec, Exception exc) {
|
||||
Vector<SpecListener> l = specListeners();
|
||||
SpecErrorEvent evt = new SpecErrorEvent(spec, exc);
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
spec.notifyError(l.elementAt(i), evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
109
jdkSrc/jdk8/com/sun/tools/example/debug/bdi/ExceptionSpec.java
Normal file
109
jdkSrc/jdk8/com/sun/tools/example/debug/bdi/ExceptionSpec.java
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
import com.sun.jdi.ReferenceType;
|
||||
|
||||
public class ExceptionSpec extends EventRequestSpec {
|
||||
|
||||
boolean notifyCaught;
|
||||
boolean notifyUncaught;
|
||||
|
||||
ExceptionSpec(EventRequestSpecList specs, ReferenceTypeSpec refSpec,
|
||||
boolean notifyCaught, boolean notifyUncaught)
|
||||
{
|
||||
super(specs, refSpec);
|
||||
this.notifyCaught = notifyCaught;
|
||||
this.notifyUncaught = notifyUncaught;
|
||||
}
|
||||
|
||||
@Override
|
||||
void notifySet(SpecListener listener, SpecEvent evt) {
|
||||
listener.exceptionInterceptSet(evt);
|
||||
}
|
||||
|
||||
@Override
|
||||
void notifyDeferred(SpecListener listener, SpecEvent evt) {
|
||||
listener.exceptionInterceptDeferred(evt);
|
||||
}
|
||||
|
||||
@Override
|
||||
void notifyResolved(SpecListener listener, SpecEvent evt) {
|
||||
listener.exceptionInterceptResolved(evt);
|
||||
}
|
||||
|
||||
@Override
|
||||
void notifyDeleted(SpecListener listener, SpecEvent evt) {
|
||||
listener.exceptionInterceptDeleted(evt);
|
||||
}
|
||||
|
||||
@Override
|
||||
void notifyError(SpecListener listener, SpecErrorEvent evt) {
|
||||
listener.exceptionInterceptError(evt);
|
||||
}
|
||||
|
||||
/**
|
||||
* The 'refType' is known to match.
|
||||
*/
|
||||
@Override
|
||||
void resolve(ReferenceType refType) {
|
||||
setRequest(refType.virtualMachine().eventRequestManager()
|
||||
.createExceptionRequest(refType,
|
||||
notifyCaught, notifyUncaught));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return refSpec.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof ExceptionSpec) {
|
||||
ExceptionSpec es = (ExceptionSpec)obj;
|
||||
|
||||
return refSpec.equals(es.refSpec);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer("exception catch ");
|
||||
buffer.append(refSpec.toString());
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,824 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.request.*;
|
||||
import com.sun.jdi.connect.*;
|
||||
import com.sun.tools.example.debug.expr.ExpressionParser;
|
||||
import com.sun.tools.example.debug.expr.ParseException;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import com.sun.tools.example.debug.event.*;
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
/**
|
||||
* Move this towards being only state and functionality
|
||||
* that spans across Sessions (and thus VMs).
|
||||
*/
|
||||
public class ExecutionManager {
|
||||
|
||||
private Session session;
|
||||
|
||||
/**
|
||||
* Get/set JDI trace mode.
|
||||
*/
|
||||
int traceMode = VirtualMachine.TRACE_NONE;
|
||||
|
||||
////////////////// Listener registration //////////////////
|
||||
|
||||
// Session Listeners
|
||||
|
||||
ArrayList<SessionListener> sessionListeners = new ArrayList<SessionListener>();
|
||||
|
||||
public void addSessionListener(SessionListener listener) {
|
||||
sessionListeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeSessionListener(SessionListener listener) {
|
||||
sessionListeners.remove(listener);
|
||||
}
|
||||
|
||||
// Spec Listeners
|
||||
|
||||
ArrayList<SpecListener> specListeners = new ArrayList<SpecListener>();
|
||||
|
||||
public void addSpecListener(SpecListener cl) {
|
||||
specListeners.add(cl);
|
||||
}
|
||||
|
||||
public void removeSpecListener(SpecListener cl) {
|
||||
specListeners.remove(cl);
|
||||
}
|
||||
|
||||
// JDI Listeners
|
||||
|
||||
ArrayList<JDIListener> jdiListeners = new ArrayList<JDIListener>();
|
||||
|
||||
/**
|
||||
* Adds a JDIListener
|
||||
*/
|
||||
public void addJDIListener(JDIListener jl) {
|
||||
jdiListeners.add(jl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a JDIListener - at the specified position
|
||||
*/
|
||||
public void addJDIListener(int index, JDIListener jl) {
|
||||
jdiListeners.add(index, jl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a JDIListener
|
||||
*/
|
||||
public void removeJDIListener(JDIListener jl) {
|
||||
jdiListeners.remove(jl);
|
||||
}
|
||||
|
||||
// App Echo Listeners
|
||||
|
||||
private ArrayList<OutputListener> appEchoListeners = new ArrayList<OutputListener>();
|
||||
|
||||
public void addApplicationEchoListener(OutputListener l) {
|
||||
appEchoListeners.add(l);
|
||||
}
|
||||
|
||||
public void removeApplicationEchoListener(OutputListener l) {
|
||||
appEchoListeners.remove(l);
|
||||
}
|
||||
|
||||
// App Output Listeners
|
||||
|
||||
private ArrayList<OutputListener> appOutputListeners = new ArrayList<OutputListener>();
|
||||
|
||||
public void addApplicationOutputListener(OutputListener l) {
|
||||
appOutputListeners.add(l);
|
||||
}
|
||||
|
||||
public void removeApplicationOutputListener(OutputListener l) {
|
||||
appOutputListeners.remove(l);
|
||||
}
|
||||
|
||||
// App Error Listeners
|
||||
|
||||
private ArrayList<OutputListener> appErrorListeners = new ArrayList<OutputListener>();
|
||||
|
||||
public void addApplicationErrorListener(OutputListener l) {
|
||||
appErrorListeners.add(l);
|
||||
}
|
||||
|
||||
public void removeApplicationErrorListener(OutputListener l) {
|
||||
appErrorListeners.remove(l);
|
||||
}
|
||||
|
||||
// Diagnostic Listeners
|
||||
|
||||
private ArrayList<OutputListener> diagnosticsListeners = new ArrayList<OutputListener>();
|
||||
|
||||
public void addDiagnosticsListener(OutputListener l) {
|
||||
diagnosticsListeners.add(l);
|
||||
}
|
||||
|
||||
public void removeDiagnosticsListener(OutputListener l) {
|
||||
diagnosticsListeners.remove(l);
|
||||
}
|
||||
|
||||
/////////// End Listener Registration //////////////
|
||||
|
||||
//### We probably don't want this public
|
||||
public VirtualMachine vm() {
|
||||
return session == null ? null : session.vm;
|
||||
}
|
||||
|
||||
void ensureActiveSession() throws NoSessionException {
|
||||
if (session == null) {
|
||||
throw new NoSessionException();
|
||||
}
|
||||
}
|
||||
|
||||
public EventRequestManager eventRequestManager() {
|
||||
return vm() == null ? null : vm().eventRequestManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get JDI trace mode.
|
||||
*/
|
||||
public int getTraceMode(int mode) {
|
||||
return traceMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set JDI trace mode.
|
||||
*/
|
||||
public void setTraceMode(int mode) {
|
||||
traceMode = mode;
|
||||
if (session != null) {
|
||||
session.setTraceMode(mode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if VM is interrupted, i.e, present and not running.
|
||||
*/
|
||||
public boolean isInterrupted() /* should: throws NoSessionException */ {
|
||||
// ensureActiveSession();
|
||||
return session.interrupted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of ReferenceType objects for all
|
||||
* currently loaded classes and interfaces.
|
||||
* Array types are not returned.
|
||||
*/
|
||||
public List<ReferenceType> allClasses() throws NoSessionException {
|
||||
ensureActiveSession();
|
||||
return vm().allClasses();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a ReferenceType object for the currently
|
||||
* loaded class or interface whose fully-qualified
|
||||
* class name is specified, else return null if there
|
||||
* is none.
|
||||
*
|
||||
* In general, we must return a list of types, because
|
||||
* multiple class loaders could have loaded a class
|
||||
* with the same fully-qualified name.
|
||||
*/
|
||||
public List<ReferenceType> findClassesByName(String name) throws NoSessionException {
|
||||
ensureActiveSession();
|
||||
return vm().classesByName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of ReferenceType objects for all
|
||||
* currently loaded classes and interfaces whose name
|
||||
* matches the given pattern. The pattern syntax is
|
||||
* open to some future revision, but currently consists
|
||||
* of a fully-qualified class name in which the first
|
||||
* component may optionally be a "*" character, designating
|
||||
* an arbitrary prefix.
|
||||
*/
|
||||
public List<ReferenceType> findClassesMatchingPattern(String pattern)
|
||||
throws NoSessionException {
|
||||
ensureActiveSession();
|
||||
List<ReferenceType> result = new ArrayList<ReferenceType>(); //### Is default size OK?
|
||||
if (pattern.startsWith("*.")) {
|
||||
// Wildcard matches any leading package name.
|
||||
pattern = pattern.substring(1);
|
||||
for (ReferenceType type : vm().allClasses()) {
|
||||
if (type.name().endsWith(pattern)) {
|
||||
result.add(type);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
// It's a class name.
|
||||
return vm().classesByName(pattern);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a list of ThreadReference objects corresponding
|
||||
* to the threads that are currently active in the VM.
|
||||
* A thread is removed from the list just before the
|
||||
* thread terminates.
|
||||
*/
|
||||
|
||||
public List<ThreadReference> allThreads() throws NoSessionException {
|
||||
ensureActiveSession();
|
||||
return vm().allThreads();
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a list of ThreadGroupReference objects corresponding
|
||||
* to the top-level threadgroups that are currently active in the VM.
|
||||
* Note that a thread group may be empty, or contain no threads as
|
||||
* descendents.
|
||||
*/
|
||||
|
||||
public List<ThreadGroupReference> topLevelThreadGroups() throws NoSessionException {
|
||||
ensureActiveSession();
|
||||
return vm().topLevelThreadGroups();
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the system threadgroup.
|
||||
*/
|
||||
|
||||
public ThreadGroupReference systemThreadGroup()
|
||||
throws NoSessionException {
|
||||
ensureActiveSession();
|
||||
return vm().topLevelThreadGroups().get(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Evaluate an expression.
|
||||
*/
|
||||
|
||||
public Value evaluate(final StackFrame f, String expr)
|
||||
throws ParseException,
|
||||
InvocationException,
|
||||
InvalidTypeException,
|
||||
ClassNotLoadedException,
|
||||
NoSessionException,
|
||||
IncompatibleThreadStateException {
|
||||
ExpressionParser.GetFrame frameGetter = null;
|
||||
ensureActiveSession();
|
||||
if (f != null) {
|
||||
frameGetter = new ExpressionParser.GetFrame() {
|
||||
@Override
|
||||
public StackFrame get() /* throws IncompatibleThreadStateException */ {
|
||||
return f;
|
||||
}
|
||||
};
|
||||
}
|
||||
return ExpressionParser.evaluate(expr, vm(), frameGetter);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Start a new VM.
|
||||
*/
|
||||
|
||||
public void run(boolean suspended,
|
||||
String vmArgs,
|
||||
String className,
|
||||
String args) throws VMLaunchFailureException {
|
||||
|
||||
endSession();
|
||||
|
||||
//### Set a breakpoint on 'main' method.
|
||||
//### Would be cleaner if we could just bring up VM already suspended.
|
||||
if (suspended) {
|
||||
//### Set breakpoint at 'main(java.lang.String[])'.
|
||||
List<String> argList = new ArrayList<String>(1);
|
||||
argList.add("java.lang.String[]");
|
||||
createMethodBreakpoint(className, "main", argList);
|
||||
}
|
||||
|
||||
String cmdLine = className + " " + args;
|
||||
|
||||
startSession(new ChildSession(this, vmArgs, cmdLine,
|
||||
appInput, appOutput, appError,
|
||||
diagnostics));
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach to an existing VM.
|
||||
*/
|
||||
public void attach(String portName) throws VMLaunchFailureException {
|
||||
endSession();
|
||||
|
||||
//### Changes made here for connectors have broken the
|
||||
//### the 'Session' abstraction. The 'Session.attach()'
|
||||
//### method is intended to encapsulate all of the various
|
||||
//### ways in which session start-up can fail. (maddox 12/18/98)
|
||||
|
||||
/*
|
||||
* Now that attaches and launches both go through Connectors,
|
||||
* it may be worth creating a new subclass of Session for
|
||||
* attach sessions.
|
||||
*/
|
||||
VirtualMachineManager mgr = Bootstrap.virtualMachineManager();
|
||||
AttachingConnector connector = mgr.attachingConnectors().get(0);
|
||||
Map<String, Connector.Argument> arguments = connector.defaultArguments();
|
||||
arguments.get("port").setValue(portName);
|
||||
|
||||
Session newSession = internalAttach(connector, arguments);
|
||||
if (newSession != null) {
|
||||
startSession(newSession);
|
||||
}
|
||||
}
|
||||
|
||||
private Session internalAttach(AttachingConnector connector,
|
||||
Map<String, Connector.Argument> arguments) {
|
||||
try {
|
||||
VirtualMachine vm = connector.attach(arguments);
|
||||
return new Session(vm, this, diagnostics);
|
||||
} catch (IOException ioe) {
|
||||
diagnostics.putString("\n Unable to attach to target VM: " +
|
||||
ioe.getMessage());
|
||||
} catch (IllegalConnectorArgumentsException icae) {
|
||||
diagnostics.putString("\n Invalid connector arguments: " +
|
||||
icae.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Session internalListen(ListeningConnector connector,
|
||||
Map<String, Connector.Argument> arguments) {
|
||||
try {
|
||||
VirtualMachine vm = connector.accept(arguments);
|
||||
return new Session(vm, this, diagnostics);
|
||||
} catch (IOException ioe) {
|
||||
diagnostics.putString(
|
||||
"\n Unable to accept connection to target VM: " +
|
||||
ioe.getMessage());
|
||||
} catch (IllegalConnectorArgumentsException icae) {
|
||||
diagnostics.putString("\n Invalid connector arguments: " +
|
||||
icae.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Connect via user specified arguments
|
||||
* @return true on success
|
||||
*/
|
||||
public boolean explictStart(Connector connector, Map<String, Connector.Argument> arguments)
|
||||
throws VMLaunchFailureException {
|
||||
Session newSession = null;
|
||||
|
||||
endSession();
|
||||
|
||||
if (connector instanceof LaunchingConnector) {
|
||||
// we were launched, use ChildSession
|
||||
newSession = new ChildSession(this, (LaunchingConnector)connector,
|
||||
arguments,
|
||||
appInput, appOutput, appError,
|
||||
diagnostics);
|
||||
} else if (connector instanceof AttachingConnector) {
|
||||
newSession = internalAttach((AttachingConnector)connector,
|
||||
arguments);
|
||||
} else if (connector instanceof ListeningConnector) {
|
||||
newSession = internalListen((ListeningConnector)connector,
|
||||
arguments);
|
||||
} else {
|
||||
diagnostics.putString("\n Unknown connector: " + connector);
|
||||
}
|
||||
if (newSession != null) {
|
||||
startSession(newSession);
|
||||
}
|
||||
return newSession != null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Detach from VM. If VM was started by debugger, terminate it.
|
||||
*/
|
||||
public void detach() throws NoSessionException {
|
||||
ensureActiveSession();
|
||||
endSession();
|
||||
}
|
||||
|
||||
private void startSession(Session s) throws VMLaunchFailureException {
|
||||
if (!s.attach()) {
|
||||
throw new VMLaunchFailureException();
|
||||
}
|
||||
session = s;
|
||||
EventRequestManager em = vm().eventRequestManager();
|
||||
ClassPrepareRequest classPrepareRequest = em.createClassPrepareRequest();
|
||||
//### We must allow the deferred breakpoints to be resolved before
|
||||
//### we continue executing the class. We could optimize if there
|
||||
//### were no deferred breakpoints outstanding for a particular class.
|
||||
//### Can we do this with JDI?
|
||||
classPrepareRequest.setSuspendPolicy(EventRequest.SUSPEND_ALL);
|
||||
classPrepareRequest.enable();
|
||||
ClassUnloadRequest classUnloadRequest = em.createClassUnloadRequest();
|
||||
classUnloadRequest.setSuspendPolicy(EventRequest.SUSPEND_NONE);
|
||||
classUnloadRequest.enable();
|
||||
ThreadStartRequest threadStartRequest = em.createThreadStartRequest();
|
||||
threadStartRequest.setSuspendPolicy(EventRequest.SUSPEND_NONE);
|
||||
threadStartRequest.enable();
|
||||
ThreadDeathRequest threadDeathRequest = em.createThreadDeathRequest();
|
||||
threadDeathRequest.setSuspendPolicy(EventRequest.SUSPEND_NONE);
|
||||
threadDeathRequest.enable();
|
||||
ExceptionRequest exceptionRequest =
|
||||
em.createExceptionRequest(null, false, true);
|
||||
exceptionRequest.setSuspendPolicy(EventRequest.SUSPEND_ALL);
|
||||
exceptionRequest.enable();
|
||||
validateThreadInfo();
|
||||
session.interrupted = true;
|
||||
notifySessionStart();
|
||||
}
|
||||
|
||||
void endSession() {
|
||||
if (session != null) {
|
||||
session.detach();
|
||||
session = null;
|
||||
invalidateThreadInfo();
|
||||
notifySessionDeath();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Suspend all VM activity.
|
||||
*/
|
||||
|
||||
public void interrupt() throws NoSessionException {
|
||||
ensureActiveSession();
|
||||
vm().suspend();
|
||||
//### Is it guaranteed that the interrupt has happened?
|
||||
validateThreadInfo();
|
||||
session.interrupted = true;
|
||||
notifyInterrupted();
|
||||
}
|
||||
|
||||
/*
|
||||
* Resume interrupted VM.
|
||||
*/
|
||||
|
||||
public void go() throws NoSessionException, VMNotInterruptedException {
|
||||
ensureActiveSession();
|
||||
invalidateThreadInfo();
|
||||
session.interrupted = false;
|
||||
notifyContinued();
|
||||
vm().resume();
|
||||
}
|
||||
|
||||
/*
|
||||
* Stepping.
|
||||
*/
|
||||
void clearPreviousStep(ThreadReference thread) {
|
||||
/*
|
||||
* A previous step may not have completed on this thread;
|
||||
* if so, it gets removed here.
|
||||
*/
|
||||
EventRequestManager mgr = vm().eventRequestManager();
|
||||
for (StepRequest request : mgr.stepRequests()) {
|
||||
if (request.thread().equals(thread)) {
|
||||
mgr.deleteEventRequest(request);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void generalStep(ThreadReference thread, int size, int depth)
|
||||
throws NoSessionException {
|
||||
ensureActiveSession();
|
||||
invalidateThreadInfo();
|
||||
session.interrupted = false;
|
||||
notifyContinued();
|
||||
|
||||
clearPreviousStep(thread);
|
||||
EventRequestManager reqMgr = vm().eventRequestManager();
|
||||
StepRequest request = reqMgr.createStepRequest(thread,
|
||||
size, depth);
|
||||
// We want just the next step event and no others
|
||||
request.addCountFilter(1);
|
||||
request.enable();
|
||||
vm().resume();
|
||||
}
|
||||
|
||||
public void stepIntoInstruction(ThreadReference thread)
|
||||
throws NoSessionException {
|
||||
generalStep(thread, StepRequest.STEP_MIN, StepRequest.STEP_INTO);
|
||||
}
|
||||
|
||||
public void stepOverInstruction(ThreadReference thread)
|
||||
throws NoSessionException {
|
||||
generalStep(thread, StepRequest.STEP_MIN, StepRequest.STEP_OVER);
|
||||
}
|
||||
|
||||
public void stepIntoLine(ThreadReference thread)
|
||||
throws NoSessionException,
|
||||
AbsentInformationException {
|
||||
generalStep(thread, StepRequest.STEP_LINE, StepRequest.STEP_INTO);
|
||||
}
|
||||
|
||||
public void stepOverLine(ThreadReference thread)
|
||||
throws NoSessionException,
|
||||
AbsentInformationException {
|
||||
generalStep(thread, StepRequest.STEP_LINE, StepRequest.STEP_OVER);
|
||||
}
|
||||
|
||||
public void stepOut(ThreadReference thread)
|
||||
throws NoSessionException {
|
||||
generalStep(thread, StepRequest.STEP_MIN, StepRequest.STEP_OUT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Thread control.
|
||||
*/
|
||||
|
||||
public void suspendThread(ThreadReference thread) throws NoSessionException {
|
||||
ensureActiveSession();
|
||||
thread.suspend();
|
||||
}
|
||||
|
||||
public void resumeThread(ThreadReference thread) throws NoSessionException {
|
||||
ensureActiveSession();
|
||||
thread.resume();
|
||||
}
|
||||
|
||||
public void stopThread(ThreadReference thread) throws NoSessionException {
|
||||
ensureActiveSession();
|
||||
//### Need an exception now. Which one to use?
|
||||
//thread.stop();
|
||||
}
|
||||
|
||||
/*
|
||||
* ThreadInfo objects -- Allow query of thread status and stack.
|
||||
*/
|
||||
|
||||
private List<ThreadInfo> threadInfoList = new LinkedList<ThreadInfo>();
|
||||
//### Should be weak! (in the value, not the key)
|
||||
private HashMap<ThreadReference, ThreadInfo> threadInfoMap = new HashMap<ThreadReference, ThreadInfo>();
|
||||
|
||||
public ThreadInfo threadInfo(ThreadReference thread) {
|
||||
if (session == null || thread == null) {
|
||||
return null;
|
||||
}
|
||||
ThreadInfo info = threadInfoMap.get(thread);
|
||||
if (info == null) {
|
||||
//### Should not hardcode initial frame count and prefetch here!
|
||||
//info = new ThreadInfo(thread, 10, 10);
|
||||
info = new ThreadInfo(thread);
|
||||
if (session.interrupted) {
|
||||
info.validate();
|
||||
}
|
||||
threadInfoList.add(info);
|
||||
threadInfoMap.put(thread, info);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
void validateThreadInfo() {
|
||||
session.interrupted = true;
|
||||
for (ThreadInfo threadInfo : threadInfoList) {
|
||||
threadInfo.validate();
|
||||
}
|
||||
}
|
||||
|
||||
private void invalidateThreadInfo() {
|
||||
if (session != null) {
|
||||
session.interrupted = false;
|
||||
for (ThreadInfo threadInfo : threadInfoList) {
|
||||
threadInfo.invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void removeThreadInfo(ThreadReference thread) {
|
||||
ThreadInfo info = threadInfoMap.get(thread);
|
||||
if (info != null) {
|
||||
info.invalidate();
|
||||
threadInfoMap.remove(thread);
|
||||
threadInfoList.remove(info);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Listen for Session control events.
|
||||
*/
|
||||
|
||||
private void notifyInterrupted() {
|
||||
ArrayList<SessionListener> l = new ArrayList<SessionListener>(sessionListeners);
|
||||
EventObject evt = new EventObject(this);
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
l.get(i).sessionInterrupt(evt);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyContinued() {
|
||||
ArrayList<SessionListener> l = new ArrayList<SessionListener>(sessionListeners);
|
||||
EventObject evt = new EventObject(this);
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
l.get(i).sessionContinue(evt);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifySessionStart() {
|
||||
ArrayList<SessionListener> l = new ArrayList<SessionListener>(sessionListeners);
|
||||
EventObject evt = new EventObject(this);
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
l.get(i).sessionStart(evt);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifySessionDeath() {
|
||||
/*** noop for now
|
||||
ArrayList<SessionListener> l = new ArrayList<SessionListener>(sessionListeners);
|
||||
EventObject evt = new EventObject(this);
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
((SessionListener)l.get(i)).sessionDeath(evt);
|
||||
}
|
||||
****/
|
||||
}
|
||||
|
||||
/*
|
||||
* Listen for input and output requests from the application
|
||||
* being debugged. These are generated only when the debuggee
|
||||
* is spawned as a child of the debugger.
|
||||
*/
|
||||
|
||||
private Object inputLock = new Object();
|
||||
private LinkedList<String> inputBuffer = new LinkedList<String>();
|
||||
|
||||
private void resetInputBuffer() {
|
||||
synchronized (inputLock) {
|
||||
inputBuffer = new LinkedList<String>();
|
||||
}
|
||||
}
|
||||
|
||||
public void sendLineToApplication(String line) {
|
||||
synchronized (inputLock) {
|
||||
inputBuffer.addFirst(line);
|
||||
inputLock.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
private InputListener appInput = new InputListener() {
|
||||
@Override
|
||||
public String getLine() {
|
||||
// Don't allow reader to be interrupted -- catch and retry.
|
||||
String line = null;
|
||||
while (line == null) {
|
||||
synchronized (inputLock) {
|
||||
try {
|
||||
while (inputBuffer.size() < 1) {
|
||||
inputLock.wait();
|
||||
}
|
||||
line = inputBuffer.removeLast();
|
||||
} catch (InterruptedException e) {}
|
||||
}
|
||||
}
|
||||
// We must not be holding inputLock here, as the listener
|
||||
// that we call to echo a line might call us re-entrantly
|
||||
// to provide another line of input.
|
||||
// Run in Swing event dispatcher thread.
|
||||
final String input = line;
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
echoInputLine(input);
|
||||
}
|
||||
});
|
||||
return line;
|
||||
}
|
||||
};
|
||||
|
||||
private static String newline = System.getProperty("line.separator");
|
||||
|
||||
private void echoInputLine(String line) {
|
||||
ArrayList<OutputListener> l = new ArrayList<OutputListener>(appEchoListeners);
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
OutputListener ol = l.get(i);
|
||||
ol.putString(line);
|
||||
ol.putString(newline);
|
||||
}
|
||||
}
|
||||
|
||||
private OutputListener appOutput = new OutputListener() {
|
||||
@Override
|
||||
public void putString(String string) {
|
||||
ArrayList<OutputListener> l = new ArrayList<OutputListener>(appEchoListeners);
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
l.get(i).putString(string);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private OutputListener appError = new OutputListener() {
|
||||
@Override
|
||||
public void putString(String string) {
|
||||
ArrayList<OutputListener> l = new ArrayList<OutputListener>(appEchoListeners);
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
l.get(i).putString(string);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private OutputListener diagnostics = new OutputListener() {
|
||||
@Override
|
||||
public void putString(String string) {
|
||||
ArrayList<OutputListener> l = new ArrayList<OutputListener>(diagnosticsListeners);
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
l.get(i).putString(string);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
///////////// Spec Request Creation/Deletion/Query ///////////
|
||||
|
||||
private EventRequestSpecList specList = new EventRequestSpecList(this);
|
||||
|
||||
public BreakpointSpec
|
||||
createSourceLineBreakpoint(String sourceName, int line) {
|
||||
return specList.createSourceLineBreakpoint(sourceName, line);
|
||||
}
|
||||
|
||||
public BreakpointSpec
|
||||
createClassLineBreakpoint(String classPattern, int line) {
|
||||
return specList.createClassLineBreakpoint(classPattern, line);
|
||||
}
|
||||
|
||||
public BreakpointSpec
|
||||
createMethodBreakpoint(String classPattern,
|
||||
String methodId, List<String> methodArgs) {
|
||||
return specList.createMethodBreakpoint(classPattern,
|
||||
methodId, methodArgs);
|
||||
}
|
||||
|
||||
public ExceptionSpec
|
||||
createExceptionIntercept(String classPattern,
|
||||
boolean notifyCaught,
|
||||
boolean notifyUncaught) {
|
||||
return specList.createExceptionIntercept(classPattern,
|
||||
notifyCaught,
|
||||
notifyUncaught);
|
||||
}
|
||||
|
||||
public AccessWatchpointSpec
|
||||
createAccessWatchpoint(String classPattern, String fieldId) {
|
||||
return specList.createAccessWatchpoint(classPattern, fieldId);
|
||||
}
|
||||
|
||||
public ModificationWatchpointSpec
|
||||
createModificationWatchpoint(String classPattern, String fieldId) {
|
||||
return specList.createModificationWatchpoint(classPattern,
|
||||
fieldId);
|
||||
}
|
||||
|
||||
public void delete(EventRequestSpec spec) {
|
||||
specList.delete(spec);
|
||||
}
|
||||
|
||||
void resolve(ReferenceType refType) {
|
||||
specList.resolve(refType);
|
||||
}
|
||||
|
||||
public void install(EventRequestSpec spec) {
|
||||
specList.install(spec, vm());
|
||||
}
|
||||
|
||||
public List<EventRequestSpec> eventRequestSpecs() {
|
||||
return specList.eventRequestSpecs();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
public class FrameIndexOutOfBoundsException extends IndexOutOfBoundsException {
|
||||
|
||||
private static final long serialVersionUID = -4870148107027371437L;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
public interface InputListener {
|
||||
String getLine();
|
||||
}
|
||||
193
jdkSrc/jdk8/com/sun/tools/example/debug/bdi/JDIEventSource.java
Normal file
193
jdkSrc/jdk8/com/sun/tools/example/debug/bdi/JDIEventSource.java
Normal file
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.event.*;
|
||||
|
||||
import com.sun.tools.example.debug.event.*;
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
/**
|
||||
*/
|
||||
class JDIEventSource extends Thread {
|
||||
|
||||
private /*final*/ EventQueue queue;
|
||||
private /*final*/ Session session;
|
||||
private /*final*/ ExecutionManager runtime;
|
||||
private final JDIListener firstListener = new FirstListener();
|
||||
|
||||
private boolean wantInterrupt; //### Hack
|
||||
|
||||
/**
|
||||
* Create event source.
|
||||
*/
|
||||
JDIEventSource(Session session) {
|
||||
super("JDI Event Set Dispatcher");
|
||||
this.session = session;
|
||||
this.runtime = session.runtime;
|
||||
this.queue = session.vm.eventQueue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
runLoop();
|
||||
} catch (Exception exc) {
|
||||
//### Do something different for InterruptedException???
|
||||
// just exit
|
||||
}
|
||||
session.running = false;
|
||||
}
|
||||
|
||||
private void runLoop() throws InterruptedException {
|
||||
AbstractEventSet es;
|
||||
do {
|
||||
EventSet jdiEventSet = queue.remove();
|
||||
es = AbstractEventSet.toSpecificEventSet(jdiEventSet);
|
||||
session.interrupted = es.suspendedAll();
|
||||
dispatchEventSet(es);
|
||||
} while(!(es instanceof VMDisconnectEventSet));
|
||||
}
|
||||
|
||||
//### Gross foul hackery!
|
||||
private void dispatchEventSet(final AbstractEventSet es) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
boolean interrupted = es.suspendedAll();
|
||||
es.notify(firstListener);
|
||||
boolean wantInterrupt = JDIEventSource.this.wantInterrupt;
|
||||
for (JDIListener jl : session.runtime.jdiListeners) {
|
||||
es.notify(jl);
|
||||
}
|
||||
if (interrupted && !wantInterrupt) {
|
||||
session.interrupted = false;
|
||||
//### Catch here is a hack
|
||||
try {
|
||||
session.vm.resume();
|
||||
} catch (VMDisconnectedException ee) {}
|
||||
}
|
||||
if (es instanceof ThreadDeathEventSet) {
|
||||
ThreadReference t = ((ThreadDeathEventSet)es).getThread();
|
||||
session.runtime.removeThreadInfo(t);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void finalizeEventSet(AbstractEventSet es) {
|
||||
if (session.interrupted && !wantInterrupt) {
|
||||
session.interrupted = false;
|
||||
//### Catch here is a hack
|
||||
try {
|
||||
session.vm.resume();
|
||||
} catch (VMDisconnectedException ee) {}
|
||||
}
|
||||
if (es instanceof ThreadDeathEventSet) {
|
||||
ThreadReference t = ((ThreadDeathEventSet)es).getThread();
|
||||
session.runtime.removeThreadInfo(t);
|
||||
}
|
||||
}
|
||||
|
||||
//### This is a Hack, deal with it
|
||||
private class FirstListener implements JDIListener {
|
||||
|
||||
@Override
|
||||
public void accessWatchpoint(AccessWatchpointEventSet e) {
|
||||
session.runtime.validateThreadInfo();
|
||||
wantInterrupt = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void classPrepare(ClassPrepareEventSet e) {
|
||||
wantInterrupt = false;
|
||||
runtime.resolve(e.getReferenceType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void classUnload(ClassUnloadEventSet e) {
|
||||
wantInterrupt = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exception(ExceptionEventSet e) {
|
||||
wantInterrupt = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void locationTrigger(LocationTriggerEventSet e) {
|
||||
session.runtime.validateThreadInfo();
|
||||
wantInterrupt = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modificationWatchpoint(ModificationWatchpointEventSet e) {
|
||||
session.runtime.validateThreadInfo();
|
||||
wantInterrupt = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void threadDeath(ThreadDeathEventSet e) {
|
||||
wantInterrupt = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void threadStart(ThreadStartEventSet e) {
|
||||
wantInterrupt = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void vmDeath(VMDeathEventSet e) {
|
||||
//### Should have some way to notify user
|
||||
//### that VM died before the session ended.
|
||||
wantInterrupt = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void vmDisconnect(VMDisconnectEventSet e) {
|
||||
//### Notify user?
|
||||
wantInterrupt = false;
|
||||
session.runtime.endSession();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void vmStart(VMStartEventSet e) {
|
||||
//### Do we need to do anything with it?
|
||||
wantInterrupt = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import java.util.List;
|
||||
|
||||
public class LineBreakpointSpec extends BreakpointSpec {
|
||||
int lineNumber;
|
||||
|
||||
LineBreakpointSpec(EventRequestSpecList specs,
|
||||
ReferenceTypeSpec refSpec, int lineNumber) {
|
||||
super(specs, refSpec);
|
||||
this.lineNumber = lineNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* The 'refType' is known to match.
|
||||
*/
|
||||
@Override
|
||||
void resolve(ReferenceType refType) throws InvalidTypeException,
|
||||
LineNotFoundException {
|
||||
if (!(refType instanceof ClassType)) {
|
||||
throw new InvalidTypeException();
|
||||
}
|
||||
Location location = location((ClassType)refType);
|
||||
setRequest(refType.virtualMachine().eventRequestManager()
|
||||
.createBreakpointRequest(location));
|
||||
}
|
||||
|
||||
private Location location(ClassType clazz) throws
|
||||
LineNotFoundException {
|
||||
Location location = null;
|
||||
try {
|
||||
List<Location> locs = clazz.locationsOfLine(lineNumber());
|
||||
if (locs.size() == 0) {
|
||||
throw new LineNotFoundException();
|
||||
}
|
||||
// TODO handle multiple locations
|
||||
location = locs.get(0);
|
||||
if (location.method() == null) {
|
||||
throw new LineNotFoundException();
|
||||
}
|
||||
} catch (AbsentInformationException e) {
|
||||
/*
|
||||
* TO DO: throw something more specific, or allow
|
||||
* AbsentInfo exception to pass through.
|
||||
*/
|
||||
throw new LineNotFoundException();
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
public int lineNumber() {
|
||||
return lineNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return refSpec.hashCode() + lineNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof LineBreakpointSpec) {
|
||||
LineBreakpointSpec breakpoint = (LineBreakpointSpec)obj;
|
||||
|
||||
return refSpec.equals(breakpoint.refSpec) &&
|
||||
(lineNumber == breakpoint.lineNumber);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String errorMessageFor(Exception e) {
|
||||
if (e instanceof LineNotFoundException) {
|
||||
return ("No code at line " + lineNumber() + " in " + refSpec);
|
||||
} else if (e instanceof InvalidTypeException) {
|
||||
return ("Breakpoints can be located only in classes. " +
|
||||
refSpec + " is an interface or array");
|
||||
} else {
|
||||
return super.errorMessageFor( e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer("breakpoint ");
|
||||
buffer.append(refSpec.toString());
|
||||
buffer.append(':');
|
||||
buffer.append(lineNumber);
|
||||
buffer.append(" (");
|
||||
buffer.append(getStatusString());
|
||||
buffer.append(')');
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
public class LineNotFoundException extends Exception
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = -5630418117861587582L;
|
||||
|
||||
public LineNotFoundException()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public LineNotFoundException(String s)
|
||||
{
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
@@ -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.bdi;
|
||||
|
||||
class MalformedMemberNameException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = -7726664097374844485L;
|
||||
|
||||
public MalformedMemberNameException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public MalformedMemberNameException(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MethodBreakpointSpec extends BreakpointSpec {
|
||||
String methodId;
|
||||
List<String> methodArgs;
|
||||
|
||||
MethodBreakpointSpec(EventRequestSpecList specs,
|
||||
ReferenceTypeSpec refSpec,
|
||||
String methodId, List<String> methodArgs) {
|
||||
super(specs, refSpec);
|
||||
this.methodId = methodId;
|
||||
this.methodArgs = methodArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* The 'refType' is known to match.
|
||||
*/
|
||||
@Override
|
||||
void resolve(ReferenceType refType) throws MalformedMemberNameException,
|
||||
AmbiguousMethodException,
|
||||
InvalidTypeException,
|
||||
NoSuchMethodException,
|
||||
NoSessionException {
|
||||
if (!isValidMethodName(methodId)) {
|
||||
throw new MalformedMemberNameException(methodId);
|
||||
}
|
||||
if (!(refType instanceof ClassType)) {
|
||||
throw new InvalidTypeException();
|
||||
}
|
||||
Location location = location((ClassType)refType);
|
||||
setRequest(refType.virtualMachine().eventRequestManager()
|
||||
.createBreakpointRequest(location));
|
||||
}
|
||||
|
||||
private Location location(ClassType clazz) throws
|
||||
AmbiguousMethodException,
|
||||
NoSuchMethodException,
|
||||
NoSessionException {
|
||||
Method method = findMatchingMethod(clazz);
|
||||
Location location = method.location();
|
||||
return location;
|
||||
}
|
||||
|
||||
public String methodName() {
|
||||
return methodId;
|
||||
}
|
||||
|
||||
public List<String> methodArgs() {
|
||||
return methodArgs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return refSpec.hashCode() +
|
||||
((methodId != null) ? methodId.hashCode() : 0) +
|
||||
((methodArgs != null) ? methodArgs.hashCode() : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof MethodBreakpointSpec) {
|
||||
MethodBreakpointSpec breakpoint = (MethodBreakpointSpec)obj;
|
||||
|
||||
return methodId.equals(breakpoint.methodId) &&
|
||||
methodArgs.equals(breakpoint.methodArgs) &&
|
||||
refSpec.equals(breakpoint.refSpec);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String errorMessageFor(Exception e) {
|
||||
if (e instanceof AmbiguousMethodException) {
|
||||
return ("Method " + methodName() + " is overloaded; specify arguments");
|
||||
/*
|
||||
* TO DO: list the methods here
|
||||
*/
|
||||
} else if (e instanceof NoSuchMethodException) {
|
||||
return ("No method " + methodName() + " in " + refSpec);
|
||||
} else if (e instanceof InvalidTypeException) {
|
||||
return ("Breakpoints can be located only in classes. " +
|
||||
refSpec + " is an interface or array");
|
||||
} else {
|
||||
return super.errorMessageFor( e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer("breakpoint ");
|
||||
buffer.append(refSpec.toString());
|
||||
buffer.append('.');
|
||||
buffer.append(methodId);
|
||||
if (methodArgs != null) {
|
||||
boolean first = true;
|
||||
buffer.append('(');
|
||||
for (String name : methodArgs) {
|
||||
if (!first) {
|
||||
buffer.append(',');
|
||||
}
|
||||
buffer.append(name);
|
||||
first = false;
|
||||
}
|
||||
buffer.append(")");
|
||||
}
|
||||
buffer.append(" (");
|
||||
buffer.append(getStatusString());
|
||||
buffer.append(')');
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
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 varargs)
|
||||
* 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;
|
||||
}
|
||||
|
||||
private VirtualMachine vm() {
|
||||
return request.virtualMachine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove unneeded spaces and expand class names to fully
|
||||
* qualified names, if necessary and possible.
|
||||
*/
|
||||
private String normalizeArgTypeName(String name) throws NoSessionException {
|
||||
/*
|
||||
* 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(
|
||||
"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 {
|
||||
List<?> refs = specs.runtime.findClassesMatchingPattern(name);
|
||||
if (refs.size() > 0) { //### ambiguity???
|
||||
name = ((ReferenceType)(refs.get(0))).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(ClassType clazz)
|
||||
throws AmbiguousMethodException,
|
||||
NoSuchMethodException,
|
||||
NoSessionException {
|
||||
|
||||
// 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 : clazz.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;
|
||||
}
|
||||
}
|
||||
@@ -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.bdi;
|
||||
|
||||
public class MethodNotFoundException extends Exception
|
||||
{
|
||||
private static final long serialVersionUID = -2064968107599632609L;
|
||||
|
||||
public MethodNotFoundException()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public MethodNotFoundException(String s)
|
||||
{
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class ModificationWatchpointSpec extends WatchpointSpec {
|
||||
|
||||
ModificationWatchpointSpec(EventRequestSpecList specs,
|
||||
ReferenceTypeSpec refSpec, String fieldId) {
|
||||
super(specs, refSpec, fieldId);
|
||||
}
|
||||
|
||||
/**
|
||||
* The 'refType' is known to match.
|
||||
*/
|
||||
@Override
|
||||
void resolve(ReferenceType refType) throws InvalidTypeException,
|
||||
NoSuchFieldException {
|
||||
if (!(refType instanceof ClassType)) {
|
||||
throw new InvalidTypeException();
|
||||
}
|
||||
Field field = refType.fieldByName(fieldId);
|
||||
if (field == null) {
|
||||
throw new NoSuchFieldException(fieldId);
|
||||
}
|
||||
setRequest(refType.virtualMachine().eventRequestManager()
|
||||
.createModificationWatchpointRequest(field));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return (obj instanceof ModificationWatchpointSpec) &&
|
||||
super.equals(obj);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
public class NoSessionException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = -7324357828115128603L;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
public class NoThreadException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1846613539928921998L;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
public interface OutputListener {
|
||||
void putString(String str);
|
||||
//void putLine(String line);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
// dummy placeholder for javaCC-generated code.
|
||||
|
||||
public class ParseException extends Exception {}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
class PatternReferenceTypeSpec implements ReferenceTypeSpec {
|
||||
final boolean isWild;
|
||||
final String classId;
|
||||
|
||||
PatternReferenceTypeSpec(String classId)
|
||||
// throws ClassNotFoundException
|
||||
{
|
||||
// checkClassName(classId);
|
||||
isWild = classId.startsWith("*.");
|
||||
if (isWild) {
|
||||
this.classId = classId.substring(1);
|
||||
} else {
|
||||
this.classId = classId;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the specified ReferenceType match this spec.
|
||||
*/
|
||||
@Override
|
||||
public boolean matches(ReferenceType refType) {
|
||||
if (isWild) {
|
||||
return refType.name().endsWith(classId);
|
||||
} else {
|
||||
return refType.name().equals(classId);
|
||||
}
|
||||
}
|
||||
|
||||
@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) && (isWild == spec.isWild);
|
||||
} 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, ".");
|
||||
boolean first = true;
|
||||
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 (!Utils.isJavaIdentifier(token) && !(first && token.equals("*"))) {
|
||||
throw new ClassNotFoundException();
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return isWild? "*" + classId : classId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
interface ReferenceTypeSpec {
|
||||
/**
|
||||
* Does the specified ReferenceType match this spec.
|
||||
*/
|
||||
boolean matches(ReferenceType refType);
|
||||
|
||||
@Override
|
||||
int hashCode();
|
||||
|
||||
@Override
|
||||
boolean equals(Object obj);
|
||||
}
|
||||
105
jdkSrc/jdk8/com/sun/tools/example/debug/bdi/Session.java
Normal file
105
jdkSrc/jdk8/com/sun/tools/example/debug/bdi/Session.java
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
import com.sun.jdi.VirtualMachine;
|
||||
import com.sun.jdi.VMDisconnectedException;
|
||||
|
||||
/**
|
||||
* Our repository of what we know about the state of one
|
||||
* running VM.
|
||||
*/
|
||||
class Session {
|
||||
|
||||
final VirtualMachine vm;
|
||||
final ExecutionManager runtime;
|
||||
final OutputListener diagnostics;
|
||||
|
||||
boolean running = true; // Set false by JDIEventSource
|
||||
boolean interrupted = false; // Set false by JDIEventSource
|
||||
|
||||
private JDIEventSource eventSourceThread = null;
|
||||
private int traceFlags;
|
||||
private boolean dead = false;
|
||||
|
||||
public Session(VirtualMachine vm, ExecutionManager runtime,
|
||||
OutputListener diagnostics) {
|
||||
this.vm = vm;
|
||||
this.runtime = runtime;
|
||||
this.diagnostics = diagnostics;
|
||||
this.traceFlags = VirtualMachine.TRACE_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if VM is interrupted, i.e, present and not running.
|
||||
*/
|
||||
public boolean isInterrupted() {
|
||||
return interrupted;
|
||||
}
|
||||
|
||||
public void setTraceMode(int traceFlags) {
|
||||
this.traceFlags = traceFlags;
|
||||
if (!dead) {
|
||||
vm.setDebugTraceMode(traceFlags);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean attach() {
|
||||
vm.setDebugTraceMode(traceFlags);
|
||||
diagnostics.putString("Connected to VM");
|
||||
eventSourceThread = new JDIEventSource(this);
|
||||
eventSourceThread.start();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void detach() {
|
||||
if (!dead) {
|
||||
eventSourceThread.interrupt();
|
||||
eventSourceThread = null;
|
||||
//### The VM may already be disconnected
|
||||
//### if the debuggee did a System.exit().
|
||||
//### Exception handler here is a kludge,
|
||||
//### Rather, there are many other places
|
||||
//### where we need to handle this exception,
|
||||
//### and initiate a detach due to an error
|
||||
//### condition, e.g., connection failure.
|
||||
try {
|
||||
vm.dispose();
|
||||
} catch (VMDisconnectedException ee) {}
|
||||
dead = true;
|
||||
diagnostics.putString("Disconnected from VM");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
import java.util.EventObject;
|
||||
import java.util.EventListener;
|
||||
|
||||
public interface SessionListener extends EventListener {
|
||||
|
||||
void sessionStart(EventObject e);
|
||||
|
||||
void sessionInterrupt(EventObject e);
|
||||
void sessionContinue(EventObject e);
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
class SourceNameReferenceTypeSpec implements ReferenceTypeSpec {
|
||||
final String sourceName;
|
||||
final int linenumber;
|
||||
|
||||
SourceNameReferenceTypeSpec(String sourceName, int linenumber) {
|
||||
this.sourceName = sourceName;
|
||||
this.linenumber = linenumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the specified ReferenceType match this spec.
|
||||
*/
|
||||
@Override
|
||||
public boolean matches(ReferenceType refType) {
|
||||
try {
|
||||
if (refType.sourceName().equals(sourceName)) {
|
||||
try {
|
||||
refType.locationsOfLine(linenumber);
|
||||
// if we don't throw an exception then it was found
|
||||
return true;
|
||||
} catch(AbsentInformationException exc) {
|
||||
} catch(ObjectCollectedException exc) {
|
||||
}
|
||||
}
|
||||
} catch(AbsentInformationException exc) {
|
||||
// for sourceName(), fall through
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return sourceName.hashCode() + linenumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof SourceNameReferenceTypeSpec) {
|
||||
SourceNameReferenceTypeSpec spec = (SourceNameReferenceTypeSpec)obj;
|
||||
|
||||
return sourceName.equals(spec.sourceName) &&
|
||||
(linenumber == spec.linenumber);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return sourceName + "@" + linenumber;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
public class SpecErrorEvent extends SpecEvent {
|
||||
|
||||
private static final long serialVersionUID = 8162634387866409578L;
|
||||
private Exception reason;
|
||||
|
||||
public SpecErrorEvent(EventRequestSpec eventRequestSpec,
|
||||
Exception reason) {
|
||||
super(eventRequestSpec);
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
public Exception getReason() {
|
||||
return reason;
|
||||
}
|
||||
}
|
||||
58
jdkSrc/jdk8/com/sun/tools/example/debug/bdi/SpecEvent.java
Normal file
58
jdkSrc/jdk8/com/sun/tools/example/debug/bdi/SpecEvent.java
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
import java.util.EventObject;
|
||||
|
||||
import com.sun.jdi.request.EventRequest;
|
||||
|
||||
public class SpecEvent extends EventObject {
|
||||
|
||||
private static final long serialVersionUID = 4820735456787276230L;
|
||||
private EventRequestSpec eventRequestSpec;
|
||||
|
||||
public SpecEvent(EventRequestSpec eventRequestSpec) {
|
||||
super(eventRequestSpec.specs);
|
||||
this.eventRequestSpec = eventRequestSpec;
|
||||
}
|
||||
|
||||
public EventRequestSpec getEventRequestSpec() {
|
||||
return eventRequestSpec;
|
||||
}
|
||||
|
||||
public EventRequest getEventRequest() {
|
||||
return eventRequestSpec.getEventRequest();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
public interface SpecListener extends EventListener {
|
||||
|
||||
void breakpointSet(SpecEvent e);
|
||||
void breakpointDeferred(SpecEvent e);
|
||||
void breakpointDeleted(SpecEvent e);
|
||||
void breakpointResolved(SpecEvent e);
|
||||
void breakpointError(SpecErrorEvent e);
|
||||
|
||||
void watchpointSet(SpecEvent e);
|
||||
void watchpointDeferred(SpecEvent e);
|
||||
void watchpointDeleted(SpecEvent e);
|
||||
void watchpointResolved(SpecEvent e);
|
||||
void watchpointError(SpecErrorEvent e);
|
||||
|
||||
void exceptionInterceptSet(SpecEvent e);
|
||||
void exceptionInterceptDeferred(SpecEvent e);
|
||||
void exceptionInterceptDeleted(SpecEvent e);
|
||||
void exceptionInterceptResolved(SpecEvent e);
|
||||
void exceptionInterceptError(SpecErrorEvent e);
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
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
|
||||
*/
|
||||
public class ThreadGroupIterator implements Iterator<ThreadGroupReference> {
|
||||
private final Stack<Iterator<ThreadGroupReference>> stack
|
||||
= new Stack<Iterator<ThreadGroupReference>>();
|
||||
|
||||
public ThreadGroupIterator(List<ThreadGroupReference> tgl) {
|
||||
push(tgl);
|
||||
}
|
||||
|
||||
public 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;
|
||||
}
|
||||
*/
|
||||
}
|
||||
126
jdkSrc/jdk8/com/sun/tools/example/debug/bdi/ThreadInfo.java
Normal file
126
jdkSrc/jdk8/com/sun/tools/example/debug/bdi/ThreadInfo.java
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
//### Should handle target VM death or connection failure cleanly.
|
||||
|
||||
public class ThreadInfo {
|
||||
|
||||
private ThreadReference thread;
|
||||
private int status;
|
||||
|
||||
private int frameCount;
|
||||
|
||||
Object userObject; // User-supplied annotation.
|
||||
|
||||
private boolean interrupted = false;
|
||||
|
||||
private void assureInterrupted() throws VMNotInterruptedException {
|
||||
if (!interrupted) {
|
||||
throw new VMNotInterruptedException();
|
||||
}
|
||||
}
|
||||
|
||||
ThreadInfo (ThreadReference thread) {
|
||||
this.thread = thread;
|
||||
this.frameCount = -1;
|
||||
}
|
||||
|
||||
public ThreadReference thread() {
|
||||
return thread;
|
||||
}
|
||||
|
||||
public int getStatus() throws VMNotInterruptedException {
|
||||
assureInterrupted();
|
||||
update();
|
||||
return status;
|
||||
}
|
||||
|
||||
public int getFrameCount() throws VMNotInterruptedException {
|
||||
assureInterrupted();
|
||||
update();
|
||||
return frameCount;
|
||||
}
|
||||
|
||||
public StackFrame getFrame(int index) throws VMNotInterruptedException {
|
||||
assureInterrupted();
|
||||
update();
|
||||
try {
|
||||
return thread.frame(index);
|
||||
} catch (IncompatibleThreadStateException e) {
|
||||
// Should not happen
|
||||
interrupted = false;
|
||||
throw new VMNotInterruptedException();
|
||||
}
|
||||
}
|
||||
|
||||
public Object getUserObject() {
|
||||
return userObject;
|
||||
}
|
||||
|
||||
public void setUserObject(Object obj) {
|
||||
userObject = obj;
|
||||
}
|
||||
|
||||
// Refresh upon first access after cache is cleared.
|
||||
|
||||
void update() throws VMNotInterruptedException {
|
||||
if (frameCount == -1) {
|
||||
try {
|
||||
status = thread.status();
|
||||
frameCount = thread.frameCount();
|
||||
} catch (IncompatibleThreadStateException e) {
|
||||
// Should not happen
|
||||
interrupted = false;
|
||||
throw new VMNotInterruptedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Called from 'ExecutionManager'.
|
||||
|
||||
void validate() {
|
||||
interrupted = true;
|
||||
}
|
||||
|
||||
void invalidate() {
|
||||
interrupted = false;
|
||||
frameCount = -1;
|
||||
status = ThreadReference.THREAD_STATUS_UNKNOWN;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
import com.sun.jdi.ThreadGroupReference;
|
||||
import com.sun.jdi.ThreadReference;
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class ThreadIterator implements Iterator<ThreadReference> {
|
||||
Iterator<ThreadReference> it = null;
|
||||
ThreadGroupIterator tgi;
|
||||
|
||||
public ThreadIterator(ThreadGroupReference tg) {
|
||||
tgi = new ThreadGroupIterator(tg);
|
||||
}
|
||||
|
||||
//### make this package access only?
|
||||
public ThreadIterator(List<ThreadGroupReference> tgl) {
|
||||
tgi = new ThreadGroupIterator(tgl);
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
190
jdkSrc/jdk8/com/sun/tools/example/debug/bdi/Utils.java
Normal file
190
jdkSrc/jdk8/com/sun/tools/example/debug/bdi/Utils.java
Normal file
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* 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.bdi; //### does it belong here?
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class Utils {
|
||||
|
||||
/**
|
||||
* Return the thread status description.
|
||||
*/
|
||||
public static String getStatus(ThreadReference thr) {
|
||||
int status = thr.status();
|
||||
String result;
|
||||
switch (status) {
|
||||
case ThreadReference.THREAD_STATUS_UNKNOWN:
|
||||
result = "unknown status";
|
||||
break;
|
||||
case ThreadReference.THREAD_STATUS_ZOMBIE:
|
||||
result = "zombie";
|
||||
break;
|
||||
case ThreadReference.THREAD_STATUS_RUNNING:
|
||||
result = "running";
|
||||
break;
|
||||
case ThreadReference.THREAD_STATUS_SLEEPING:
|
||||
result = "sleeping";
|
||||
break;
|
||||
case ThreadReference.THREAD_STATUS_MONITOR:
|
||||
result = "waiting to acquire a monitor lock";
|
||||
break;
|
||||
case ThreadReference.THREAD_STATUS_WAIT:
|
||||
result = "waiting on a condition";
|
||||
break;
|
||||
default:
|
||||
result = "<invalid thread status>";
|
||||
}
|
||||
if (thr.isSuspended()) {
|
||||
result += " (suspended)";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a description of an object.
|
||||
*/
|
||||
public static String description(ObjectReference ref) {
|
||||
ReferenceType clazz = ref.referenceType();
|
||||
long id = ref.uniqueID(); //### TODO use real id
|
||||
if (clazz == null) {
|
||||
return toHex(id);
|
||||
} else {
|
||||
return "(" + clazz.name() + ")" + toHex(id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a long to a hexadecimal string.
|
||||
*/
|
||||
public 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.
|
||||
*/
|
||||
public 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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The next two methods are used by this class and by EventHandler
|
||||
* to print consistent locations and error messages.
|
||||
*/
|
||||
public static String locationString(Location loc) {
|
||||
return loc.declaringType().name() +
|
||||
"." + loc.method().name() + "(), line=" +
|
||||
loc.lineNumber();
|
||||
}
|
||||
|
||||
//### UNUSED.
|
||||
/************************
|
||||
private String typedName(Method method) {
|
||||
// TO DO: Use method.signature() instead of method.arguments() so that
|
||||
// we get sensible results for classes without debugging info
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append(method.name());
|
||||
buf.append("(");
|
||||
Iterator it = method.arguments().iterator();
|
||||
while (it.hasNext()) {
|
||||
buf.append(((LocalVariable)it.next()).typeName());
|
||||
if (it.hasNext()) {
|
||||
buf.append(",");
|
||||
}
|
||||
}
|
||||
buf.append(")");
|
||||
return buf.toString();
|
||||
}
|
||||
************************/
|
||||
|
||||
public static boolean isValidMethodName(String s) {
|
||||
return isJavaIdentifier(s) ||
|
||||
s.equals("<init>") ||
|
||||
s.equals("<clinit>");
|
||||
}
|
||||
|
||||
public static 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
public class VMLaunchFailureException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = -2439646729274310108L;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
public class VMNotInterruptedException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 8111074582188765600L;
|
||||
}
|
||||
101
jdkSrc/jdk8/com/sun/tools/example/debug/bdi/WatchpointSpec.java
Normal file
101
jdkSrc/jdk8/com/sun/tools/example/debug/bdi/WatchpointSpec.java
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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.bdi;
|
||||
|
||||
public abstract class WatchpointSpec extends EventRequestSpec {
|
||||
final String fieldId;
|
||||
|
||||
WatchpointSpec(EventRequestSpecList specs,
|
||||
ReferenceTypeSpec refSpec, String fieldId) {
|
||||
super(specs, refSpec);
|
||||
this.fieldId = fieldId;
|
||||
// if (!isJavaIdentifier(fieldId)) {
|
||||
// throw new MalformedMemberNameException(fieldId);
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
void notifySet(SpecListener listener, SpecEvent evt) {
|
||||
listener.watchpointSet(evt);
|
||||
}
|
||||
|
||||
@Override
|
||||
void notifyDeferred(SpecListener listener, SpecEvent evt) {
|
||||
listener.watchpointDeferred(evt);
|
||||
}
|
||||
|
||||
@Override
|
||||
void notifyResolved(SpecListener listener, SpecEvent evt) {
|
||||
listener.watchpointResolved(evt);
|
||||
}
|
||||
|
||||
@Override
|
||||
void notifyDeleted(SpecListener listener, SpecEvent evt) {
|
||||
listener.watchpointDeleted(evt);
|
||||
}
|
||||
|
||||
@Override
|
||||
void notifyError(SpecListener listener, SpecErrorEvent evt) {
|
||||
listener.watchpointError(evt);
|
||||
}
|
||||
|
||||
@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
|
||||
public String errorMessageFor(Exception e) {
|
||||
if (e instanceof NoSuchFieldException) {
|
||||
return ("No field " + fieldId + " in " + refSpec);
|
||||
} else {
|
||||
return super.errorMessageFor(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user