1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Moved generic packages out of the org.eclipse.dd.dsf.mi.* plugins and into the org.eclipse.dd.dsf.debug.* plugins as appropriate, in preparation for the memory view work (bug 160047).

This commit is contained in:
Pawel Piech 2007-06-08 20:37:43 +00:00
parent 434c29ab17
commit 51452d7e2c
16 changed files with 1801 additions and 3 deletions

View file

@ -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

View file

@ -7,4 +7,50 @@
delegateClass="org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionDelegate"/>
</extension>
<extension point="org.eclipse.ui.editors.annotationTypes">
<type
name="org.eclipse.dd.debug.currentIP">
</type>
<type
name="org.eclipse.dd.debug.secondaryIP">
</type>
</extension>
<extension point="org.eclipse.ui.editors.markerAnnotationSpecification">
<specification
annotationImageProvider="org.eclipse.dd.dsf.debug.ui.sourcelookup.InstructionPointerImageProvider"
annotationType="org.eclipse.dd.debug.currentIP"
colorPreferenceKey="currentIPColor"
colorPreferenceValue="198,219,174"
highlightPreferenceKey="currentIPHighlight"
highlightPreferenceValue="true"
label="%debugCurrentInstructionPointer"
overviewRulerPreferenceKey="currentIPOverviewRuler"
overviewRulerPreferenceValue="true"
presentationLayer="6"
textPreferenceKey="currentIPIndication"
textPreferenceValue="false"
verticalRulerPreferenceKey="currentIPVerticalRuler"
verticalRulerPreferenceValue="true">
</specification>
<specification
annotationImageProvider="org.eclipse.dd.dsf.debug.ui.sourcelookup.InstructionPointerImageProvider"
annotationType="org.eclipse.dd.debug.secondaryIP"
colorPreferenceKey="secondaryIPColor"
colorPreferenceValue="219,235,204"
highlightPreferenceKey="secondaryIPHighlight"
highlightPreferenceValue="true"
label="%debugCallStack"
overviewRulerPreferenceKey="secondaryIPOverviewRuler"
overviewRulerPreferenceValue="true"
presentationLayer="6"
textPreferenceKey="secondaryIPIndication"
textPreferenceValue="false"
verticalRulerPreferenceKey="secondaryIPVerticalRuler"
verticalRulerPreferenceValue="true">
</specification>
</extension>
</plugin>

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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<Boolean>(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;
}
}

View file

@ -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;
}
}

View file

@ -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<AnnotationWrapper> fAnnotationWrappers;
/**
* Clients must not instantiate this class.
*/
public InstructionPointerManager() {
fAnnotationWrappers = Collections.synchronizedList(new LinkedList<AnnotationWrapper>());
}
/**
* 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<AnnotationWrapper> 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);
}
}
}
}

View file

@ -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.
* <p>
* The implementation relies on three types of jobs to perform the operations.<br>
* - The first kind, "lookup job" performs the source lookup operation. <br>
* - The second "display job" positions and annotates the editor. <br>
* - The third clears the old IP annotations when a thread or process has resumed
* or exited.
* <p>
* 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 <code>null</code> 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 <code>null</code> 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<FramePositioningData> query = new Query<FramePositioningData>(fExecutor) {
@Override
protected void execute(final DataRequestMonitor<FramePositioningData> 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<IFrameDMData>(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<IRunControl.IExecutionDMContext> fDmcsToClear;
public ClearingJob(List<IRunControl.IExecutionDMContext> 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<IRunControl.IExecutionDMContext> fPendingExecDmcsToClear = new LinkedList<IRunControl.IExecutionDMContext>();
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<IRunControl.IExecutionDMContext>();
} 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<IRunControl.IExecutionDMContext>();
}
}
@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());
}
}

View file

@ -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 <code>null</code>
* if unknown.
*/
private Object fSourceElement;
/**
* Associated editor id, used to display the source element,
* or <code>null</code> if unknown.
*/
private String fEditorId;
/**
* Associatd editor input, used to display the source element,
* or <code>null</code> 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 <code>null</code> if a source element
* was not resolved.
*
* @param element resolved source element or <code>null</code> 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 <code>null</code> if unknown.
*
* @param id the identifier of the editor used to display this source
* lookup result's source element, or <code>null</code> 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 <code>null</code> if unknown.
*
* @param input the editor input used to display this source lookup
* result's source element, or <code>null</code> 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;
}
}
}

View file

@ -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

View file

@ -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;
}
}

View file

@ -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<String, List<Object>> fLookupCache = Collections.synchronizedMap(new HashMap<String, List<Object>>());
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<Object> results = null;
String name = getSourceName(object);
if (name != null) {
results = fLookupCache.get(name);
if (results != null) {
return results.toArray();
} else {
results = new ArrayList<Object>();
}
ISourceContainer[] containers = getSourceContainers();
for (int i = 0; i < containers.length; i++) {
try {
ISourceContainer container = containers[i];
if (container != null) {
Object[] objects = container.findSourceElements(name);
if (objects.length > 0) {
if (isFindDuplicates()) {
results.addAll(Arrays.asList(objects));
} else {
results.add(objects[0]);
break;
}
}
}
} catch (CoreException e) {
if (single == null) {
single = e;
} else if (multiStatus == null) {
multiStatus = new MultiStatus(DebugPlugin.getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, new IStatus[]{single.getStatus()}, "Source Lookup error", null); //$NON-NLS-1$
multiStatus.add(e.getStatus());
} else {
multiStatus.add(e.getStatus());
}
}
}
if (!results.isEmpty()) {
synchronized(fLookupCache) {
if (!fLookupCache.containsKey(name)) {
fLookupCache.put(name, results);
}
}
}
}
if (results == null || results.isEmpty()) {
if (multiStatus != null) {
throw new CoreException(multiStatus);
} else if (single != null) {
throw single;
}
return EMPTY;
}
return results.toArray();
}
/**
* Returns whether this participant's source lookup director is configured
* to search for duplicate source elements.
*
* @return whether this participant's source lookup director is configured
* to search for duplicate source elements
*/
protected boolean isFindDuplicates() {
ISourceLookupDirector director = fDirector;
if (director != null) {
return director.isFindDuplicates();
}
return false;
}
/**
* Returns the source containers currently registered with this participant's
* source lookup director.
*
* @return the source containers currently registered with this participant's
* source lookup director
*/
protected ISourceContainer[] getSourceContainers() {
ISourceLookupDirector director = fDirector;
if (director != null) {
return director.getSourceContainers();
}
return new ISourceContainer[0];
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant#sourceContainersChanged(org.eclipse.debug.core.sourcelookup.ISourceLookupDirector)
*/
public void sourceContainersChanged(ISourceLookupDirector director) {
fLookupCache.clear();
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.core.sourcelookup.ISourceLookupParticipant#getSourceName(java.lang.Object)
*/
public String getSourceName(Object object) throws CoreException {
if ( !(object instanceof IDMContext<?>) ||
!((IDMContext<?>)object).getSessionId().equals(fSessionId) )
{
throw new CoreException(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, -1, "Invalid object", null)); //$NON-NLS-1$
}
final IDMContext<?> dmc = (IDMContext<?>)object;
Query<String> query = new Query<String>(fExecutor) {
@Override
protected void execute(final DataRequestMonitor<String> rm) {
getSourceNameOnDispatchThread(dmc, rm);
}};
fExecutor.execute(query);
try {
return query.get();
} catch (InterruptedException e) { assert false : "Interrupted exception in DSF executor"; //$NON-NLS-1$
} catch (ExecutionException e) {
if (e.getCause() instanceof CoreException) {
throw (CoreException)e.getCause();
}
assert false : "Unexptected exception"; //$NON-NLS-1$
}
return null; // Should never get here.
}
@ConfinedToDsfExecutor("fExecutor")
private void getSourceNameOnDispatchThread(IDMContext<?> dmc, final DataRequestMonitor<String> rm) {
if (!(dmc instanceof IStack.IFrameDMContext)) {
rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "No source for this object", null)); //$NON-NLS-1$
rm.done();
return;
}
IFrameDMContext frameDmc = (IFrameDMContext)dmc;
IStack stackService = fServicesTracker.getService(IStack.class);
if (stackService == null) {
rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Stack data not available", null)); //$NON-NLS-1$
rm.done();
return;
}
stackService.getModelData(
frameDmc,
new DataRequestMonitor<IFrameDMData>(fExecutor, rm) { @Override
public void handleOK() {
rm.setData(getData().getFile());
rm.done();
}});
}
}