diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/META-INF/MANIFEST.MF b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/META-INF/MANIFEST.MF index 6165783264e..a4894fcb84a 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/META-INF/MANIFEST.MF +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/META-INF/MANIFEST.MF @@ -17,7 +17,8 @@ Require-Bundle: org.eclipse.ui, org.eclipse.cdt.core, org.eclipse.cdt.ui, org.eclipse.ui.ide, - org.eclipse.core.variables + org.eclipse.core.variables, + org.eclipse.core.expressions Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: J2SE-1.5 Export-Package: org.eclipse.cdt.dsf.gdb.internal.ui.actions;x-internal:=true, diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/icons/full/obj16/reverseresume.gif b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/icons/full/obj16/reverseresume.gif new file mode 100644 index 00000000000..a22c49d3857 Binary files /dev/null and b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/icons/full/obj16/reverseresume.gif differ diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/icons/full/obj16/reversestepinto.gif b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/icons/full/obj16/reversestepinto.gif new file mode 100755 index 00000000000..bda91578236 Binary files /dev/null and b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/icons/full/obj16/reversestepinto.gif differ diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/icons/full/obj16/reversestepover.gif b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/icons/full/obj16/reversestepover.gif new file mode 100755 index 00000000000..95ea1f0496c Binary files /dev/null and b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/icons/full/obj16/reversestepover.gif differ diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/icons/full/obj16/reversetoggle.gif b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/icons/full/obj16/reversetoggle.gif new file mode 100644 index 00000000000..409eb0dbaac Binary files /dev/null and b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/icons/full/obj16/reversetoggle.gif differ diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/icons/full/obj16/uncall.gif b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/icons/full/obj16/uncall.gif new file mode 100755 index 00000000000..8e7a780a358 Binary files /dev/null and b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/icons/full/obj16/uncall.gif differ diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.properties b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.properties index affa7716080..e9377520097 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.properties +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.properties @@ -13,3 +13,25 @@ providerName=Eclipse.org action.connect.label = Connect... action.connect.tooltip = Connect to a process + +actionSet.reverse.label = Reverse Debugging +actionSet.reverse.description = Reverse Debugging + +command.reverseCategory.name = Reverse Debugging Commands +command.reverseCategory.description = Set of commands for Reverse Debugging + +command.reverseToggle.name = Reverse Toggle +command.reverseToggle.description = Toggle Reverse Debugging +command.reverseToggle.label = Toggle Reverse Debugging +command.reverseResume.name = Reverse Resume +command.reverseResume.description = Perform Reverse Resume +command.reverseResume.label = Reverse Resume +command.reverseStepInto.name = Reverse StepInto +command.reverseStepInto.description = Perform Reverse StepInto +command.reverseStepInto.label = Reverse StepInto +command.reverseStepOver.name = Reverse StepOver +command.reverseStepOver.description = Perform Reverse StepOver +command.reverseStepOver.label = Reverse StepOver +command.uncall.name = Uncall +command.uncall.description = Perform Uncall +command.uncall.label = Uncall diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml index 2b4ad5f4e77..a70a4fa327d 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml @@ -142,5 +142,373 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbAdapterFactory.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbAdapterFactory.java index 6dd3e7cb61c..d0eca3c6b6e 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbAdapterFactory.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbAdapterFactory.java @@ -32,10 +32,20 @@ import org.eclipse.cdt.dsf.debug.ui.viewmodel.actions.DefaultRefreshAllTarget; import org.eclipse.cdt.dsf.debug.ui.viewmodel.actions.IRefreshAllTarget; import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.DefaultDsfModelSelectionPolicyFactory; import org.eclipse.cdt.dsf.gdb.actions.IConnect; +import org.eclipse.cdt.dsf.gdb.actions.IReverseResumeHandler; +import org.eclipse.cdt.dsf.gdb.actions.IReverseStepIntoHandler; +import org.eclipse.cdt.dsf.gdb.actions.IReverseStepOverHandler; +import org.eclipse.cdt.dsf.gdb.actions.IReverseToggleHandler; +import org.eclipse.cdt.dsf.gdb.actions.IUncallHandler; import org.eclipse.cdt.dsf.gdb.internal.ui.actions.DsfTerminateCommand; import org.eclipse.cdt.dsf.gdb.internal.ui.actions.GdbConnectCommand; import org.eclipse.cdt.dsf.gdb.internal.ui.actions.GdbDisconnectCommand; import org.eclipse.cdt.dsf.gdb.internal.ui.actions.GdbRestartCommand; +import org.eclipse.cdt.dsf.gdb.internal.ui.actions.GdbReverseResumeCommand; +import org.eclipse.cdt.dsf.gdb.internal.ui.actions.GdbReverseStepIntoCommand; +import org.eclipse.cdt.dsf.gdb.internal.ui.actions.GdbReverseStepOverCommand; +import org.eclipse.cdt.dsf.gdb.internal.ui.actions.GdbReverseToggleCommand; +import org.eclipse.cdt.dsf.gdb.internal.ui.actions.GdbUncallCommand; import org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.GdbViewModelAdapter; import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch; import org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate; @@ -77,10 +87,14 @@ public class GdbAdapterFactory final GdbViewModelAdapter fViewModelAdapter; final DsfSourceDisplayAdapter fSourceDisplayAdapter; final DsfStepIntoCommand fStepIntoCommand; + final GdbReverseStepIntoCommand fReverseStepIntoCommand; final DsfStepOverCommand fStepOverCommand; + final GdbReverseStepOverCommand fReverseStepOverCommand; final DsfStepReturnCommand fStepReturnCommand; + final GdbUncallCommand fUncallCommand; final DsfSuspendCommand fSuspendCommand; final DsfResumeCommand fResumeCommand; + final GdbReverseResumeCommand fReverseResumeCommand; final GdbRestartCommand fRestartCommand; final DsfTerminateCommand fTerminateCommand; final GdbConnectCommand fConnectCommand; @@ -91,6 +105,7 @@ public class GdbAdapterFactory final IModelSelectionPolicyFactory fModelSelectionPolicyFactory; final SteppingController fSteppingController; final DefaultRefreshAllTarget fRefreshAllTarget; + final GdbReverseToggleCommand fReverseToggleTarget; SessionAdapterSet(GdbLaunch launch) { fLaunch = launch; @@ -111,10 +126,14 @@ public class GdbAdapterFactory fSteppingModeTarget= new DsfSteppingModeTarget(); fStepIntoCommand = new DsfStepIntoCommand(session, fSteppingModeTarget); + fReverseStepIntoCommand = new GdbReverseStepIntoCommand(session, fSteppingModeTarget); fStepOverCommand = new DsfStepOverCommand(session, fSteppingModeTarget); + fReverseStepOverCommand = new GdbReverseStepOverCommand(session, fSteppingModeTarget); fStepReturnCommand = new DsfStepReturnCommand(session); + fUncallCommand = new GdbUncallCommand(session, fSteppingModeTarget); fSuspendCommand = new DsfSuspendCommand(session); fResumeCommand = new DsfResumeCommand(session); + fReverseResumeCommand = new GdbReverseResumeCommand(session); fRestartCommand = new GdbRestartCommand(session, fLaunch); fTerminateCommand = new DsfTerminateCommand(session); fConnectCommand = new GdbConnectCommand(session); @@ -122,19 +141,25 @@ public class GdbAdapterFactory fSuspendTrigger = new DsfSuspendTrigger(session, fLaunch); fModelSelectionPolicyFactory = new DefaultDsfModelSelectionPolicyFactory(); fRefreshAllTarget = new DefaultRefreshAllTarget(); + fReverseToggleTarget = new GdbReverseToggleCommand(session); session.registerModelAdapter(ISteppingModeTarget.class, fSteppingModeTarget); session.registerModelAdapter(IStepIntoHandler.class, fStepIntoCommand); + session.registerModelAdapter(IReverseStepIntoHandler.class, fReverseStepIntoCommand); session.registerModelAdapter(IStepOverHandler.class, fStepOverCommand); + session.registerModelAdapter(IReverseStepOverHandler.class, fReverseStepOverCommand); session.registerModelAdapter(IStepReturnHandler.class, fStepReturnCommand); + session.registerModelAdapter(IUncallHandler.class, fUncallCommand); session.registerModelAdapter(ISuspendHandler.class, fSuspendCommand); session.registerModelAdapter(IResumeHandler.class, fResumeCommand); + session.registerModelAdapter(IReverseResumeHandler.class, fReverseResumeCommand); session.registerModelAdapter(IRestart.class, fRestartCommand); session.registerModelAdapter(ITerminateHandler.class, fTerminateCommand); session.registerModelAdapter(IConnect.class, fConnectCommand); session.registerModelAdapter(IDisconnectHandler.class, fDisconnectCommand); session.registerModelAdapter(IModelSelectionPolicyFactory.class, fModelSelectionPolicyFactory); session.registerModelAdapter(IRefreshAllTarget.class, fRefreshAllTarget); + session.registerModelAdapter(IReverseToggleHandler.class, fReverseToggleTarget); fDebugModelProvider = new IDebugModelProvider() { // @see org.eclipse.debug.core.model.IDebugModelProvider#getModelIdentifiers() @@ -165,27 +190,37 @@ public class GdbAdapterFactory session.unregisterModelAdapter(ISteppingModeTarget.class); session.unregisterModelAdapter(IStepIntoHandler.class); + session.unregisterModelAdapter(IReverseStepIntoHandler.class); session.unregisterModelAdapter(IStepOverHandler.class); + session.unregisterModelAdapter(IReverseStepOverHandler.class); session.unregisterModelAdapter(IStepReturnHandler.class); + session.unregisterModelAdapter(IUncallHandler.class); session.unregisterModelAdapter(ISuspendHandler.class); session.unregisterModelAdapter(IResumeHandler.class); + session.unregisterModelAdapter(IReverseResumeHandler.class); session.unregisterModelAdapter(IRestart.class); session.unregisterModelAdapter(ITerminateHandler.class); session.unregisterModelAdapter(IConnect.class); session.unregisterModelAdapter(IDisconnectHandler.class); session.unregisterModelAdapter(IModelSelectionPolicyFactory.class); session.unregisterModelAdapter(IRefreshAllTarget.class); + session.unregisterModelAdapter(IReverseToggleHandler.class); fStepIntoCommand.dispose(); + fReverseStepIntoCommand.dispose(); fStepOverCommand.dispose(); + fReverseStepOverCommand.dispose(); fStepReturnCommand.dispose(); + fUncallCommand.dispose(); fSuspendCommand.dispose(); fResumeCommand.dispose(); + fReverseResumeCommand.dispose(); fRestartCommand.dispose(); fTerminateCommand.dispose(); fConnectCommand.dispose(); fDisconnectCommand.dispose(); fSuspendTrigger.dispose(); + fReverseToggleTarget.dispose(); } } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbAbstractReverseStepCommand.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbAbstractReverseStepCommand.java new file mode 100644 index 00000000000..e2953da330a --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbAbstractReverseStepCommand.java @@ -0,0 +1,134 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.ui.actions; + + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.DsfExecutor; +import org.eclipse.cdt.dsf.concurrent.Immutable; +import org.eclipse.cdt.dsf.concurrent.Query; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.cdt.dsf.debug.service.IRunControl.StepType; +import org.eclipse.cdt.dsf.debug.ui.actions.DsfSteppingModeTarget; +import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin; +import org.eclipse.cdt.dsf.gdb.service.IReverseRunControl; +import org.eclipse.cdt.dsf.service.DsfServicesTracker; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; + +@Immutable +public abstract class GdbAbstractReverseStepCommand { + + private final DsfExecutor fExecutor; + private final DsfServicesTracker fTracker; + private final DsfSteppingModeTarget fSteppingMode; + + protected DsfSteppingModeTarget getSteppingMode() { return fSteppingMode; } + + public GdbAbstractReverseStepCommand(DsfSession session, DsfSteppingModeTarget steppingMode) { + fExecutor = session.getExecutor(); + fTracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), session.getId()); + fSteppingMode = steppingMode; + } + + public void dispose() { + fTracker.dispose(); + } + + protected boolean canReverseStep(ISelection debugContext) { + final IExecutionDMContext dmc = getContext(debugContext); + + if (dmc == null) { + return false; + } + + final StepType stepType = getStepType(); + Query canReverseQuery = new Query() { + @Override + public void execute(DataRequestMonitor rm) { + IReverseRunControl runControl = fTracker.getService(IReverseRunControl.class); + + if (runControl != null) { + runControl.canReverseStep(dmc, stepType, rm); + } else { + rm.setData(false); + rm.done(); + } + } + }; + try { + fExecutor.execute(canReverseQuery); + return canReverseQuery.get(); + } catch (InterruptedException e) { + } catch (ExecutionException e) { + } catch (RejectedExecutionException e) { + // Can be thrown if the session is shutdown + } + + return false; + } + + protected void reverseStep(ISelection debugContext) { + final IExecutionDMContext dmc = getContext(debugContext); + + if (dmc == null) { + return; + } + + final StepType stepType = getStepType(); + Query reverseStepQuery = new Query() { + @Override + public void execute(DataRequestMonitor rm) { + IReverseRunControl runControl = fTracker.getService(IReverseRunControl.class); + + if (runControl != null) { + runControl.reverseStep(dmc, stepType, rm); + } else { + rm.setData(false); + rm.done(); + } + } + }; + try { + fExecutor.execute(reverseStepQuery); + reverseStepQuery.get(); + } catch (InterruptedException e) { + } catch (ExecutionException e) { + } catch (RejectedExecutionException e) { + // Can be thrown if the session is shutdown + } + } + + private IExecutionDMContext getContext(ISelection debugContext) { + if (debugContext instanceof IStructuredSelection) { + IStructuredSelection ss = (IStructuredSelection) debugContext; + if (!ss.isEmpty()) { + Object object = ss.getFirstElement(); + if (object instanceof IDMVMContext) { + return DMContexts.getAncestorOfType(((IDMVMContext)object).getDMContext(), IExecutionDMContext.class); + } + } + } + + return null; + } + + /** + * @return the currently active step type + */ + abstract StepType getStepType(); +} \ No newline at end of file diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbReverseResumeCommand.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbReverseResumeCommand.java new file mode 100644 index 00000000000..f54e808f9f7 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbReverseResumeCommand.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.ui.actions; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.DsfExecutor; +import org.eclipse.cdt.dsf.concurrent.Immutable; +import org.eclipse.cdt.dsf.concurrent.Query; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.cdt.dsf.gdb.actions.IReverseResumeHandler; +import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin; +import org.eclipse.cdt.dsf.gdb.service.IReverseRunControl; +import org.eclipse.cdt.dsf.service.DsfServicesTracker; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; + +@Immutable +public class GdbReverseResumeCommand implements IReverseResumeHandler { + + private final DsfExecutor fExecutor; + private final DsfServicesTracker fTracker; + + public GdbReverseResumeCommand(DsfSession session) { + fExecutor = session.getExecutor(); + fTracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), session.getId()); + } + + public void dispose() { + fTracker.dispose(); + } + + public boolean canReverseResume(ISelection debugContext) { + final IExecutionDMContext dmc = getContext(debugContext); + + if (dmc == null) { + return false; + } + + Query canReverseResume = new Query() { + @Override + public void execute(DataRequestMonitor rm) { + IReverseRunControl runControl = fTracker.getService(IReverseRunControl.class); + + if (runControl != null) { + runControl.canReverseResume(dmc, rm); + } else { + rm.setData(false); + rm.done(); + } + } + }; + try { + fExecutor.execute(canReverseResume); + return canReverseResume.get(); + } catch (InterruptedException e) { + } catch (ExecutionException e) { + } catch (RejectedExecutionException e) { + // Can be thrown if the session is shutdown + } + + return false; + } + + public void reverseResume(ISelection debugContext) { + final IExecutionDMContext dmc = getContext(debugContext); + + if (dmc == null) { + return; + } + + Query reverseResume = new Query() { + @Override + public void execute(DataRequestMonitor rm) { + IReverseRunControl runControl = fTracker.getService(IReverseRunControl.class); + + if (runControl != null) { + runControl.reverseResume(dmc, rm); + } else { + rm.setData(false); + rm.done(); + } + } + }; + try { + fExecutor.execute(reverseResume); + reverseResume.get(); + } catch (InterruptedException e) { + } catch (ExecutionException e) { + } catch (RejectedExecutionException e) { + // Can be thrown if the session is shutdown + } + } + + private IExecutionDMContext getContext(ISelection debugContext) { + if (debugContext instanceof IStructuredSelection) { + IStructuredSelection ss = (IStructuredSelection) debugContext; + if (!ss.isEmpty()) { + Object object = ss.getFirstElement(); + if (object instanceof IDMVMContext) { + return DMContexts.getAncestorOfType(((IDMVMContext)object).getDMContext(), IExecutionDMContext.class); + } + } + } + + return null; + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbReverseStepIntoCommand.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbReverseStepIntoCommand.java new file mode 100644 index 00000000000..80b7f929a09 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbReverseStepIntoCommand.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.ui.actions; + +import org.eclipse.cdt.dsf.concurrent.Immutable; +import org.eclipse.cdt.dsf.debug.service.IRunControl.StepType; +import org.eclipse.cdt.dsf.debug.ui.actions.DsfSteppingModeTarget; +import org.eclipse.cdt.dsf.gdb.actions.IReverseStepIntoHandler; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.jface.viewers.ISelection; + +@Immutable +public class GdbReverseStepIntoCommand extends GdbAbstractReverseStepCommand implements IReverseStepIntoHandler { + + public GdbReverseStepIntoCommand(DsfSession session, DsfSteppingModeTarget steppingMode) { + super(session, steppingMode); + } + + public boolean canReverseStepInto(ISelection debugContext) { + return canReverseStep(debugContext); + } + + public void reverseStepInto(ISelection debugContext) { + reverseStep(debugContext); + } + + /** + * @return the currently active step type + */ + @Override + protected final StepType getStepType() { + boolean instructionSteppingEnabled = getSteppingMode() != null && getSteppingMode().isInstructionSteppingEnabled(); + return instructionSteppingEnabled ? StepType.INSTRUCTION_STEP_INTO : StepType.STEP_INTO; + } +} + diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbReverseStepOverCommand.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbReverseStepOverCommand.java new file mode 100644 index 00000000000..b57f443c22e --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbReverseStepOverCommand.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.ui.actions; + +import org.eclipse.cdt.dsf.concurrent.Immutable; +import org.eclipse.cdt.dsf.debug.service.IRunControl.StepType; +import org.eclipse.cdt.dsf.debug.ui.actions.DsfSteppingModeTarget; +import org.eclipse.cdt.dsf.gdb.actions.IReverseStepOverHandler; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.jface.viewers.ISelection; + +@Immutable +public class GdbReverseStepOverCommand extends GdbAbstractReverseStepCommand implements IReverseStepOverHandler { + + public GdbReverseStepOverCommand(DsfSession session, DsfSteppingModeTarget steppingMode) { + super(session, steppingMode); + } + + public boolean canReverseStepOver(ISelection debugContext) { + return canReverseStep(debugContext); + } + + public void reverseStepOver(ISelection debugContext) { + reverseStep(debugContext); + } + + /** + * @return the currently active step type + */ + @Override + protected final StepType getStepType() { + boolean instructionSteppingEnabled = getSteppingMode() != null && getSteppingMode().isInstructionSteppingEnabled(); + return instructionSteppingEnabled ? StepType.INSTRUCTION_STEP_OVER : StepType.STEP_OVER; + } +} + diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbReverseToggleCommand.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbReverseToggleCommand.java new file mode 100644 index 00000000000..d6096d67d0c --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbReverseToggleCommand.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.ui.actions; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.DsfExecutor; +import org.eclipse.cdt.dsf.concurrent.Immutable; +import org.eclipse.cdt.dsf.concurrent.Query; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; +import org.eclipse.cdt.dsf.gdb.actions.IReverseToggleHandler; +import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin; +import org.eclipse.cdt.dsf.gdb.service.IReverseRunControl; +import org.eclipse.cdt.dsf.service.DsfServicesTracker; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; + +@Immutable +public class GdbReverseToggleCommand implements IReverseToggleHandler { + + private final DsfExecutor fExecutor; + private final DsfServicesTracker fTracker; + + public GdbReverseToggleCommand(DsfSession session) { + fExecutor = session.getExecutor(); + fTracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), session.getId()); + } + + public void dispose() { + fTracker.dispose(); + } + + public boolean canToggleReverse(ISelection debugContext) { + final ICommandControlDMContext dmc = getContext(debugContext); + + if (dmc == null) { + return false; + } + + Query canSetReverseMode = new Query() { + @Override + public void execute(DataRequestMonitor rm) { + IReverseRunControl runControl = fTracker.getService(IReverseRunControl.class); + + if (runControl != null) { + runControl.canEnableReverseMode(dmc, rm); + } else { + rm.setData(false); + rm.done(); + } + } + }; + try { + fExecutor.execute(canSetReverseMode); + return canSetReverseMode.get(); + } catch (InterruptedException e) { + } catch (ExecutionException e) { + } catch (RejectedExecutionException e) { + // Can be thrown if the session is shutdown + } + + return false; + } + + public void toggleReverse(ISelection debugContext) { + final ICommandControlDMContext dmc = getContext(debugContext); + + if (dmc == null) { + return; + } + + Query setReverseMode = new Query() { + @Override + public void execute(final DataRequestMonitor rm) { + final IReverseRunControl runControl = fTracker.getService(IReverseRunControl.class); + + if (runControl != null) { + runControl.isReverseModeEnabled(dmc, + new DataRequestMonitor(fExecutor, rm) { + @Override + public void handleSuccess() { + runControl.enableReverseMode(dmc, !getData(), rm); + } + }); + } else { + rm.setData(false); + rm.done(); + } + } + }; + try { + fExecutor.execute(setReverseMode); + setReverseMode.get(); + } catch (InterruptedException e) { + } catch (ExecutionException e) { + } catch (RejectedExecutionException e) { + // Can be thrown if the session is shutdown + } + } + + private ICommandControlDMContext getContext(ISelection debugContext) { + if (debugContext instanceof IStructuredSelection) { + IStructuredSelection ss = (IStructuredSelection) debugContext; + if (!ss.isEmpty()) { + Object object = ss.getFirstElement(); + if (object instanceof IDMVMContext) { + return DMContexts.getAncestorOfType(((IDMVMContext)object).getDMContext(), ICommandControlDMContext.class); + } + } + } + + return null; + } + + public boolean isReverseToggled(ISelection debugContext) { + final ICommandControlDMContext dmc = getContext(debugContext); + return isReverseToggled(dmc); + } + + public boolean isReverseToggled(final ICommandControlDMContext dmc) { + + if (dmc == null) { + return false; + } + + Query isToggledQuery = new Query() { + @Override + public void execute(final DataRequestMonitor rm) { + final IReverseRunControl runControl = fTracker.getService(IReverseRunControl.class); + + if (runControl != null) { + runControl.isReverseModeEnabled(dmc, rm); + } else { + rm.setData(false); + rm.done(); + } + } + }; + try { + fExecutor.execute(isToggledQuery); + return isToggledQuery.get(); + } catch (InterruptedException e) { + } catch (ExecutionException e) { + } catch (RejectedExecutionException e) { + // Can be thrown if the session is shutdown + } + + return false; + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbUncallCommand.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbUncallCommand.java new file mode 100644 index 00000000000..bba52f4ace7 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbUncallCommand.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.ui.actions; + +import org.eclipse.cdt.dsf.concurrent.Immutable; +import org.eclipse.cdt.dsf.debug.service.IRunControl.StepType; +import org.eclipse.cdt.dsf.debug.ui.actions.DsfSteppingModeTarget; +import org.eclipse.cdt.dsf.gdb.actions.IUncallHandler; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.jface.viewers.ISelection; + +@Immutable +public class GdbUncallCommand extends GdbAbstractReverseStepCommand implements IUncallHandler { + + public GdbUncallCommand(DsfSession session, DsfSteppingModeTarget steppingMode) { + super(session, steppingMode); + } + + public boolean canUncall(ISelection debugContext) { + return canReverseStep(debugContext); + } + + public void uncall(ISelection debugContext) { + reverseStep(debugContext); + } + + /** + * @return the currently active step type + */ + @Override + protected final StepType getStepType() { + boolean instructionSteppingEnabled = getSteppingMode() != null && getSteppingMode().isInstructionSteppingEnabled(); + return instructionSteppingEnabled ? StepType.INSTRUCTION_STEP_RETUTRN : StepType.STEP_RETURN; + } +} + diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/ReverseResumeCommandHandler.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/ReverseResumeCommandHandler.java new file mode 100644 index 00000000000..3f7c2a34553 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/ReverseResumeCommandHandler.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.ui.actions; + +import org.eclipse.cdt.dsf.gdb.actions.IReverseResumeHandler; +import org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.commands.RetargetDebugContextCommand; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; + +/** + * Command handler to trigger a reverse resume operation + */ +public class ReverseResumeCommandHandler extends RetargetDebugContextCommand { + + @Override + protected boolean canPerformCommand(Object target, ISelection debugContext) { + return ((IReverseResumeHandler)target).canReverseResume(debugContext); + } + + @Override + protected Class getAdapterClass() { + return IReverseResumeHandler.class; + } + + @Override + protected void performCommand(Object target, ISelection debugContext) throws ExecutionException { + ((IReverseResumeHandler)target).reverseResume(debugContext); + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/ReverseStepIntoCommandHandler.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/ReverseStepIntoCommandHandler.java new file mode 100644 index 00000000000..812092bfcb5 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/ReverseStepIntoCommandHandler.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.ui.actions; + +import org.eclipse.cdt.dsf.gdb.actions.IReverseStepIntoHandler; +import org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.commands.RetargetDebugContextCommand; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; + +/** + * Command handler to trigger a reverse stepinto operation + */ +public class ReverseStepIntoCommandHandler extends RetargetDebugContextCommand { + + @Override + protected boolean canPerformCommand(Object target, ISelection debugContext) { + return ((IReverseStepIntoHandler)target).canReverseStepInto(debugContext); + } + + @Override + protected Class getAdapterClass() { + return IReverseStepIntoHandler.class; + } + + @Override + protected void performCommand(Object target, ISelection debugContext) throws ExecutionException { + ((IReverseStepIntoHandler)target).reverseStepInto(debugContext); + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/ReverseStepOverCommandHandler.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/ReverseStepOverCommandHandler.java new file mode 100644 index 00000000000..1f81bb6d14e --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/ReverseStepOverCommandHandler.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.ui.actions; + +import org.eclipse.cdt.dsf.gdb.actions.IReverseStepOverHandler; +import org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.commands.RetargetDebugContextCommand; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; + +/** + * Command handler to trigger a reverse stepover operation + */ +public class ReverseStepOverCommandHandler extends RetargetDebugContextCommand { + + @Override + protected boolean canPerformCommand(Object target, ISelection debugContext) { + return ((IReverseStepOverHandler)target).canReverseStepOver(debugContext); + } + + @Override + protected Class getAdapterClass() { + return IReverseStepOverHandler.class; + } + + @Override + protected void performCommand(Object target, ISelection debugContext) throws ExecutionException { + ((IReverseStepOverHandler)target).reverseStepOver(debugContext); + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/ReverseToggleCommandHandler.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/ReverseToggleCommandHandler.java new file mode 100644 index 00000000000..48829b7287e --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/ReverseToggleCommandHandler.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.ui.actions; + +import org.eclipse.cdt.dsf.gdb.actions.IReverseToggleHandler; +import org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.commands.RetargetDebugContextCommand; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.debug.ui.contexts.DebugContextEvent; +import org.eclipse.jface.viewers.ISelection; + +/** + * Command handler to toggle reverse debugging mode + */ +public class ReverseToggleCommandHandler extends RetargetDebugContextCommand { + + @Override + protected boolean canPerformCommand(Object target, ISelection debugContext) { + return ((IReverseToggleHandler)target).canToggleReverse(debugContext); + } + + @Override + protected Class getAdapterClass() { + return IReverseToggleHandler.class; + } + + @Override + protected void performCommand(Object target, ISelection debugContext) throws ExecutionException { + ((IReverseToggleHandler)target).toggleReverse(debugContext); + } + + @Override + public void debugContextChanged(DebugContextEvent event) { + super.debugContextChanged(event); + + // Make sure the toggle state reflects the actual state + // We must check this, in case we have multiple launches + // or if we re-launch + if (fTargetAdapter != null && fToolItem != null) { + boolean toggled = ((IReverseToggleHandler)fTargetAdapter).isReverseToggled(event.getContext()); + fToolItem.setSelection(toggled); + } + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/UncallCommandHandler.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/UncallCommandHandler.java new file mode 100644 index 00000000000..9f4d156e9d6 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/UncallCommandHandler.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.ui.actions; + +import org.eclipse.cdt.dsf.gdb.actions.IUncallHandler; +import org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.commands.RetargetDebugContextCommand; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; + +/** + * Command handler to trigger an uncall operation + */ +public class UncallCommandHandler extends RetargetDebugContextCommand { + + @Override + protected boolean canPerformCommand(Object target, ISelection debugContext) { + return ((IUncallHandler)target).canUncall(debugContext); + } + + @Override + protected Class getAdapterClass() { + return IUncallHandler.class; + } + + @Override + protected void performCommand(Object target, ISelection debugContext) throws ExecutionException { + ((IUncallHandler)target).uncall(debugContext); + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/commands/RetargetDebugContextCommand.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/commands/RetargetDebugContextCommand.java new file mode 100644 index 00000000000..77caa3f493a --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/commands/RetargetDebugContextCommand.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - initial implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.commands; + +import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.actions.MessagesForVMActions; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IAdapterManager; +import org.eclipse.core.runtime.Platform; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.contexts.DebugContextEvent; +import org.eclipse.debug.ui.contexts.IDebugContextListener; +import org.eclipse.debug.ui.contexts.IDebugContextService; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.ToolItem; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +/** + * Base class for actions which delegate functionality to an adapter retrieved + * from the current debug context. + */ +abstract public class RetargetDebugContextCommand extends AbstractHandler implements IDebugContextListener { + + private IWorkbenchWindow fWindow = null; + private ISelection fDebugContext; + protected Object fTargetAdapter = null; + // The button representing the command + protected ToolItem fToolItem = null; + + /* (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow) + */ + public RetargetDebugContextCommand() { + fWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + IDebugContextService debugContextService = DebugUITools.getDebugContextManager().getContextService(fWindow); + debugContextService.addPostDebugContextListener(this); + fDebugContext = debugContextService.getActiveContext(); + update(); + } + + public Object execute(ExecutionEvent event) throws ExecutionException { + // Store the toolItem in case we need to act on it. + fToolItem = null; + if (event.getTrigger() instanceof Event) { + Event swtEvent = (Event)event.getTrigger(); + if (swtEvent.widget instanceof ToolItem) { + fToolItem = (ToolItem)swtEvent.widget; + } + } + + if (fTargetAdapter != null) { + try { + performCommand(fTargetAdapter, fDebugContext); + } catch (ExecutionException e) { + ErrorDialog.openError(fWindow.getShell(), MessagesForVMActions.RetargetDebugContextAction_ErrorDialog_title, MessagesForVMActions.RetargetDebugContextAction_ErrorDialog_message, null); + } + } + + return null; + } + + /** + * Returns whether the specific operation is supported. + * + * @param target the target adapter + * @param debugContext the selection to verify the operation on + * @return whether the operation can be performed + */ + protected abstract boolean canPerformCommand(Object target, ISelection debugContext); + + /** + * Performs the specific operation. + * + * @param target the target adapter + * @param debugContext the selection to verify the operation on + * @throws CoreException if an exception occurs + */ + protected abstract void performCommand(Object target, ISelection debugContext) throws ExecutionException; + + /** + * Returns the type of adapter (target) this command works on. + * + * @return the type of adapter this command works on + */ + protected abstract Class getAdapterClass(); + + public void update() { + fTargetAdapter = null; + if (fDebugContext instanceof IStructuredSelection) { + IStructuredSelection ss = (IStructuredSelection) fDebugContext; + if (!ss.isEmpty()) { + Object object = ss.getFirstElement(); + if (object instanceof IAdaptable) { + fTargetAdapter = getAdapter((IAdaptable) object); + if (fTargetAdapter != null) { + setBaseEnabled(canPerformCommand(fTargetAdapter, fDebugContext)); + return; + } + } + } + } + + setBaseEnabled(false); + } + + @Override + public void dispose() { + DebugUITools.getDebugContextManager().getContextService(fWindow).removePostDebugContextListener(this); + fTargetAdapter = null; + } + + public void debugContextChanged(DebugContextEvent event) { + fDebugContext = event.getContext(); + update(); + } + + protected Object getAdapter(IAdaptable adaptable) { + Object adapter = adaptable.getAdapter(getAdapterClass()); + if (adapter == null) { + IAdapterManager adapterManager = Platform.getAdapterManager(); + if (adapterManager.hasAdapter(adaptable, getAdapterClass().getName())) { + adapter = adapterManager.loadAdapter(adaptable, getAdapterClass().getName()); + } + } + return adapter; + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/META-INF/MANIFEST.MF b/dsf-gdb/org.eclipse.cdt.dsf.gdb/META-INF/MANIFEST.MF index 997fe8ae320..bcfdc05818f 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/META-INF/MANIFEST.MF +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/META-INF/MANIFEST.MF @@ -10,7 +10,8 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.debug.core, org.eclipse.cdt.core, org.eclipse.cdt.debug.core, - org.eclipse.core.variables + org.eclipse.core.variables, + org.eclipse.jface Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: J2SE-1.5 Export-Package: org.eclipse.cdt.dsf.gdb, diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/actions/IReverseResumeHandler.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/actions/IReverseResumeHandler.java new file mode 100644 index 00000000000..9f42f302bd0 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/actions/IReverseResumeHandler.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.actions; + +import org.eclipse.jface.viewers.ISelection; + +public interface IReverseResumeHandler { + public boolean canReverseResume(ISelection debugContext); + public void reverseResume(ISelection debugContext); +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/actions/IReverseStepIntoHandler.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/actions/IReverseStepIntoHandler.java new file mode 100644 index 00000000000..e0e72e329e3 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/actions/IReverseStepIntoHandler.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.actions; + +import org.eclipse.jface.viewers.ISelection; + +public interface IReverseStepIntoHandler { + public boolean canReverseStepInto(ISelection debugContext); + public void reverseStepInto(ISelection debugContext); +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/actions/IReverseStepOverHandler.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/actions/IReverseStepOverHandler.java new file mode 100644 index 00000000000..1f02cd8aaf0 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/actions/IReverseStepOverHandler.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.actions; + +import org.eclipse.jface.viewers.ISelection; + +public interface IReverseStepOverHandler { + public boolean canReverseStepOver(ISelection debugContext); + public void reverseStepOver(ISelection debugContext); +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/actions/IReverseToggleHandler.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/actions/IReverseToggleHandler.java new file mode 100644 index 00000000000..4aee8e4bd1d --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/actions/IReverseToggleHandler.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.actions; + +import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; +import org.eclipse.jface.viewers.ISelection; + +public interface IReverseToggleHandler { + public boolean canToggleReverse(ISelection debugContext); + public void toggleReverse(ISelection debugContext); + public boolean isReverseToggled(ISelection debugContext); + public boolean isReverseToggled(ICommandControlDMContext debugContext); + +} \ No newline at end of file diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/actions/IUncallHandler.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/actions/IUncallHandler.java new file mode 100644 index 00000000000..dab6c425b67 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/actions/IUncallHandler.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.actions; + +import org.eclipse.jface.viewers.ISelection; + +public interface IUncallHandler { + public boolean canUncall(ISelection debugContext); + public void uncall(ISelection debugContext); +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_0.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_0.java index ee33e80b63b..5370306f248 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_0.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_0.java @@ -9,7 +9,8 @@ * Wind River Systems - initial API and implementation * Ericsson - Modified for additional functionality * Ericsson - Version 7.0 - * Nokia - create and use backend service. + * Nokia - create and use backend service. + * Ericsson - Added IReverseControl support *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.service; @@ -24,17 +25,32 @@ import org.eclipse.cdt.dsf.datamodel.IDMContext; import org.eclipse.cdt.dsf.debug.service.IRunControl; import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext; import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext; +import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext; import org.eclipse.cdt.dsf.mi.service.IMIProcesses; import org.eclipse.cdt.dsf.mi.service.MIRunControl; +import org.eclipse.cdt.dsf.mi.service.MIStack; +import org.eclipse.cdt.dsf.mi.service.command.commands.MICommand; +import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecReverseContinue; +import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecReverseNext; +import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecReverseNextInstruction; +import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecReverseStep; +import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecReverseStepInstruction; +import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecUncall; +import org.eclipse.cdt.dsf.mi.service.command.commands.RawCommand; +import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; import org.eclipse.cdt.dsf.service.DsfSession; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; -public class GDBRunControl_7_0 extends MIRunControl { +public class GDBRunControl_7_0 extends MIRunControl implements IReverseRunControl { private IGDBBackend fGdb; private IMIProcesses fProcService; + private boolean fReverseSupported = true; + private boolean fReverseStepping = false; + private boolean fReverseModeEnabled = false; public GDBRunControl_7_0(DsfSession session) { super(session); @@ -55,7 +71,8 @@ public class GDBRunControl_7_0 extends MIRunControl { fGdb = getServicesTracker().getService(IGDBBackend.class); fProcService = getServicesTracker().getService(IMIProcesses.class); - register(new String[]{IRunControl.class.getName(), MIRunControl.class.getName()}, + register(new String[]{IRunControl.class.getName(), MIRunControl.class.getName(), + IReverseRunControl.class.getName()}, new Hashtable()); requestMonitor.done(); } @@ -113,4 +130,195 @@ public class GDBRunControl_7_0 extends MIRunControl { } }); } + + public void canReverseResume(IExecutionDMContext context, DataRequestMonitor rm) { + rm.setData(fReverseModeEnabled && doCanResume(context)); + rm.done(); + } + + public void canReverseStep(IExecutionDMContext context, StepType stepType, DataRequestMonitor rm) { + if (context instanceof IContainerDMContext) { + rm.setData(false); + rm.done(); + return; + } + + canReverseResume(context, rm); + } + + public boolean isReverseStepping(IExecutionDMContext context) { + return !fTerminated && fReverseStepping; + } + + public void reverseResume(IExecutionDMContext context, final RequestMonitor rm) { + if (fReverseModeEnabled && doCanResume(context)) { + fResumePending = true; + // Cygwin GDB will accept commands and execute them after the step + // which is not what we want, so mark the target as unavailable + // as soon as we send a resume command. + getCache().setContextAvailable(context, false); + MIExecReverseContinue cmd = null; + if (context instanceof IContainerDMContext) { + cmd = new MIExecReverseContinue(context); + } else { + IMIExecutionDMContext dmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class); + if (dmc == null){ + rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Given context: " + context + " is not an execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$ + rm.done(); + return; + } + cmd = new MIExecReverseContinue(dmc); + } +// getConnection().queueCommand(cmd, new DataRequestMonitor(getExecutor(), rm)); + // temporary + final MIExecReverseContinue finalcmd = cmd; + final IExecutionDMContext finaldmc = context; + getConnection().queueCommand( + new RawCommand(finaldmc, "set exec-direction reverse"), + new DataRequestMonitor(getExecutor(), rm) { + @Override + public void handleSuccess() { + getConnection().queueCommand(finalcmd, new DataRequestMonitor(getExecutor(), rm) { + @Override + public void handleSuccess() { + getConnection().queueCommand( + new RawCommand(finaldmc, "set exec-direction forward"), + new DataRequestMonitor(getExecutor(), rm)); + } + }); + } + }); + // end temporary + } else { + rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Given context: " + context + ", is already running or reverse not enabled.", null)); //$NON-NLS-1$ //$NON-NLS-2$ + rm.done(); + } + + } + + public void reverseStep(IExecutionDMContext context, StepType stepType, final RequestMonitor rm) { + assert context != null; + + IMIExecutionDMContext dmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class); + if (dmc == null){ + rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Given context: " + context + " is not an execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$ + rm.done(); + return; + } + + if (!fReverseModeEnabled || !doCanResume(context)) { + rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Cannot resume context", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + fResumePending = true; + fReverseStepping = true; + getCache().setContextAvailable(context, false); + MICommand cmd = null; + switch(stepType) { + case STEP_INTO: + cmd = new MIExecReverseStep(dmc, 1); + break; + case STEP_OVER: + cmd = new MIExecReverseNext(dmc, 1); + break; + case STEP_RETURN: + // The -exec-finish command operates on the selected stack frame, but here we always + // want it to operate on the top stack frame. So we manually create a top-frame + // context to use with the MI command. + // We get a local instance of the stack service because the stack service can be shut + // down before the run control service is shut down. So it is possible for the + // getService() request below to return null. + MIStack stackService = getServicesTracker().getService(MIStack.class); + if (stackService != null) { + IFrameDMContext topFrameDmc = stackService.createFrameDMContext(dmc, 0); + cmd = new MIExecUncall(topFrameDmc); + } else { + rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Cannot create context for command, stack service not available.", null)); //$NON-NLS-1$ + rm.done(); + return; + } + break; + case INSTRUCTION_STEP_INTO: + cmd = new MIExecReverseStepInstruction(dmc, 1); + break; + case INSTRUCTION_STEP_OVER: + cmd = new MIExecReverseNextInstruction(dmc, 1); + break; + default: + rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Given step type not supported", null)); //$NON-NLS-1$ + rm.done(); + } + + // temporary + final MICommand finalcmd = cmd; + final IExecutionDMContext finaldmc = context; + getConnection().queueCommand( + new RawCommand(finaldmc, "set exec-direction reverse"), + new DataRequestMonitor(getExecutor(), rm) { + @Override + public void handleSuccess() { + getConnection().queueCommand(finalcmd, new DataRequestMonitor(getExecutor(), rm) { + @Override + public void handleSuccess() { + getConnection().queueCommand( + new RawCommand(finaldmc, "set exec-direction forward"), + new DataRequestMonitor(getExecutor(), rm)); + } + }); + } + }); + // end temporary + } + + public void canEnableReverseMode(ICommandControlDMContext context, DataRequestMonitor rm) { + rm.setData(fReverseSupported); + rm.done(); + } + + public void isReverseModeEnabled(ICommandControlDMContext context, DataRequestMonitor rm) { + rm.setData(fReverseModeEnabled); + rm.done(); + } + + public void enableReverseMode(ICommandControlDMContext context, final boolean enable, final RequestMonitor rm) { + if (!fReverseSupported) { + rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Reverse mode is not supported.", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + if (fReverseModeEnabled == enable) { + rm.done(); + return; + } + + if (enable) { + getConnection().queueCommand( + new RawCommand(context, "record"), //$NON-NLS-1$ + new DataRequestMonitor(getExecutor(), rm) { + @Override + public void handleSuccess() { + setReverseModeEnabled(true); + rm.done(); + } + }); + } else { + getConnection().queueCommand( + new RawCommand(context, "stoprecord"), //$NON-NLS-1$ + new DataRequestMonitor(getExecutor(), rm) { + @Override + public void handleSuccess() { + setReverseModeEnabled(false); + rm.done(); + } + }); + } + } + + public void setReverseModeEnabled(boolean enabled) { + fReverseModeEnabled = enabled; + System.setProperty("debug.reverse.enabled", Boolean.toString(enabled)); + } } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IReverseRunControl.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IReverseRunControl.java new file mode 100644 index 00000000000..54c9a0bb4ec --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IReverseRunControl.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.service; + +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.cdt.dsf.debug.service.IRunControl.StepType; +import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; + +/** + * @since 1.1 + */ +public interface IReverseRunControl { + + void canReverseResume(IExecutionDMContext context, DataRequestMonitor rm); + void reverseResume(IExecutionDMContext context, RequestMonitor requestMonitor); + boolean isReverseStepping(IExecutionDMContext context); + void canReverseStep(IExecutionDMContext context, StepType stepType, DataRequestMonitor rm); + void reverseStep(IExecutionDMContext context, StepType stepType, RequestMonitor requestMonitor); + + void canEnableReverseMode(ICommandControlDMContext context, DataRequestMonitor rm); + void isReverseModeEnabled(ICommandControlDMContext context, DataRequestMonitor rm); + void enableReverseMode(ICommandControlDMContext context, boolean enable, RequestMonitor rm); +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_0.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_0.java index c156634d217..dae8fac123a 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_0.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_0.java @@ -30,6 +30,7 @@ import org.eclipse.cdt.dsf.debug.service.command.ICommandControl; import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService; import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch; +import org.eclipse.cdt.dsf.gdb.service.GDBRunControl_7_0; import org.eclipse.cdt.dsf.gdb.service.IGDBBackend; import org.eclipse.cdt.dsf.gdb.service.SessionType; import org.eclipse.cdt.dsf.mi.service.IMIBackend; @@ -258,14 +259,14 @@ public class GDBControl_7_0 extends AbstractMIControl implements IGDBControl { return true; } - /* + /** * Start the program. */ public void start(GdbLaunch launch, final RequestMonitor requestMonitor) { startOrRestart(launch, false, requestMonitor); } - /* + /** * Before restarting the inferior, we must re-initialize its input/output streams * and create a new inferior process object. Then we can restart the inferior. */ @@ -273,8 +274,9 @@ public class GDBControl_7_0 extends AbstractMIControl implements IGDBControl { startOrRestart(launch, true, requestMonitor); } - /* + /** * Insert breakpoint at entry if set, and start or restart the program. + * Note that restart does not apply to remote or attach sessions. */ protected void startOrRestart(final GdbLaunch launch, boolean restart, final RequestMonitor requestMonitor) { if (fMIBackend.getIsAttachSession()) { @@ -307,7 +309,20 @@ public class GDBControl_7_0 extends AbstractMIControl implements IGDBControl { return; } - final DataRequestMonitor execMonitor = new DataRequestMonitor(getExecutor(), requestMonitor); + final DataRequestMonitor execMonitor = new DataRequestMonitor(getExecutor(), requestMonitor) { + @Override + public void handleSuccess() { + DsfServicesTracker servicesTracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), getSession().getId()); + GDBRunControl_7_0 reverseService = servicesTracker.getService(GDBRunControl_7_0.class); + servicesTracker.dispose(); + + if (reverseService != null) { + // When starting or restarting a program, reverse mode is automatically disabled + reverseService.setReverseModeEnabled(false); + } + requestMonitor.done(); + } + }; if (!stopInMain) { // Just start the program. @@ -335,7 +350,7 @@ public class GDBControl_7_0 extends AbstractMIControl implements IGDBControl { } } - /* + /** * This method creates a new inferior process object based on the current Pty or output stream. */ public void createInferiorProcess() { diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIRunControl.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIRunControl.java index 247ea764052..d27f8436860 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIRunControl.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIRunControl.java @@ -265,9 +265,9 @@ public class MIRunControl extends AbstractDsfService implements IRunControl, ICa // State flags private boolean fSuspended = true; - private boolean fResumePending = false; + protected boolean fResumePending = false; private boolean fStepping = false; - private boolean fTerminated = false; + protected boolean fTerminated = false; private StateChangeReason fStateChangeReason; private IExecutionDMContext fStateChangeTriggeringContext; @@ -316,7 +316,8 @@ public class MIRunControl extends AbstractDsfService implements IRunControl, ICa } public CommandCache getCache() { return fMICommandCache; } - + public ICommandControlService getConnection() { return fConnection; } + public IMIExecutionDMContext createMIExecutionContext(IContainerDMContext container, int threadId) { return new MIExecutionDMC(getSession().getId(), container, threadId); } @@ -472,8 +473,8 @@ public class MIRunControl extends AbstractDsfService implements IRunControl, ICa rm.setData(doCanResume(context)); rm.done(); } - - private boolean doCanResume(IExecutionDMContext context) { + + protected boolean doCanResume(IExecutionDMContext context) { return !fTerminated && isSuspended(context) && !fResumePending; } @@ -602,11 +603,11 @@ public class MIRunControl extends AbstractDsfService implements IRunControl, ICa break; case STEP_RETURN: // The -exec-finish command operates on the selected stack frame, but here we always - // want it to operate on the stop stack frame. So we manually create a top-frame + // want it to operate on the top stack frame. So we manually create a top-frame // context to use with the MI command. // We get a local instance of the stack service because the stack service can be shut // down before the run control service is shut down. So it is possible for the - // getService() reqeust below to return null. + // getService() request below to return null. MIStack stackService = getServicesTracker().getService(MIStack.class); if (stackService != null) { IFrameDMContext topFrameDmc = stackService.createFrameDMContext(dmc, 0); diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIExecReverseContinue.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIExecReverseContinue.java new file mode 100644 index 00000000000..fddc9518884 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIExecReverseContinue.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.mi.service.command.commands; + +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; + +/** Resume backwards. */ +public class MIExecReverseContinue extends MICommand { + + public MIExecReverseContinue(IExecutionDMContext dmc) { + super(dmc, "-exec-continue"); //$NON-NLS-1$ + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIExecReverseNext.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIExecReverseNext.java new file mode 100644 index 00000000000..64517b4c506 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIExecReverseNext.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.mi.service.command.commands; + +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; + +/** Steps backward one source code line, not entering function calls. + */ +public class MIExecReverseNext extends MICommand { + + public MIExecReverseNext(IExecutionDMContext dmc) { + this(dmc, 1); + } + + public MIExecReverseNext(IExecutionDMContext dmc, int count) { + super(dmc, "-exec-next", new String[] { Integer.toString(count) }); //$NON-NLS-1$ + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIExecReverseNextInstruction.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIExecReverseNextInstruction.java new file mode 100644 index 00000000000..d1a52f672d4 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIExecReverseNextInstruction.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.mi.service.command.commands; + +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; + +/** Steps backward one machine instruction, not entering function calls. + */ +public class MIExecReverseNextInstruction extends MICommand { + + public MIExecReverseNextInstruction(IExecutionDMContext dmc) { + this(dmc, 1); + } + + public MIExecReverseNextInstruction(IExecutionDMContext dmc, int count) { + super(dmc, "-exec-nexti", new String[] { Integer.toString(count) }); //$NON-NLS-1$ + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIExecReverseStep.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIExecReverseStep.java new file mode 100644 index 00000000000..b6a45c57723 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIExecReverseStep.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.mi.service.command.commands; + +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; + +/** Step backwards i source lines, entering function calls. + */ +public class MIExecReverseStep extends MICommand { + + public MIExecReverseStep(IExecutionDMContext dmc) { + this(dmc, 1); + } + public MIExecReverseStep(IExecutionDMContext dmc, int count) { + super(dmc, "-exec-step", new String[] { Integer.toString(count) }); //$NON-NLS-1$ + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIExecReverseStepInstruction.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIExecReverseStepInstruction.java new file mode 100644 index 00000000000..ca689d26e83 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIExecReverseStepInstruction.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.mi.service.command.commands; + +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; + +/** Step backwards i instructions, entering function calls. + */ +public class MIExecReverseStepInstruction extends MICommand { + + public MIExecReverseStepInstruction(IExecutionDMContext dmc) { + this(dmc, 1); + } + public MIExecReverseStepInstruction(IExecutionDMContext dmc, int count) { + super(dmc, "-exec-stepi", new String[] { Integer.toString(count) }); //$NON-NLS-1$ + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIExecUncall.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIExecUncall.java new file mode 100644 index 00000000000..936ee77a2ba --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIExecUncall.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2009 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.mi.service.command.commands; + +import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; + +/** Steps backward one source code line, not entering function calls. + */ +public class MIExecUncall extends MICommand { + + public MIExecUncall(IFrameDMContext dmc) { + super(dmc, "-exec-finish"); //$NON-NLS-1$ + } +}