Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDADebugTarget.java')
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDADebugTarget.java525
1 files changed, 525 insertions, 0 deletions
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDADebugTarget.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDADebugTarget.java
new file mode 100644
index 000000000..6df9fad76
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDADebugTarget.java
@@ -0,0 +1,525 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Bjorn Freeman-Benson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.pda.model;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.Vector;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IMarkerDelta;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.IBreakpointManager;
+import org.eclipse.debug.core.IBreakpointManagerListener;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.IDebugTarget;
+import org.eclipse.debug.core.model.IMemoryBlock;
+import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.debug.core.model.IThread;
+import org.eclipse.debug.core.model.IValue;
+import org.eclipse.debug.examples.core.pda.DebugCorePlugin;
+import org.eclipse.debug.examples.core.pda.breakpoints.PDALineBreakpoint;
+import org.eclipse.debug.examples.core.pda.breakpoints.PDARunToLineBreakpoint;
+
+
+/**
+ * PDA Debug Target
+ */
+public class PDADebugTarget extends PDADebugElement implements IDebugTarget, IBreakpointManagerListener, IPDAEventListener {
+
+ // associated system process (VM)
+ private IProcess fProcess;
+
+ // containing launch object
+ private ILaunch fLaunch;
+
+ // sockets to communicate with VM
+ private Socket fRequestSocket;
+ private PrintWriter fRequestWriter;
+ private BufferedReader fRequestReader;
+ private Socket fEventSocket;
+ private BufferedReader fEventReader;
+
+ // terminated state
+ private boolean fTerminated = false;
+
+ // threads
+ private IThread[] fThreads;
+ private PDAThread fThread;
+
+ // event dispatch job
+ private EventDispatchJob fEventDispatch;
+ // event listeners
+ private Vector fEventListeners = new Vector();
+
+ /**
+ * Listens to events from the PDA VM and fires corresponding
+ * debug events.
+ */
+ class EventDispatchJob extends Job {
+
+ public EventDispatchJob() {
+ super("PDA Event Dispatch");
+ setSystem(true);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ protected IStatus run(IProgressMonitor monitor) {
+ String event = "";
+ while (!isTerminated() && event != null) {
+ try {
+ event = fEventReader.readLine();
+ if (event != null) {
+ Object[] listeners = fEventListeners.toArray();
+ for (int i = 0; i < listeners.length; i++) {
+ ((IPDAEventListener)listeners[i]).handleEvent(event);
+ }
+ }
+ } catch (IOException e) {
+ terminated();
+ }
+ }
+ return Status.OK_STATUS;
+ }
+
+ }
+
+ /**
+ * Registers the given event listener. The listener will be notified of
+ * events in the program being interpretted. Has no effect if the listener
+ * is already registered.
+ *
+ * @param listener event listener
+ */
+ public void addEventListener(IPDAEventListener listener) {
+ if (!fEventListeners.contains(listener)) {
+ fEventListeners.add(listener);
+ }
+ }
+
+ /**
+ * Deregisters the given event listener. Has no effect if the listener is
+ * not currently registered.
+ *
+ * @param listener event listener
+ */
+ public void removeEventListener(IPDAEventListener listener) {
+ fEventListeners.remove(listener);
+ }
+
+ /**
+ * Constructs a new debug target in the given launch for the
+ * associated PDA VM process.
+ *
+ * @param launch containing launch
+ * @param process PDA VM
+ * @param requestPort port to send requests to the VM
+ * @param eventPort port to read events from
+ * @exception CoreException if unable to connect to host
+ */
+ public PDADebugTarget(ILaunch launch, IProcess process, int requestPort, int eventPort) throws CoreException {
+ super(null);
+ fLaunch = launch;
+ fProcess = process;
+ addEventListener(this);
+ try {
+ // give interpreter a chance to start
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+ fRequestSocket = new Socket("localhost", requestPort);
+ fRequestWriter = new PrintWriter(fRequestSocket.getOutputStream());
+ fRequestReader = new BufferedReader(new InputStreamReader(fRequestSocket.getInputStream()));
+ // give interpreter a chance to open next socket
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+ fEventSocket = new Socket("localhost", eventPort);
+ fEventReader = new BufferedReader(new InputStreamReader(fEventSocket.getInputStream()));
+ } catch (UnknownHostException e) {
+ requestFailed("Unable to connect to PDA VM", e);
+ } catch (IOException e) {
+ requestFailed("Unable to connect to PDA VM", e);
+ }
+ fThread = new PDAThread(this);
+ fThreads = new IThread[] {fThread};
+ fEventDispatch = new EventDispatchJob();
+ fEventDispatch.schedule();
+ IBreakpointManager breakpointManager = getBreakpointManager();
+ breakpointManager.addBreakpointListener(this);
+ breakpointManager.addBreakpointManagerListener(this);
+ // initialize error hanlding to suspend on 'unimplemented instructions'
+ // and 'no such label' errors
+ sendRequest("eventstop unimpinstr 1");
+ sendRequest("eventstop nosuchlabel 1");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IDebugTarget#getProcess()
+ */
+ public IProcess getProcess() {
+ return fProcess;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IDebugTarget#getThreads()
+ */
+ public IThread[] getThreads() throws DebugException {
+ return fThreads;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IDebugTarget#hasThreads()
+ */
+ public boolean hasThreads() throws DebugException {
+ return true;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IDebugTarget#getName()
+ */
+ public String getName() throws DebugException {
+ return "PDA";
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IDebugTarget#supportsBreakpoint(org.eclipse.debug.core.model.IBreakpoint)
+ */
+ public boolean supportsBreakpoint(IBreakpoint breakpoint) {
+ if (!isTerminated() && breakpoint.getModelIdentifier().equals(getModelIdentifier())) {
+ try {
+ String program = getLaunch().getLaunchConfiguration().getAttribute(DebugCorePlugin.ATTR_PDA_PROGRAM, (String)null);
+ if (program != null) {
+ IResource resource = null;
+ if (breakpoint instanceof PDARunToLineBreakpoint) {
+ PDARunToLineBreakpoint rtl = (PDARunToLineBreakpoint) breakpoint;
+ resource = rtl.getSourceFile();
+ } else {
+ IMarker marker = breakpoint.getMarker();
+ if (marker != null) {
+ resource = marker.getResource();
+ }
+ }
+ if (resource != null) {
+ IPath p = new Path(program);
+ return resource.getFullPath().equals(p);
+ }
+ }
+ } catch (CoreException e) {
+ }
+ }
+ return false;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IDebugElement#getDebugTarget()
+ */
+ public IDebugTarget getDebugTarget() {
+ return this;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IDebugElement#getLaunch()
+ */
+ public ILaunch getLaunch() {
+ return fLaunch;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.ITerminate#canTerminate()
+ */
+ public boolean canTerminate() {
+ return getProcess().canTerminate();
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.ITerminate#isTerminated()
+ */
+ public boolean isTerminated() {
+ return fTerminated || getProcess().isTerminated();
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.ITerminate#terminate()
+ */
+ public void terminate() throws DebugException {
+ getThread().terminate();
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.ISuspendResume#canResume()
+ */
+ public boolean canResume() {
+ return !isTerminated() && isSuspended();
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.ISuspendResume#canSuspend()
+ */
+ public boolean canSuspend() {
+ return !isTerminated() && !isSuspended();
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.ISuspendResume#isSuspended()
+ */
+ public boolean isSuspended() {
+ return !isTerminated() && getThread().isSuspended();
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.ISuspendResume#resume()
+ */
+ public void resume() throws DebugException {
+ getThread().resume();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.ISuspendResume#suspend()
+ */
+ public void suspend() throws DebugException {
+ getThread().suspend();
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.IBreakpointListener#breakpointAdded(org.eclipse.debug.core.model.IBreakpoint)
+ */
+ public void breakpointAdded(IBreakpoint breakpoint) {
+ if (supportsBreakpoint(breakpoint)) {
+ try {
+ if ((breakpoint.isEnabled() && getBreakpointManager().isEnabled()) || !breakpoint.isRegistered()) {
+ PDALineBreakpoint pdaBreakpoint = (PDALineBreakpoint)breakpoint;
+ pdaBreakpoint.install(this);
+ }
+ } catch (CoreException e) {
+ }
+ }
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.IBreakpointListener#breakpointRemoved(org.eclipse.debug.core.model.IBreakpoint, org.eclipse.core.resources.IMarkerDelta)
+ */
+ public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) {
+ if (supportsBreakpoint(breakpoint)) {
+ try {
+ PDALineBreakpoint pdaBreakpoint = (PDALineBreakpoint)breakpoint;
+ pdaBreakpoint.remove(this);
+ } catch (CoreException e) {
+ }
+ }
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.IBreakpointListener#breakpointChanged(org.eclipse.debug.core.model.IBreakpoint, org.eclipse.core.resources.IMarkerDelta)
+ */
+ public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) {
+ if (supportsBreakpoint(breakpoint)) {
+ try {
+ if (breakpoint.isEnabled() && getBreakpointManager().isEnabled()) {
+ breakpointAdded(breakpoint);
+ } else {
+ breakpointRemoved(breakpoint, null);
+ }
+ } catch (CoreException e) {
+ }
+ }
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IDisconnect#canDisconnect()
+ */
+ public boolean canDisconnect() {
+ return false;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IDisconnect#disconnect()
+ */
+ public void disconnect() throws DebugException {
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IDisconnect#isDisconnected()
+ */
+ public boolean isDisconnected() {
+ return false;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#supportsStorageRetrieval()
+ */
+ public boolean supportsStorageRetrieval() {
+ return false;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#getMemoryBlock(long, long)
+ */
+ public IMemoryBlock getMemoryBlock(long startAddress, long length) throws DebugException {
+ return null;
+ }
+
+ /**
+ * Notification we have connected to the VM and it has started.
+ * Resume the VM.
+ */
+ private void started() {
+ fireCreationEvent();
+ installDeferredBreakpoints();
+ try {
+ resume();
+ } catch (DebugException e) {
+ }
+ }
+
+ /**
+ * Install breakpoints that are already registered with the breakpoint
+ * manager.
+ */
+ private void installDeferredBreakpoints() {
+ IBreakpoint[] breakpoints = getBreakpointManager().getBreakpoints(getModelIdentifier());
+ for (int i = 0; i < breakpoints.length; i++) {
+ breakpointAdded(breakpoints[i]);
+ }
+ }
+
+ /**
+ * Called when this debug target terminates.
+ */
+ private synchronized void terminated() {
+ fTerminated = true;
+ fThread = null;
+ fThreads = new IThread[0];
+ IBreakpointManager breakpointManager = getBreakpointManager();
+ breakpointManager.removeBreakpointListener(this);
+ breakpointManager.removeBreakpointManagerListener(this);
+ fireTerminateEvent();
+ removeEventListener(this);
+ }
+
+ /**
+ * Returns the values on the data stack (top down)
+ *
+ * @return the values on the data stack (top down)
+ */
+ public IValue[] getDataStack() throws DebugException {
+ String dataStack = sendRequest("data");
+ if (dataStack != null && dataStack.length() > 0) {
+ String[] values = dataStack.split("\\|");
+ IValue[] theValues = new IValue[values.length];
+ for (int i = 0; i < values.length; i++) {
+ String value = values[values.length - i - 1];
+ theValues[i] = new PDAStackValue(this, value, i);
+ }
+ return theValues;
+ }
+ return new IValue[0];
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.examples.core.pda.model.PDADebugElement#sendRequest(java.lang.String)
+ */
+ public String sendRequest(String request) throws DebugException {
+ synchronized (fRequestSocket) {
+ fRequestWriter.println(request);
+ fRequestWriter.flush();
+ try {
+ // wait for reply
+ return fRequestReader.readLine();
+ } catch (IOException e) {
+ requestFailed("Request failed: " + request, e);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * When the breakpoint manager disables, remove all registered breakpoints
+ * requests from the VM. When it enables, reinstall them.
+ */
+ public void breakpointManagerEnablementChanged(boolean enabled) {
+ IBreakpoint[] breakpoints = getBreakpointManager().getBreakpoints(getModelIdentifier());
+ for (int i = 0; i < breakpoints.length; i++) {
+ if (enabled) {
+ breakpointAdded(breakpoints[i]);
+ } else {
+ breakpointRemoved(breakpoints[i], null);
+ }
+ }
+ }
+
+ /**
+ * Returns whether popping the data stack is currently permitted
+ *
+ * @return whether popping the data stack is currently permitted
+ */
+ public boolean canPop() {
+ try {
+ return !isTerminated() && isSuspended() && getDataStack().length > 0;
+ } catch (DebugException e) {
+ }
+ return false;
+ }
+
+ /**
+ * Pops and returns the top of the data stack
+ *
+ * @return the top value on the stack
+ * @throws DebugException if the stack is empty or the request fails
+ */
+ public IValue pop() throws DebugException {
+ IValue[] dataStack = getDataStack();
+ if (dataStack.length > 0) {
+ sendRequest("popdata");
+ return dataStack[0];
+ }
+ requestFailed("Empty stack", null);
+ return null;
+ }
+
+ /**
+ * Returns whether pushing a value is currently supported.
+ *
+ * @return whether pushing a value is currently supported
+ */
+ public boolean canPush() {
+ return !isTerminated() && isSuspended();
+ }
+
+ /**
+ * Pushes a value onto the stack.
+ *
+ * @param value value to push
+ * @throws DebugException on failure
+ */
+ public void push(String value) throws DebugException {
+ sendRequest("pushdata " + value);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.examples.core.pda.model.IPDAEventListener#handleEvent(java.lang.String)
+ */
+ public void handleEvent(String event) {
+ if (event.equals("started")) {
+ started();
+ } else if (event.equals("terminated")) {
+ terminated();
+ }
+ }
+
+ /**
+ * Returns this debug target's single thread, or <code>null</code>
+ * if terminated.
+ *
+ * @return this debug target's single thread, or <code>null</code>
+ * if terminated
+ */
+ public synchronized PDAThread getThread() {
+ return fThread;
+ }
+}

Back to the top