diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF
index c768637b570..1a96a0189b8 100644
--- a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF
@@ -12,6 +12,8 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.debug.core,
org.eclipse.debug.ui,
org.eclipse.ui.ide,
+ org.eclipse.jface.text,
+ org.eclipse.ui.workbench.texteditor,
org.eclipse.dd.dsf,
org.eclipse.dd.dsf.ui,
org.eclipse.dd.dsf.debug,
@@ -24,5 +26,7 @@ Export-Package:
org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport,
org.eclipse.dd.dsf.debug.ui.viewmodel.launch,
org.eclipse.dd.dsf.debug.ui.viewmodel.register,
- org.eclipse.dd.dsf.debug.ui.viewmodel.variable
+ org.eclipse.dd.dsf.debug.ui.viewmodel.variable,
+ org.eclipse.dd.dsf.debug.ui.sourcelookup,
+ org.eclipse.dd.dsf.debug.ui.actions
Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml
index 614503dc5b9..ec8c6e8158e 100644
--- a/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/plugin.xml
@@ -7,4 +7,50 @@
delegateClass="org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionDelegate"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java
new file mode 100644
index 00000000000..d77cfa1a26d
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.ui.actions;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.dd.dsf.concurrent.DsfRunnable;
+import org.eclipse.dd.dsf.concurrent.Immutable;
+import org.eclipse.dd.dsf.datamodel.DMContexts;
+import org.eclipse.dd.dsf.debug.service.INativeProcesses;
+import org.eclipse.dd.dsf.debug.service.IRunControl;
+import org.eclipse.dd.dsf.debug.service.IStepQueueManager;
+import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
+import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
+import org.eclipse.dd.dsf.service.DsfServicesTracker;
+import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode;
+import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext;
+import org.eclipse.debug.core.commands.IDebugCommandRequest;
+
+@SuppressWarnings("restriction")
+@Immutable
+public abstract class DsfCommandRunnable extends DsfRunnable {
+ private final IExecutionDMContext fContext;
+ private final DsfServicesTracker fTracker;
+ private final IDebugCommandRequest fRequest;
+
+ public IExecutionDMContext getContext() { return fContext; }
+ public IRunControl getRunControl() {
+ return fTracker.getService(IRunControl.class);
+ }
+ public IStepQueueManager getStepQueueMgr() {
+ return fTracker.getService(IStepQueueManager.class);
+ }
+
+ public INativeProcesses getProcesses() {
+ return fTracker.getService(INativeProcesses.class);
+ }
+
+ public DsfCommandRunnable(DsfServicesTracker servicesTracker, Object element, IDebugCommandRequest request) {
+ fTracker = servicesTracker;
+ if (element instanceof DMVMContext) {
+ // Javac doesn't like the cast to "(AbstractDMVMLayoutNode>.DMVMContext)" need to use the
+ // construct below and suppress warnings.
+ @SuppressWarnings("unchecked")
+ AbstractDMVMLayoutNode.DMVMContext vmc = (AbstractDMVMLayoutNode.DMVMContext)element;
+ fContext = DMContexts.getAncestorOfType(vmc.getDMC(), IExecutionDMContext.class);
+ } else {
+ fContext = null;
+ }
+
+ fRequest = request;
+ }
+
+ public final void run() {
+ if (fRequest.isCanceled()) return;
+ if (getContext() == null) {
+ fRequest.setStatus(makeError("Selected object does not support run control.", null)); //$NON-NLS-1$
+ } else if (getRunControl() == null) {
+ fRequest.setStatus(makeError("Run Control not available", null)); //$NON-NLS-1$
+ } else {
+ doExecute();
+ }
+ fRequest.done();
+ }
+
+ /**
+ * Method to perform the actual work. It should not call monitor.done(), because
+ * it will be called in the super-class.
+ */
+ protected abstract void doExecute();
+
+ protected IStatus makeError(String message, Throwable e) {
+ return new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, -1, message, e);
+ }
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfResumeCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfResumeCommand.java
new file mode 100644
index 00000000000..23adc2644d4
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfResumeCommand.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.ui.actions;
+
+import org.eclipse.dd.dsf.concurrent.DsfExecutor;
+import org.eclipse.dd.dsf.concurrent.Immutable;
+import org.eclipse.dd.dsf.concurrent.RequestMonitor;
+import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
+import org.eclipse.dd.dsf.service.DsfServicesTracker;
+import org.eclipse.dd.dsf.service.DsfSession;
+import org.eclipse.debug.core.commands.IDebugCommandRequest;
+import org.eclipse.debug.core.commands.IEnabledStateRequest;
+import org.eclipse.debug.core.commands.IResumeHandler;
+
+@Immutable
+public class DsfResumeCommand implements IResumeHandler {
+
+ private final DsfExecutor fExecutor;
+ private final DsfServicesTracker fTracker;
+
+ public DsfResumeCommand(DsfSession session) {
+ fExecutor = session.getExecutor();
+ fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId());
+ }
+
+ public void dispose() {
+ fTracker.dispose();
+ }
+
+ public void canExecute(final IEnabledStateRequest request) {
+ if (request.getElements().length != 1) {
+ request.setEnabled(false);
+ request.done();
+ return;
+ }
+
+ fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
+ @Override public void doExecute() {
+ request.setEnabled(getRunControl().canResume(getContext()));
+ }
+ });
+ }
+
+ public boolean execute(final IDebugCommandRequest request) {
+ if (request.getElements().length != 1) {
+ request.done();
+ return false;
+ }
+
+ fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
+ @Override public void doExecute() {
+ getRunControl().resume(getContext(), new RequestMonitor(fExecutor, null));
+ }
+ });
+ return false;
+ }
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java
new file mode 100644
index 00000000000..16c1b183d48
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.ui.actions;
+
+import org.eclipse.dd.dsf.concurrent.DsfExecutor;
+import org.eclipse.dd.dsf.concurrent.Immutable;
+import org.eclipse.dd.dsf.debug.service.IRunControl.StepType;
+import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
+import org.eclipse.dd.dsf.service.DsfServicesTracker;
+import org.eclipse.dd.dsf.service.DsfSession;
+import org.eclipse.debug.core.commands.IDebugCommandRequest;
+import org.eclipse.debug.core.commands.IEnabledStateRequest;
+import org.eclipse.debug.core.commands.IStepIntoHandler;
+
+@Immutable
+public class DsfStepIntoCommand implements IStepIntoHandler {
+
+ private final DsfExecutor fExecutor;
+ private final DsfServicesTracker fTracker;
+
+ public DsfStepIntoCommand(DsfSession session) {
+ fExecutor = session.getExecutor();
+ fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId());
+ }
+
+ public void dispose() {
+ fTracker.dispose();
+ }
+
+ public void canExecute(final IEnabledStateRequest request) {
+ if (request.getElements().length != 1) {
+ request.setEnabled(false);
+ request.done();
+ return;
+ }
+
+ fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
+ @Override public void doExecute() {
+ request.setEnabled(getStepQueueMgr().canEnqueueStep(getContext()));
+ }
+ });
+ }
+
+ public boolean execute(final IDebugCommandRequest request) {
+ if (request.getElements().length != 1) {
+ request.done();
+ return false;
+ }
+
+ fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
+ @Override public void doExecute() {
+ getStepQueueMgr().enqueueStep(getContext(), StepType.STEP_INTO);
+ }
+ });
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java
new file mode 100644
index 00000000000..6881453e80d
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.ui.actions;
+
+import org.eclipse.dd.dsf.concurrent.DsfExecutor;
+import org.eclipse.dd.dsf.concurrent.Immutable;
+import org.eclipse.dd.dsf.debug.service.IRunControl.StepType;
+import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
+import org.eclipse.dd.dsf.service.DsfServicesTracker;
+import org.eclipse.dd.dsf.service.DsfSession;
+import org.eclipse.debug.core.commands.IDebugCommandRequest;
+import org.eclipse.debug.core.commands.IEnabledStateRequest;
+import org.eclipse.debug.core.commands.IStepIntoHandler;
+
+@Immutable
+public class DsfStepOverCommand implements IStepIntoHandler {
+
+ private final DsfExecutor fExecutor;
+ private final DsfServicesTracker fTracker;
+
+ public DsfStepOverCommand(DsfSession session) {
+ fExecutor = session.getExecutor();
+ fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId());
+ }
+
+ public void dispose() {
+ fTracker.dispose();
+ }
+
+ public void canExecute(final IEnabledStateRequest request) {
+ if (request.getElements().length != 1) {
+ request.setEnabled(false);
+ request.done();
+ return;
+ }
+
+ fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
+ @Override public void doExecute() {
+ request.setEnabled(getStepQueueMgr().canEnqueueStep(getContext()));
+ }
+ });
+ }
+
+ public boolean execute(final IDebugCommandRequest request) {
+ if (request.getElements().length != 1) {
+ request.done();
+ return false;
+ }
+
+ fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
+ @Override public void doExecute() {
+ getStepQueueMgr().enqueueStep(getContext(), StepType.STEP_OVER);
+ }
+ });
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepReturnCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepReturnCommand.java
new file mode 100644
index 00000000000..0e179cebc19
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepReturnCommand.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.ui.actions;
+
+import org.eclipse.dd.dsf.concurrent.DsfExecutor;
+import org.eclipse.dd.dsf.concurrent.Immutable;
+import org.eclipse.dd.dsf.debug.service.IRunControl.StepType;
+import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
+import org.eclipse.dd.dsf.service.DsfServicesTracker;
+import org.eclipse.dd.dsf.service.DsfSession;
+import org.eclipse.debug.core.commands.IDebugCommandRequest;
+import org.eclipse.debug.core.commands.IEnabledStateRequest;
+import org.eclipse.debug.core.commands.IStepIntoHandler;
+
+@Immutable
+public class DsfStepReturnCommand implements IStepIntoHandler {
+
+ private final DsfExecutor fExecutor;
+ private final DsfServicesTracker fTracker;
+
+ public DsfStepReturnCommand(DsfSession session) {
+ fExecutor = session.getExecutor();
+ fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId());
+ }
+
+ public void dispose() {
+ fTracker.dispose();
+ }
+
+ public void canExecute(final IEnabledStateRequest request) {
+ if (request.getElements().length != 1) {
+ request.setEnabled(false);
+ request.done();
+ return;
+ }
+
+ fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
+ @Override public void doExecute() {
+ request.setEnabled(getStepQueueMgr().canEnqueueStep(getContext()));
+ }
+ });
+ }
+
+ public boolean execute(final IDebugCommandRequest request) {
+ if (request.getElements().length != 1) {
+ request.done();
+ return false;
+ }
+
+ fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
+ @Override public void doExecute() {
+ getStepQueueMgr().enqueueStep(getContext(), StepType.STEP_RETURN);
+ }
+ });
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfSuspendCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfSuspendCommand.java
new file mode 100644
index 00000000000..882d165fe09
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfSuspendCommand.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.ui.actions;
+
+import org.eclipse.dd.dsf.concurrent.DsfExecutor;
+import org.eclipse.dd.dsf.concurrent.Immutable;
+import org.eclipse.dd.dsf.concurrent.RequestMonitor;
+import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
+import org.eclipse.dd.dsf.service.DsfServicesTracker;
+import org.eclipse.dd.dsf.service.DsfSession;
+import org.eclipse.debug.core.commands.IDebugCommandRequest;
+import org.eclipse.debug.core.commands.IEnabledStateRequest;
+import org.eclipse.debug.core.commands.ISuspendHandler;
+
+@Immutable
+public class DsfSuspendCommand implements ISuspendHandler {
+ private final DsfExecutor fExecutor;
+ private final DsfServicesTracker fTracker;
+
+ public DsfSuspendCommand(DsfSession session) {
+ fExecutor = session.getExecutor();
+ fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId());
+ }
+
+ public void dispose() {
+ fTracker.dispose();
+ }
+
+ public void canExecute(final IEnabledStateRequest request) {
+ if (request.getElements().length != 1) {
+ request.setEnabled(false);
+ request.done();
+ return;
+ }
+
+ fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
+ @Override public void doExecute() {
+ request.setEnabled(getRunControl().canSuspend(getContext()));
+ }
+ });
+ }
+
+ public boolean execute(final IDebugCommandRequest request) {
+ if (request.getElements().length != 1) {
+ request.done();
+ return false;
+ }
+
+ fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
+ @Override public void doExecute() {
+ getRunControl().suspend(getContext(), new RequestMonitor(fExecutor, null));
+ }
+ });
+ return false;
+ }
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfTerminateCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfTerminateCommand.java
new file mode 100644
index 00000000000..5f1af3cd6a9
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfTerminateCommand.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.ui.actions;
+
+import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
+import org.eclipse.dd.dsf.concurrent.DsfExecutor;
+import org.eclipse.dd.dsf.concurrent.DsfRunnable;
+import org.eclipse.dd.dsf.concurrent.RequestMonitor;
+import org.eclipse.dd.dsf.datamodel.DMContexts;
+import org.eclipse.dd.dsf.debug.service.INativeProcesses;
+import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
+import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
+import org.eclipse.dd.dsf.service.DsfServicesTracker;
+import org.eclipse.dd.dsf.service.DsfSession;
+import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode;
+import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext;
+import org.eclipse.debug.core.commands.IDebugCommandRequest;
+import org.eclipse.debug.core.commands.IEnabledStateRequest;
+import org.eclipse.debug.core.commands.ITerminateHandler;
+
+public class DsfTerminateCommand implements ITerminateHandler {
+ private final DsfExecutor fExecutor;
+ private final DsfServicesTracker fTracker;
+
+ public DsfTerminateCommand(DsfSession session) {
+ fExecutor = session.getExecutor();
+ fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId());
+ }
+
+ public void dispose() {
+ fTracker.dispose();
+ }
+
+ // Run control may not be avilable after a connection is terminated and shut down.
+ public void canExecute(final IEnabledStateRequest request) {
+ if (request.getElements().length != 1 ||
+ !(request.getElements()[0] instanceof DMVMContext) )
+ {
+ request.setEnabled(false);
+ request.done();
+ return;
+ }
+
+ // Javac doesn't like the cast to "(AbstractDMVMLayoutNode>.DMVMContext)" need to use the
+ // construct below and suppress warnings.
+ @SuppressWarnings("unchecked")
+ AbstractDMVMLayoutNode>.DMVMContext vmc = (AbstractDMVMLayoutNode.DMVMContext)request.getElements()[0];
+ final IExecutionDMContext dmc = DMContexts.getAncestorOfType(vmc.getDMC(), IExecutionDMContext.class);
+ if (dmc == null) {
+ request.setEnabled(false);
+ request.done();
+ return;
+ }
+
+ fExecutor.execute(
+ new DsfRunnable() {
+ public void run() {
+ // Get the processes service and the exec context.
+ INativeProcesses processes = fTracker.getService(INativeProcesses.class);
+ if (processes == null || dmc == null) {
+ // Context or service already invalid.
+ request.done();
+ } else {
+ // Check the teriminate.
+ processes.canTerminate(
+ processes.getThreadForExecutionContext(dmc),
+ new DataRequestMonitor(fExecutor, null) {
+ @Override
+ public void handleCompleted() {
+ request.setEnabled(getData());
+ request.done();
+ }
+ });
+ }
+ }
+ });
+ }
+
+ public boolean execute(final IDebugCommandRequest request) {
+ if (request.getElements().length != 1) {
+ request.done();
+ return false;
+ }
+
+ fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
+ @Override public void doExecute() {
+ getProcesses().terminate(
+ getProcesses().getThreadForExecutionContext(getContext()), new RequestMonitor(fExecutor, null));
+ }
+ });
+ return false;
+ }
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/InstructionPointerImageProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/InstructionPointerImageProvider.java
new file mode 100644
index 00000000000..4c3d3bc6c99
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/InstructionPointerImageProvider.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+
+package org.eclipse.dd.dsf.debug.ui.sourcelookup;
+
+import org.eclipse.dd.dsf.concurrent.ThreadSafe;
+import org.eclipse.dd.dsf.debug.ui.sourcelookup.InstructionPointerManager.IPAnnotation;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.texteditor.IAnnotationImageProvider;
+
+@ThreadSafe
+public class InstructionPointerImageProvider implements IAnnotationImageProvider {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.texteditor.IAnnotationImageProvider#getManagedImage(org.eclipse.jface.text.source.Annotation)
+ */
+ public Image getManagedImage(Annotation annotation) {
+ return ((IPAnnotation)annotation).getImage();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.texteditor.IAnnotationImageProvider#getImageDescriptorId(org.eclipse.jface.text.source.Annotation)
+ */
+ public String getImageDescriptorId(Annotation annotation) {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.texteditor.IAnnotationImageProvider#getImageDescriptor(java.lang.String)
+ */
+ public ImageDescriptor getImageDescriptor(String imageDescritporId) {
+ return null;
+ }
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/InstructionPointerManager.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/InstructionPointerManager.java
new file mode 100644
index 00000000000..d24ddce5c3a
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/InstructionPointerManager.java
@@ -0,0 +1,231 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * Wind River Systems - Adapter to use with DSF
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.ui.sourcelookup;
+
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.dd.dsf.concurrent.ThreadSafe;
+import org.eclipse.dd.dsf.datamodel.DMContexts;
+import org.eclipse.dd.dsf.debug.service.IRunControl;
+import org.eclipse.dd.dsf.debug.service.IStack;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * This class tracks instruction pointer contexts for a single DSF session.
+ */
+@ThreadSafe
+class InstructionPointerManager {
+
+ /**
+ * Editor annotation object for instruction pointers.
+ */
+ static class IPAnnotation extends Annotation {
+
+ /** The image for this annotation. */
+ private Image fImage;
+
+ /** Frame DMC that this IP is for **/
+ private IStack.IFrameDMContext fFrame;
+
+ /**
+ * Constructs an instruction pointer image.
+ *
+ * @param frame stack frame the instruction pointer is associated with
+ * @param annotationType the type of annotation to display (annotation identifier)
+ * @param text the message to display with the annotation as hover help
+ * @param image the image used to display the annotation
+ */
+ IPAnnotation(IStack.IFrameDMContext frame, String annotationType, String text, Image image) {
+ super(annotationType, false, text);
+ fFrame = frame;
+ fImage = image;
+ }
+
+ /**
+ * Returns this annotation's image.
+ *
+ * @return image
+ */
+ protected Image getImage() {
+ return fImage;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object other) {
+ if (other instanceof IPAnnotation) {
+ return fFrame.equals(((IPAnnotation)other).fFrame);
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return fFrame.hashCode();
+ }
+
+ }
+
+ /**
+ * Represents the context for a single instruction pointer. This is a convenience class
+ * used to store the three objects that comprise an instruction pointer 'context' so it
+ * can be stored in collections.
+ */
+ static class AnnotationWrapper {
+
+ /** The text editor for this context. */
+ private ITextEditor fTextEditor;
+
+ /** Stack frame that this annotation is for */
+ private IStack.IFrameDMContext fFrameDmc;
+
+ /** The vertical ruler annotation for this context. */
+ private Annotation fAnnotation;
+
+ AnnotationWrapper(ITextEditor textEditor, Annotation annotation, IStack.IFrameDMContext frameDmc) {
+ fTextEditor = textEditor;
+ fAnnotation = annotation;
+ fFrameDmc = frameDmc;
+ }
+
+ /**
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object other) {
+ if (other instanceof AnnotationWrapper) {
+ AnnotationWrapper otherContext = (AnnotationWrapper) other;
+ return getAnnotation().equals(otherContext.getAnnotation());
+ }
+ return false;
+ }
+
+ /**
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return getAnnotation().hashCode();
+ }
+
+ ITextEditor getTextEditor() { return fTextEditor; }
+ Annotation getAnnotation() { return fAnnotation; }
+ IStack.IFrameDMContext getFrameDMC() { return fFrameDmc; }
+ }
+
+ /**
+ * Mapping of IDebugTarget objects to (mappings of IThread objects to lists of instruction
+ * pointer contexts).
+ */
+ private List fAnnotationWrappers;
+
+ /**
+ * Clients must not instantiate this class.
+ */
+ public InstructionPointerManager() {
+ fAnnotationWrappers = Collections.synchronizedList(new LinkedList());
+ }
+
+ /**
+ * Add an instruction pointer annotation in the specified editor for the
+ * specified stack frame.
+ */
+ public void addAnnotation(ITextEditor textEditor, IStack.IFrameDMContext frame, Position position, boolean isTopFrame) {
+
+ IDocumentProvider docProvider = textEditor.getDocumentProvider();
+ IEditorInput editorInput = textEditor.getEditorInput();
+ // If there is no annotation model, there's nothing more to do
+ IAnnotationModel annModel = docProvider.getAnnotationModel(editorInput);
+ if (annModel == null) {
+ return;
+ }
+
+ String id;
+ String text;
+ Image image;
+ if (isTopFrame) {
+ id = "org.eclipse.dd.debug.currentIP"; //$NON-NLS-1$
+ text = "Debug Current Instruction Pointer"; //$NON-NLS-1$
+ image = DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER_TOP);
+ } else {
+ id = "org.eclipse.dd.debug.secondaryIP"; //$NON-NLS-1$
+ text = "Debug Call Stack"; //$NON-NLS-1$
+ image = DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER);
+ }
+
+ Annotation annotation = new IPAnnotation(frame, id, text, image);
+
+ // Add the annotation at the position to the editor's annotation model.
+ annModel.removeAnnotation(annotation);
+ annModel.addAnnotation(annotation, position);
+
+ // Add to list of existing wrappers
+ fAnnotationWrappers.add(new AnnotationWrapper(textEditor, annotation, frame));
+ }
+
+ /**
+ * Remove all annotations associated with the specified debug target that this class
+ * is tracking.
+ */
+ public void removeAnnotations(IRunControl.IExecutionDMContext execDmc) {
+ // Retrieve the mapping of threads to context lists
+ synchronized(fAnnotationWrappers) {
+ for (Iterator wrapperItr = fAnnotationWrappers.iterator(); wrapperItr.hasNext();) {
+ AnnotationWrapper wrapper = wrapperItr.next();
+ if (DMContexts.isAncestorOf(wrapper.getFrameDMC(), execDmc)) {
+ removeAnnotation(wrapper.getTextEditor(), wrapper.getAnnotation());
+ wrapperItr.remove();
+ }
+ }
+ }
+ }
+
+ /** Removes all annotations tracked by this manager */
+ public void removeAllAnnotations() {
+ synchronized(fAnnotationWrappers) {
+ for (AnnotationWrapper wrapper : fAnnotationWrappers) {
+ removeAnnotation(wrapper.getTextEditor(), wrapper.getAnnotation());
+ }
+ fAnnotationWrappers.clear();
+ }
+ }
+
+ /**
+ * Remove the specified annotation from the specified text editor.
+ */
+ private void removeAnnotation(ITextEditor textEditor, Annotation annotation) {
+ IDocumentProvider docProvider = textEditor.getDocumentProvider();
+ if (docProvider != null) {
+ IAnnotationModel annotationModel = docProvider.getAnnotationModel(textEditor.getEditorInput());
+ if (annotationModel != null) {
+ annotationModel.removeAnnotation(annotation);
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java
new file mode 100644
index 00000000000..38cab0bd740
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/MISourceDisplayAdapter.java
@@ -0,0 +1,552 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.ui.sourcelookup;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.RejectedExecutionException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
+import org.eclipse.dd.dsf.concurrent.DsfExecutor;
+import org.eclipse.dd.dsf.concurrent.DsfRunnable;
+import org.eclipse.dd.dsf.concurrent.Query;
+import org.eclipse.dd.dsf.concurrent.ThreadSafe;
+import org.eclipse.dd.dsf.datamodel.DMContexts;
+import org.eclipse.dd.dsf.datamodel.IDMContext;
+import org.eclipse.dd.dsf.debug.service.IRunControl;
+import org.eclipse.dd.dsf.debug.service.IStack;
+import org.eclipse.dd.dsf.debug.service.IStepQueueManager;
+import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason;
+import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
+import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMData;
+import org.eclipse.dd.dsf.debug.sourcelookup.DsfMISourceLookupParticipant;
+import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin;
+import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
+import org.eclipse.dd.dsf.service.DsfServicesTracker;
+import org.eclipse.dd.dsf.service.DsfSession;
+import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode.DMVMContext;
+import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
+import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant;
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.debug.ui.sourcelookup.CommonSourceNotFoundEditorInput;
+import org.eclipse.debug.ui.sourcelookup.ISourceDisplay;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorRegistry;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.progress.UIJob;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Source display adapter that performs the source lookup, opens the editor,
+ * and paints the IP for the given object.
+ *
+ * The implementation relies on three types of jobs to perform the operations.
+ * - The first kind, "lookup job" performs the source lookup operation.
+ * - The second "display job" positions and annotates the editor.
+ * - The third clears the old IP annotations when a thread or process has resumed
+ * or exited.
+ *
+ * The the lookup jobs can run in parallel with the display or the clearing job,
+ * but the clearing job and the display job must not run at the same time.
+ * Hence there is some involved logic which ensures that the jobs are run in
+ * proper order. To avoid race conditions, this logic uses the session's
+ * dispatch thread to synchronize access to the state data of the running jobs.
+ */
+@ThreadSafe
+@SuppressWarnings("restriction")
+public class MISourceDisplayAdapter implements ISourceDisplay
+{
+ /**
+ * A job to perform source lookup on the given DMC.
+ */
+ class LookupJob extends Job {
+
+ private IDMContext> fDmc;
+ private IWorkbenchPage fPage;
+
+ /**
+ * Constructs a new source lookup job.
+ */
+ public LookupJob(IDMContext> dmc, IWorkbenchPage page) {
+ super("DSF Source Lookup"); //$NON-NLS-1$
+ setPriority(Job.INTERACTIVE);
+ setSystem(true);
+ fDmc = dmc;
+ fPage = page;
+ }
+
+ IDMContext> getDmc() { return fDmc; }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ protected IStatus run(final IProgressMonitor monitor) {
+ if (monitor.isCanceled()) {
+ return Status.CANCEL_STATUS;
+ }
+
+ final SourceLookupResult result = performLookup();
+ executeFromJob(new DsfRunnable() { public void run() {
+ if (!monitor.isCanceled()) {
+ fPrevResult = result;
+ fPrevModelContext = fDmc;
+ fRunningLookupJob = null;
+ startDisplayJob(fPrevResult, fPage);
+ }
+ }});
+ return Status.OK_STATUS;
+ }
+
+ private SourceLookupResult performLookup() {
+ SourceLookupResult result = new SourceLookupResult(fDmc, null, null, null);
+ String editorId = null;
+ IEditorInput editorInput = null;
+ Object sourceElement = fSourceLookup.getSourceElement(fDmc);
+
+ if (sourceElement == null) {
+ editorInput = new CommonSourceNotFoundEditorInput(fDmc);
+ editorId = IDebugUIConstants.ID_COMMON_SOURCE_NOT_FOUND_EDITOR;
+ } else if (sourceElement instanceof IFile) {
+ editorId = getEditorIdForFilename(((IFile)sourceElement).getName());
+ editorInput = new FileEditorInput((IFile)sourceElement);
+ }
+ result.setEditorInput(editorInput);
+ result.setEditorId(editorId);
+ result.setSourceElement(sourceElement);
+
+ return result;
+ }
+
+ private String getEditorIdForFilename(String filename) {
+ IEditorRegistry registry = PlatformUI.getWorkbench().getEditorRegistry();
+ IEditorDescriptor descriptor = registry.getDefaultEditor(filename);
+ if (descriptor == null) {
+ return "org.eclipse.ui.DefaultTextEditor"; //$NON-NLS-1$
+ }
+
+ return descriptor.getId();
+ }
+ }
+
+ /**
+ * Job that positions the editor and paints the IP Annotation for given DMC.
+ */
+ class DisplayJob extends UIJob {
+ private SourceLookupResult fResult;
+ private IWorkbenchPage fPage;
+
+ IDMContext> getDmc() { return fResult.getDmc(); }
+
+ /**
+ * Constructs a new source display job
+ */
+ public DisplayJob(SourceLookupResult result, IWorkbenchPage page) {
+ super("Debug Source Display"); //$NON-NLS-1$
+ setSystem(true);
+ setPriority(Job.INTERACTIVE);
+ fResult = result;
+ fPage = page;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public IStatus runInUIThread(final IProgressMonitor monitor) {
+ DsfRunnable displayJobFinishedRunnable = new DsfRunnable() {
+ public void run() {
+ // If the current display job does not match up with "this", it means that this job got cancelled
+ // after it already completed and after this runnable was queued into the dispatch thread.
+ if (fRunningDisplayJob == DisplayJob.this) {
+ fRunningDisplayJob = null;
+ serviceDisplayAndClearingJobs();
+ }
+ }
+ };
+
+ if (monitor.isCanceled()) {
+ executeFromJob(displayJobFinishedRunnable);
+ return Status.CANCEL_STATUS;
+ }
+
+ IEditorPart editor = openEditor(fResult, fPage);
+ if (editor == null) {
+ executeFromJob(displayJobFinishedRunnable);
+ return Status.OK_STATUS;
+ }
+
+ ITextEditor textEditor = null;
+ if (editor instanceof ITextEditor) {
+ textEditor = (ITextEditor)editor;
+ } else {
+ textEditor = (ITextEditor) editor.getAdapter(ITextEditor.class);
+ }
+ if (textEditor != null) {
+ positionEditor(textEditor, fResult.getDmc());
+ }
+
+ executeFromJob(displayJobFinishedRunnable);
+
+ return Status.OK_STATUS;
+ }
+
+ /**
+ * Opens the editor used to display the source for an element selected in
+ * this view and returns the editor that was opened or null if
+ * no editor could be opened.
+ */
+ private IEditorPart openEditor(SourceLookupResult result, IWorkbenchPage page) {
+ IEditorInput input= result.getEditorInput();
+ String id= result.getEditorId();
+ if (input == null || id == null) {
+ return null;
+ }
+
+ return openEditor(page, input, id);
+ }
+
+ /**
+ * Opens an editor in the workbench and returns the editor that was opened
+ * or null if an error occurred while attempting to open the
+ * editor.
+ */
+ private IEditorPart openEditor(final IWorkbenchPage page, final IEditorInput input, final String id) {
+ final IEditorPart[] editor = new IEditorPart[] {null};
+ Runnable r = new Runnable() {
+ public void run() {
+ if (!page.getWorkbenchWindow().getWorkbench().isClosing()) {
+ try {
+ editor[0] = page.openEditor(input, id, false);
+ } catch (PartInitException e) {}
+ }
+ }
+ };
+ BusyIndicator.showWhile(Display.getDefault(), r);
+ return editor[0];
+ }
+
+ /**
+ * Positions the text editor for the given stack frame
+ */
+ private void positionEditor(ITextEditor editor, final IDMContext> dmc) {
+ if (!(dmc instanceof IFrameDMContext)) return;
+ final IFrameDMContext frameDmc = (IFrameDMContext)dmc;
+
+ // We need to retrieve the frame level and line number from the service.
+ // Normally we could just get the needed information from IFrameDMData, but
+ // IFrameDMData, which derives from IModelData can only be accessed on the
+ // dispatch thread, so we need to copy over relevant information from
+ // IFrameDMData into this structure so we can read it in the job thread.
+ class FramePositioningData {
+ int fLine;
+ int fLevel;
+ }
+
+ // Query the service for frame data. We are calling from a job thread,
+ // so we use the Query.get() method, which will block until the
+ // query is completed.
+ Query query = new Query(fExecutor) {
+ @Override
+ protected void execute(final DataRequestMonitor rm) {
+ IStack stackService = fServicesTracker.getService(IStack.class);
+ if (stackService == null) {
+ doneException(new CoreException(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, -1, "Stack data not available", null))); //$NON-NLS-1$
+ return;
+ }
+ stackService.getModelData(
+ frameDmc,
+ new DataRequestMonitor(fExecutor, rm) {
+ @Override
+ public void handleOK() {
+ FramePositioningData clientData = new FramePositioningData();
+ clientData.fLevel = getData().getLevel();
+ // Document line numbers are 0-based. While debugger line numbers are 1-based.
+ clientData.fLine = getData().getLine() - 1;
+ rm.setData(clientData);
+ rm.done();
+ }
+ });
+ }
+ };
+ try {
+ fExecutor.execute(query);
+ FramePositioningData framePositioningData = query.get();
+ // If the frame data is not available, or the line number is not
+ // known, give up.
+ if (framePositioningData == null || framePositioningData.fLevel < 0) {
+ return;
+ }
+
+ // Position and annotate the editor.
+ IRegion region= getLineInformation(editor, framePositioningData.fLine);
+ if (region != null) {
+ editor.selectAndReveal(region.getOffset(), 0);
+ fIPManager.addAnnotation(
+ editor, frameDmc, new Position(region.getOffset(), region.getLength()),
+ framePositioningData.fLevel == 0);
+ }
+ } catch (InterruptedException e) { assert false : "Interrupted exception in DSF thread"; //$NON-NLS-1$
+ } catch (ExecutionException e) { // Ignore
+ }
+
+
+ }
+
+ /**
+ * Returns the line information for the given line in the given editor
+ */
+ private IRegion getLineInformation(ITextEditor editor, int lineNumber) {
+ IDocumentProvider provider= editor.getDocumentProvider();
+ IEditorInput input= editor.getEditorInput();
+ try {
+ provider.connect(input);
+ } catch (CoreException e) {
+ return null;
+ }
+ try {
+ IDocument document= provider.getDocument(input);
+ if (document != null)
+ return document.getLineInformation(lineNumber);
+ } catch (BadLocationException e) {
+ } finally {
+ provider.disconnect(input);
+ }
+ return null;
+ }
+
+ }
+
+ /**
+ * Job that removes the old IP Annotations associated with given execution
+ * context.
+ */
+ class ClearingJob extends UIJob {
+ List fDmcsToClear;
+
+ public ClearingJob(List dmcs) {
+ super("Debug Source Display"); //$NON-NLS-1$
+ setSystem(true);
+ setPriority(Job.INTERACTIVE);
+ fDmcsToClear = dmcs;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public IStatus runInUIThread(IProgressMonitor monitor) {
+ DsfRunnable clearingJobFinishedRunnable = new DsfRunnable() { public void run() {
+ assert fRunningClearingJob == ClearingJob.this;
+ fRunningClearingJob = null;
+ serviceDisplayAndClearingJobs();
+ }};
+
+ if (monitor.isCanceled()) {
+ executeFromJob(clearingJobFinishedRunnable);
+ return Status.CANCEL_STATUS;
+ }
+
+ for (IRunControl.IExecutionDMContext dmc : fDmcsToClear) {
+ fIPManager.removeAnnotations(dmc);
+ }
+
+ executeFromJob(clearingJobFinishedRunnable);
+ return Status.OK_STATUS;
+ }
+ }
+
+ private DsfSession fSession;
+ private DsfExecutor fExecutor;
+ private DsfServicesTracker fServicesTracker;
+ private IDMContext> fPrevModelContext;
+ private SourceLookupResult fPrevResult;
+ private ISourceLookupDirector fSourceLookup;
+ private DsfMISourceLookupParticipant fSourceLookupParticipant;
+ private InstructionPointerManager fIPManager;
+
+ private LookupJob fRunningLookupJob;
+ private DisplayJob fRunningDisplayJob;
+ private DisplayJob fPendingDisplayJob;
+ private ClearingJob fRunningClearingJob;
+ private List fPendingExecDmcsToClear = new LinkedList();
+
+ public MISourceDisplayAdapter(DsfSession session, ISourceLookupDirector sourceLocator) {
+ fSession = session;
+ fExecutor = session.getExecutor();
+ fServicesTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId());
+ fSourceLookup = sourceLocator;
+ fSourceLookupParticipant = new DsfMISourceLookupParticipant(session);
+ fSourceLookup.addParticipants(new ISourceLookupParticipant[] {fSourceLookupParticipant} );
+
+ fIPManager = new InstructionPointerManager();
+
+ fSession.addServiceEventListener(this, null);
+ }
+
+ public void dispose() {
+ fSession.removeServiceEventListener(this);
+ fServicesTracker.dispose();
+ fSourceLookup.removeParticipants(new ISourceLookupParticipant[] {fSourceLookupParticipant});
+
+ // fSourceLookupParticipant is disposed by teh source lookup director
+
+ // Need to remove annotations in UI thread.
+ //fIPManager.removeAllAnnotations();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.contexts.ISourceDisplayAdapter#displaySource(java.lang.Object, org.eclipse.ui.IWorkbenchPage, boolean)
+ */
+ public void displaySource(Object context, final IWorkbenchPage page, final boolean force) {
+ if (!(context instanceof DMVMContext)) return;
+ // Correct cast: (AbstractDMVMLayoutNode>.DMVMContext) breaks the javac compiler
+ @SuppressWarnings("unchecked")
+ final IDMContext> dmc = ((DMVMContext)context).getDMC();
+
+ // Quick test. DMC is checked again in source lookup participant, but
+ // it's much quicker to test here.
+ if (!(dmc instanceof IFrameDMContext)) return;
+
+ // Re-dispatch to executor thread before accessing job lists.
+ fExecutor.execute(new DsfRunnable() { public void run() {
+ if (!force && dmc.equals(fPrevModelContext)) {
+ fPrevResult.updateArtifact(dmc);
+ startDisplayJob(fPrevResult, page);
+ } else {
+ startLookupJob(dmc, page);
+ }
+ }});
+ }
+
+ private void executeFromJob(Runnable runnable) {
+ try {
+ fExecutor.execute(runnable);
+ } catch (RejectedExecutionException e) {
+ // Session disposed, ignore
+ }
+ }
+
+ private void startLookupJob(final IDMContext> dmc, final IWorkbenchPage page) {
+ // If there is a previous lookup job running, cancel it.
+ if (fRunningLookupJob != null) {
+ fRunningLookupJob.cancel();
+ }
+
+ fRunningLookupJob = new LookupJob(dmc, page);
+ fRunningLookupJob.schedule();
+ }
+
+ // To be called only on dispatch thread.
+ private void startDisplayJob(SourceLookupResult lookupResult, IWorkbenchPage page) {
+ DisplayJob nextDisplayJob = new DisplayJob(lookupResult, page);
+ if (fRunningDisplayJob != null) {
+ // There is a display job currently running. Cancel it, and set
+ // the next display job to be run.
+ if (false && fRunningDisplayJob.cancel()) {
+ fPendingDisplayJob = nextDisplayJob;
+ fRunningDisplayJob = null;
+ serviceDisplayAndClearingJobs();
+ } else {
+ // The job already started, so we need to wait until
+ // serviceDisplayAndClearingJobs() is called by the job itself.
+ fPendingDisplayJob = nextDisplayJob;
+ }
+ } else if (fRunningClearingJob != null) {
+ // Wait for the clearing job to finish, instead, set the
+ // display job as pending.
+ fPendingDisplayJob = nextDisplayJob;
+ } else {
+ fRunningDisplayJob = nextDisplayJob;
+ fRunningDisplayJob.schedule();
+ }
+ }
+
+
+ private void serviceDisplayAndClearingJobs() {
+ if (!fPendingExecDmcsToClear.isEmpty()) {
+ // There are annotations to be cleared, run the job first
+ fRunningClearingJob = new ClearingJob(fPendingExecDmcsToClear);
+ fRunningClearingJob.schedule();
+ fPendingExecDmcsToClear = new LinkedList();
+ } else if (fPendingDisplayJob != null) {
+ fRunningDisplayJob = fPendingDisplayJob;
+ fRunningDisplayJob.schedule();
+ fPendingDisplayJob = null;
+ }
+ }
+
+ private void startAnnotationClearingJob(IRunControl.IExecutionDMContext execDmc) {
+ // Make sure to add the dmc to the list.
+ fPendingExecDmcsToClear.add(execDmc);
+
+ // If lookup job is running, check it agains the exec context,
+ // and cancel it if matches.
+ if (fRunningLookupJob != null) {
+ if (DMContexts.isAncestorOf(fRunningLookupJob.getDmc(), execDmc)) {
+ fRunningLookupJob.cancel();
+ fRunningLookupJob = null;
+ }
+ }
+ // If there is a pending displahy job, make sure it doesn't get
+ // pre-empted by this event. If so, just cancel the pending
+ // display job.
+ if (fPendingDisplayJob != null) {
+ if (DMContexts.isAncestorOf(fPendingDisplayJob.getDmc(), execDmc)) {
+ fPendingDisplayJob = null;
+ }
+ }
+
+ // If no display or clearing jobs are running, schedule the clearing job.
+ if (fRunningClearingJob == null && fRunningDisplayJob == null) {
+ fRunningClearingJob = new ClearingJob(fPendingExecDmcsToClear);
+ fRunningClearingJob.schedule();
+ fPendingExecDmcsToClear = new LinkedList();
+ }
+ }
+
+ @DsfServiceEventHandler
+ public void eventDispatched(IRunControl.IResumedDMEvent e) {
+ if (e.getReason() != StateChangeReason.STEP) {
+ startAnnotationClearingJob(e.getDMContext());
+ }
+ }
+
+ @DsfServiceEventHandler
+ public void eventDispatched(IRunControl.IExitedDMEvent e) {
+ startAnnotationClearingJob(e.getExecutionContext());
+ }
+
+ @DsfServiceEventHandler
+ public void eventDispatched(IStepQueueManager.ISteppingTimedOutEvent e) {
+ startAnnotationClearingJob(e.getDMContext());
+ }
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/SourceLookupResult.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/SourceLookupResult.java
new file mode 100644
index 00000000000..fdf90a4eeab
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/SourceLookupResult.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.ui.sourcelookup;
+
+import org.eclipse.dd.dsf.datamodel.IDMContext;
+import org.eclipse.ui.IEditorInput;
+
+/**
+ * The result of a source lookup contains the source element, editor id, and
+ * editor input resolved for a debug artifact.
+ *
+ * @since 3.1
+ */
+class SourceLookupResult {
+
+ /**
+ * Element that source was resolved for.
+ */
+ private IDMContext> fDmc;
+ /**
+ * Corresponding source element, or null
+ * if unknown.
+ */
+ private Object fSourceElement;
+ /**
+ * Associated editor id, used to display the source element,
+ * or null if unknown.
+ */
+ private String fEditorId;
+ /**
+ * Associatd editor input, used to display the source element,
+ * or null if unknown.
+ */
+ private IEditorInput fEditorInput;
+
+ /**
+ * Creates a source lookup result on the given artifact, source element,
+ * editor id, and editor input.
+ */
+ public SourceLookupResult(IDMContext> dmc, Object sourceElement, String editorId, IEditorInput editorInput) {
+ fDmc = dmc;
+ setSourceElement(sourceElement);
+ setEditorId(editorId);
+ setEditorInput(editorInput);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.sourcelookup.ISourceLookupResult#getArtifact()
+ */
+ public IDMContext> getDmc() {
+ return fDmc;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.sourcelookup.ISourceLookupResult#getSourceElement()
+ */
+ public Object getSourceElement() {
+ return fSourceElement;
+ }
+
+ /**
+ * Sets the source element resolved for the artifact that source
+ * lookup was performed for, or null if a source element
+ * was not resolved.
+ *
+ * @param element resolved source element or null if unknown
+ */
+ protected void setSourceElement(Object element) {
+ fSourceElement = element;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.sourcelookup.ISourceLookupResult#getEditorId()
+ */
+ public String getEditorId() {
+ return fEditorId;
+ }
+
+ /**
+ * Sets the identifier of the editor used to display this source
+ * lookup result's source element, or null if unknown.
+ *
+ * @param id the identifier of the editor used to display this source
+ * lookup result's source element, or null if unknown
+ */
+ protected void setEditorId(String id) {
+ fEditorId = id;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.sourcelookup.ISourceLookupResult#getEditorInput()
+ */
+ public IEditorInput getEditorInput() {
+ return fEditorInput;
+ }
+
+ /**
+ * Sets the editor input used to display this source lookup
+ * result's source element, or null if unknown.
+ *
+ * @param input the editor input used to display this source lookup
+ * result's source element, or null if unknown
+ */
+ protected void setEditorInput(IEditorInput input) {
+ fEditorInput = input;
+ }
+
+ /**
+ * Updates the artifact to refer to the given artifact
+ * if equal. For example, when a source lookup result is resued
+ * for the same stack frame, we still need to update in case
+ * the stack frame is not identical.
+ *
+ * @param artifact new artifact state
+ */
+ public void updateArtifact(IDMContext> dmc) {
+ if (fDmc.equals(dmc)) {
+ fDmc = dmc;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF
index e803dac64a4..42715ebf451 100644
--- a/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.dd.dsf.debug/META-INF/MANIFEST.MF
@@ -11,6 +11,8 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.dd.dsf,
org.eclipse.cdt.core
Eclipse-LazyStart: true
-Export-Package: org.eclipse.dd.dsf.debug.service,
- org.eclipse.dd.dsf.debug.service.command
+Export-Package: org.eclipse.dd.dsf.debug.model,
+ org.eclipse.dd.dsf.debug.service,
+ org.eclipse.dd.dsf.debug.service.command,
+ org.eclipse.dd.dsf.debug.sourcelookup
Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java
new file mode 100644
index 00000000000..ffd9d525696
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/model/DsfMemoryBlockRetrieval.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Wind River Systems 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.model;
+
+import org.eclipse.dd.dsf.datamodel.IDMContext;
+import org.eclipse.dd.dsf.debug.DsfDebugPlugin;
+import org.eclipse.dd.dsf.debug.service.IMemory;
+import org.eclipse.dd.dsf.service.IDsfService;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IMemoryBlock;
+import org.eclipse.debug.core.model.IMemoryBlockRetrieval;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ *
+ */
+public class DsfMemoryBlockRetrieval implements IMemoryBlockRetrieval {
+
+ private final IDMContext> fContext;
+ private final ServiceTracker fServiceTracker;
+
+ public DsfMemoryBlockRetrieval(IDMContext> dmc) {
+ fContext = dmc;
+ String memoryServiceFilter =
+ "(&" +
+ "(OBJECTCLASS=" + IMemory.class.getName() + ")" +
+ "(" + IDsfService.PROP_SESSION_ID + "=" + dmc.getSessionId() + ")" +
+ ")";
+ fServiceTracker = new ServiceTracker(DsfDebugPlugin.getBundleContext(), memoryServiceFilter, null);
+ fServiceTracker.open();
+ }
+
+ public IMemoryBlock getMemoryBlock(long startAddress, long length) throws DebugException {
+ return null;
+ }
+
+ public boolean supportsStorageRetrieval() {
+ return false;
+ }
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java
new file mode 100644
index 00000000000..e890d519889
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/sourcelookup/DsfMISourceLookupParticipant.java
@@ -0,0 +1,228 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.sourcelookup;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
+import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
+import org.eclipse.dd.dsf.concurrent.DsfExecutor;
+import org.eclipse.dd.dsf.concurrent.Query;
+import org.eclipse.dd.dsf.concurrent.ThreadSafe;
+import org.eclipse.dd.dsf.datamodel.IDMContext;
+import org.eclipse.dd.dsf.debug.DsfDebugPlugin;
+import org.eclipse.dd.dsf.debug.service.IStack;
+import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
+import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMData;
+import org.eclipse.dd.dsf.service.DsfServicesTracker;
+import org.eclipse.dd.dsf.service.DsfSession;
+import org.eclipse.dd.dsf.service.IDsfService;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.sourcelookup.ISourceContainer;
+import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
+import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant;
+
+/**
+ */
+@ThreadSafe
+public class DsfMISourceLookupParticipant implements ISourceLookupParticipant {
+ protected static final Object[] EMPTY = new Object[0];
+
+ private DsfExecutor fExecutor;
+ private String fSessionId;
+ private DsfServicesTracker fServicesTracker;
+ private ISourceLookupDirector fDirector;
+ private Map> fLookupCache = Collections.synchronizedMap(new HashMap>());
+
+ public DsfMISourceLookupParticipant(DsfSession session) {
+ fSessionId = session.getId();
+ fExecutor = DsfSession.getSession(fSessionId).getExecutor();
+ fServicesTracker = new DsfServicesTracker(DsfDebugPlugin.getBundleContext(), fSessionId);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant#init(org.eclipse.debug.core.sourcelookup.ISourceLookupDirector)
+ */
+ public void init(ISourceLookupDirector director) {
+ fDirector = director;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant#dispose()
+ */
+ public void dispose() {
+ fServicesTracker.dispose();
+ fDirector = null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant#findSourceElements(java.lang.Object)
+ */
+ public Object[] findSourceElements(Object object) throws CoreException {
+ CoreException single = null;
+ MultiStatus multiStatus = null;
+ List