1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-04 23:05:47 +02:00

[258284] First attempt at supporting Reverse Debugging. Note that this can only tested with a manually built GDB with Process Record patches. Also, MI support is not defined yet, so the MI commands created in this commit actually use forward commands and a trick to 'reverse' their meaning.

This commit is contained in:
Marc Khouzam 2009-01-23 18:09:01 +00:00
parent 17fd7a87d9
commit 35a7e9d02b
37 changed files with 1838 additions and 17 deletions

View file

@ -17,7 +17,8 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.cdt.core, org.eclipse.cdt.core,
org.eclipse.cdt.ui, org.eclipse.cdt.ui,
org.eclipse.ui.ide, org.eclipse.ui.ide,
org.eclipse.core.variables org.eclipse.core.variables,
org.eclipse.core.expressions
Bundle-ActivationPolicy: lazy Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-RequiredExecutionEnvironment: J2SE-1.5
Export-Package: org.eclipse.cdt.dsf.gdb.internal.ui.actions;x-internal:=true, Export-Package: org.eclipse.cdt.dsf.gdb.internal.ui.actions;x-internal:=true,

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

View file

@ -13,3 +13,25 @@ providerName=Eclipse.org
action.connect.label = Connect... action.connect.label = Connect...
action.connect.tooltip = Connect to a process 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

View file

@ -142,5 +142,373 @@
</action> </action>
</viewContribution> </viewContribution>
</extension> </extension>
<extension
point="org.eclipse.ui.actionSets">
<actionSet
description="%actionSet.reverse.description"
id="org.eclipse.cdt.dsf.gdb.ui.reverseDebuggingActionSet"
label="%actionSet.reverse.label"
visible="false">
</actionSet>
</extension>
<extension
point="org.eclipse.ui.commands">
<category
description="%command.reverseCategory.description"
id="org.eclipse.cdt.dsf.gdb.ui.reverseDebuggingCategory"
name="%command.reverseCategory.name">
</category>
<command
categoryId="org.eclipse.cdt.dsf.gdb.ui.reverseDebuggingCategory"
description="%command.reverseToggle.description"
id="org.eclipse.cdt.dsf.gdb.ui.commands.reverseToggle"
name="%command.reverseToggle.name">
</command>
<command
categoryId="org.eclipse.cdt.dsf.gdb.ui.reverseDebuggingCategory"
description="%command.reverseResume.description"
id="org.eclipse.cdt.dsf.gdb.ui.commands.reverseResume"
name="%command.reverseResume.name">
</command>
<command
categoryId="org.eclipse.cdt.dsf.gdb.ui.reverseDebuggingCategory"
description="%command.reverseStepInto.description"
id="org.eclipse.cdt.dsf.gdb.ui.commands.reverseStepInto"
name="%command.reverseStepInto.name">
</command>
<command
categoryId="org.eclipse.cdt.dsf.gdb.ui.reverseDebuggingCategory"
description="%command.reverseStepOver.description"
id="org.eclipse.cdt.dsf.gdb.ui.commands.reverseStepOver"
name="%command.reverseStepOver.name">
</command>
<command
categoryId="org.eclipse.cdt.dsf.gdb.ui.reverseDebuggingCategory"
description="%command.uncall.description"
id="org.eclipse.cdt.dsf.gdb.ui.commands.uncall"
name="%command.uncall.name">
</command>
</extension>
<extension
point="org.eclipse.ui.menus">
<menuContribution
locationURI="toolbar:org.eclipse.ui.main.toolbar?after=additions">
<toolbar
id="org.eclipse.cdt.dsf.gdb.ui.toolbars.reverseDebuggingToolbar">
<command
commandId="org.eclipse.cdt.dsf.gdb.ui.commands.reverseToggle"
icon="icons/full/obj16/reversetoggle.gif"
id="org.eclipse.cdt.dsf.gdb.ui.button.reverseToggle"
label="%command.reverseToggle.label"
style="toggle">
<visibleWhen
checkEnabled="false">
<reference
definitionId="org.eclipse.cdt.dsf.gdb.ui.testIsReverseDebuggingActionSetActive">
</reference>
</visibleWhen>
</command>
</toolbar>
</menuContribution>
<menuContribution
locationURI="toolbar:org.eclipse.debug.ui.DebugView?after=threadGroup">
<command
commandId="org.eclipse.cdt.dsf.gdb.ui.commands.reverseResume"
icon="icons/full/obj16/reverseresume.gif"
label="%command.reverseResume.label"
style="push">
<visibleWhen
checkEnabled="false">
<reference
definitionId="org.eclipse.cdt.dsf.gdb.ui.testIsReverseDebuggingActionSetActive">
</reference>
</visibleWhen>
</command>
</menuContribution>
<menuContribution
locationURI="toolbar:org.eclipse.debug.ui.DebugView?after=stepIntoGroup">
<command
commandId="org.eclipse.cdt.dsf.gdb.ui.commands.reverseStepInto"
icon="icons/full/obj16/reversestepinto.gif"
label="%command.reverseStepInto.label"
style="push">
<visibleWhen
checkEnabled="false">
<reference
definitionId="org.eclipse.cdt.dsf.gdb.ui.testIsReverseDebuggingActionSetActive">
</reference>
</visibleWhen>
</command>
</menuContribution>
<menuContribution
locationURI="toolbar:org.eclipse.debug.ui.DebugView?after=stepOverGroup">
<command
commandId="org.eclipse.cdt.dsf.gdb.ui.commands.reverseStepOver"
icon="icons/full/obj16/reversestepover.gif"
label="%command.reverseStepOver.label"
style="push">
<visibleWhen
checkEnabled="false">
<reference
definitionId="org.eclipse.cdt.dsf.gdb.ui.testIsReverseDebuggingActionSetActive">
</reference>
</visibleWhen>
</command>
</menuContribution>
<menuContribution
locationURI="toolbar:org.eclipse.debug.ui.DebugView?after=stepReturnGroup">
<command
commandId="org.eclipse.cdt.dsf.gdb.ui.commands.uncall"
icon="icons/full/obj16/uncall.gif"
label="%command.uncall.label"
style="push">
<visibleWhen
checkEnabled="false">
<reference
definitionId="org.eclipse.cdt.dsf.gdb.ui.testIsReverseDebuggingActionSetActive">
</reference>
</visibleWhen>
</command>
</menuContribution>
<menuContribution
locationURI="menu:org.eclipse.ui.run?after=stepGroup">
<command
commandId="org.eclipse.cdt.dsf.gdb.ui.commands.reverseResume"
icon="icons/full/obj16/reverseresume.gif"
label="%command.reverseResume.label"
style="push">
<visibleWhen
checkEnabled="false">
<reference
definitionId="org.eclipse.cdt.dsf.gdb.ui.testIsReverseDebuggingActionSetActive">
</reference>
</visibleWhen>
</command>
</menuContribution>
<menuContribution
locationURI="menu:org.eclipse.ui.run?before=stepIntoGroup">
<command
commandId="org.eclipse.cdt.dsf.gdb.ui.commands.reverseStepInto"
icon="icons/full/obj16/reversestepinto.gif"
label="%command.reverseStepInto.label"
style="push">
<visibleWhen
checkEnabled="false">
<reference
definitionId="org.eclipse.cdt.dsf.gdb.ui.testIsReverseDebuggingActionSetActive">
</reference>
</visibleWhen>
</command>
</menuContribution>
<menuContribution
locationURI="menu:org.eclipse.ui.run?before=stepOverGroup">
<command
commandId="org.eclipse.cdt.dsf.gdb.ui.commands.reverseStepOver"
icon="icons/full/obj16/reversestepover.gif"
label="%command.reverseStepOver.label"
style="push">
<visibleWhen
checkEnabled="false">
<reference
definitionId="org.eclipse.cdt.dsf.gdb.ui.testIsReverseDebuggingActionSetActive">
</reference>
</visibleWhen>
</command>
</menuContribution>
<menuContribution
locationURI="menu:org.eclipse.ui.run?before=stepReturnGroup">
<command
commandId="org.eclipse.cdt.dsf.gdb.ui.commands.uncall"
icon="icons/full/obj16/uncall.gif"
label="%command.uncall.label"
style="push">
<visibleWhen
checkEnabled="false">
<reference
definitionId="org.eclipse.cdt.dsf.gdb.ui.testIsReverseDebuggingActionSetActive">
</reference>
</visibleWhen>
</command>
</menuContribution>
<menuContribution
locationURI="popup:org.eclipse.debug.ui.DebugView?after=threadGroup">
<command
commandId="org.eclipse.cdt.dsf.gdb.ui.commands.reverseResume"
icon="icons/full/obj16/reverseresume.gif"
label="%command.reverseResume.label"
style="push">
<visibleWhen
checkEnabled="false">
<reference
definitionId="org.eclipse.cdt.dsf.gdb.ui.testIsReverseDebuggingActionSetActive">
</reference>
</visibleWhen>
</command>
</menuContribution>
<menuContribution
locationURI="popup:org.eclipse.debug.ui.DebugView?before=stepIntoGroup">
<command
commandId="org.eclipse.cdt.dsf.gdb.ui.commands.reverseStepInto"
icon="icons/full/obj16/reversestepinto.gif"
label="%command.reverseStepInto.label"
style="push">
<visibleWhen
checkEnabled="false">
<reference
definitionId="org.eclipse.cdt.dsf.gdb.ui.testIsReverseDebuggingActionSetActive">
</reference>
</visibleWhen>
</command>
</menuContribution>
<menuContribution
locationURI="popup:org.eclipse.debug.ui.DebugView?before=stepOverGroup">
<command
commandId="org.eclipse.cdt.dsf.gdb.ui.commands.reverseStepOver"
icon="icons/full/obj16/reversestepover.gif"
label="%command.reverseStepOver.label"
style="push">
<visibleWhen
checkEnabled="false">
<reference
definitionId="org.eclipse.cdt.dsf.gdb.ui.testIsReverseDebuggingActionSetActive">
</reference>
</visibleWhen>
</command>
</menuContribution>
<menuContribution
locationURI="popup:org.eclipse.debug.ui.DebugView?before=stepReturnGroup">
<command
commandId="org.eclipse.cdt.dsf.gdb.ui.commands.uncall"
icon="icons/full/obj16/uncall.gif"
label="%command.uncall.label"
style="push">
<visibleWhen
checkEnabled="false">
<reference
definitionId="org.eclipse.cdt.dsf.gdb.ui.testIsReverseDebuggingActionSetActive">
</reference>
</visibleWhen>
</command>
</menuContribution>
</extension>
<extension
point="org.eclipse.ui.bindings">
<key
commandId="org.eclipse.cdt.dsf.gdb.ui.commands.reverseResume"
contextId="org.eclipse.ui.contexts.window"
schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
sequence="SHIFT+F8">
</key>
<key
commandId="org.eclipse.cdt.dsf.gdb.ui.commands.reverseStepInto"
contextId="org.eclipse.ui.contexts.window"
schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
sequence="SHIFT+F5">
</key>
<key
commandId="org.eclipse.cdt.dsf.gdb.ui.commands.reverseStepOver"
contextId="org.eclipse.ui.contexts.window"
schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
sequence="SHIFT+F6">
</key>
<key
commandId="org.eclipse.cdt.dsf.gdb.ui.commands.uncall"
contextId="org.eclipse.ui.contexts.window"
schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
sequence="SHIFT+F7">
</key>
</extension>
<extension
point="org.eclipse.core.expressions.definitions">
<definition
id="org.eclipse.cdt.dsf.gdb.ui.testIsReverseDebuggingActionSetActive">
<with
variable="activeContexts">
<iterate
operator="or">
<equals
value="org.eclipse.cdt.dsf.gdb.ui.reverseDebuggingActionSet">
</equals>
</iterate>
</with>
</definition>
<definition
id="org.eclipse.cdt.dsf.gdb.ui.testIsGdbUIPluginActive">
<with
variable="org.eclipse.core.runtime.Platform">
<test
args="org.eclipse.cdt.dsf.gdb.ui"
property="org.eclipse.core.runtime.bundleState"
value="ACTIVE">
</test>
</with>
</definition>
</extension>
<extension
point="org.eclipse.ui.handlers">
<handler
class="org.eclipse.cdt.dsf.gdb.internal.ui.actions.ReverseToggleCommandHandler"
commandId="org.eclipse.cdt.dsf.gdb.ui.commands.reverseToggle">
<enabledWhen>
<reference
definitionId="org.eclipse.cdt.dsf.gdb.ui.testIsGdbUIPluginActive">
</reference>
</enabledWhen>
</handler>
<handler
class="org.eclipse.cdt.dsf.gdb.internal.ui.actions.ReverseResumeCommandHandler"
commandId="org.eclipse.cdt.dsf.gdb.ui.commands.reverseResume">
<enabledWhen>
<reference
definitionId="org.eclipse.cdt.dsf.gdb.ui.testIsGdbUIPluginActive">
</reference>
</enabledWhen>
</handler>
<handler
class="org.eclipse.cdt.dsf.gdb.internal.ui.actions.ReverseStepIntoCommandHandler"
commandId="org.eclipse.cdt.dsf.gdb.ui.commands.reverseStepInto">
<enabledWhen>
<reference
definitionId="org.eclipse.cdt.dsf.gdb.ui.testIsGdbUIPluginActive">
</reference>
</enabledWhen>
</handler>
<handler
class="org.eclipse.cdt.dsf.gdb.internal.ui.actions.ReverseStepOverCommandHandler"
commandId="org.eclipse.cdt.dsf.gdb.ui.commands.reverseStepOver">
<enabledWhen>
<reference
definitionId="org.eclipse.cdt.dsf.gdb.ui.testIsGdbUIPluginActive">
</reference>
</enabledWhen>
</handler>
<handler
class="org.eclipse.cdt.dsf.gdb.internal.ui.actions.UncallCommandHandler"
commandId="org.eclipse.cdt.dsf.gdb.ui.commands.uncall">
<enabledWhen>
<reference
definitionId="org.eclipse.cdt.dsf.gdb.ui.testIsGdbUIPluginActive">
</reference>
</enabledWhen>
</handler>
</extension>
<extension
point="org.eclipse.core.expressions.propertyTesters">
<propertyTester
class="org.eclipse.cdt.dsf.gdb.internal.ui.actions.ReverseDebuggingPropertyTester"
id="org.eclipse.cdt.dsf.gdb.ui.selectionReverseDebuggingTester"
namespace="org.eclipse.cdt.dsf.gdb.ui"
properties="isReverseDebuggingEnabled"
type="org.eclipse.jface.viewers.TreeSelection">
</propertyTester>
<propertyTester
class="org.eclipse.cdt.dsf.gdb.internal.ui.actions.ReverseDebuggingPropertyTester"
id="org.eclipse.cdt.dsf.gdb.ui.partReverseDebuggingTester"
namespace="org.eclipse.cdt.dsf.gdb.ui"
properties="isReverseDebuggingEnabled"
type="org.eclipse.debug.ui.IDebugView">
</propertyTester>
</extension>
</plugin> </plugin>

View file

@ -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.actions.IRefreshAllTarget;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.DefaultDsfModelSelectionPolicyFactory; 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.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.DsfTerminateCommand;
import org.eclipse.cdt.dsf.gdb.internal.ui.actions.GdbConnectCommand; 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.GdbDisconnectCommand;
import org.eclipse.cdt.dsf.gdb.internal.ui.actions.GdbRestartCommand; 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.internal.ui.viewmodel.GdbViewModelAdapter;
import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch; import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch;
import org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate; import org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate;
@ -77,10 +87,14 @@ public class GdbAdapterFactory
final GdbViewModelAdapter fViewModelAdapter; final GdbViewModelAdapter fViewModelAdapter;
final DsfSourceDisplayAdapter fSourceDisplayAdapter; final DsfSourceDisplayAdapter fSourceDisplayAdapter;
final DsfStepIntoCommand fStepIntoCommand; final DsfStepIntoCommand fStepIntoCommand;
final GdbReverseStepIntoCommand fReverseStepIntoCommand;
final DsfStepOverCommand fStepOverCommand; final DsfStepOverCommand fStepOverCommand;
final GdbReverseStepOverCommand fReverseStepOverCommand;
final DsfStepReturnCommand fStepReturnCommand; final DsfStepReturnCommand fStepReturnCommand;
final GdbUncallCommand fUncallCommand;
final DsfSuspendCommand fSuspendCommand; final DsfSuspendCommand fSuspendCommand;
final DsfResumeCommand fResumeCommand; final DsfResumeCommand fResumeCommand;
final GdbReverseResumeCommand fReverseResumeCommand;
final GdbRestartCommand fRestartCommand; final GdbRestartCommand fRestartCommand;
final DsfTerminateCommand fTerminateCommand; final DsfTerminateCommand fTerminateCommand;
final GdbConnectCommand fConnectCommand; final GdbConnectCommand fConnectCommand;
@ -91,6 +105,7 @@ public class GdbAdapterFactory
final IModelSelectionPolicyFactory fModelSelectionPolicyFactory; final IModelSelectionPolicyFactory fModelSelectionPolicyFactory;
final SteppingController fSteppingController; final SteppingController fSteppingController;
final DefaultRefreshAllTarget fRefreshAllTarget; final DefaultRefreshAllTarget fRefreshAllTarget;
final GdbReverseToggleCommand fReverseToggleTarget;
SessionAdapterSet(GdbLaunch launch) { SessionAdapterSet(GdbLaunch launch) {
fLaunch = launch; fLaunch = launch;
@ -111,10 +126,14 @@ public class GdbAdapterFactory
fSteppingModeTarget= new DsfSteppingModeTarget(); fSteppingModeTarget= new DsfSteppingModeTarget();
fStepIntoCommand = new DsfStepIntoCommand(session, fSteppingModeTarget); fStepIntoCommand = new DsfStepIntoCommand(session, fSteppingModeTarget);
fReverseStepIntoCommand = new GdbReverseStepIntoCommand(session, fSteppingModeTarget);
fStepOverCommand = new DsfStepOverCommand(session, fSteppingModeTarget); fStepOverCommand = new DsfStepOverCommand(session, fSteppingModeTarget);
fReverseStepOverCommand = new GdbReverseStepOverCommand(session, fSteppingModeTarget);
fStepReturnCommand = new DsfStepReturnCommand(session); fStepReturnCommand = new DsfStepReturnCommand(session);
fUncallCommand = new GdbUncallCommand(session, fSteppingModeTarget);
fSuspendCommand = new DsfSuspendCommand(session); fSuspendCommand = new DsfSuspendCommand(session);
fResumeCommand = new DsfResumeCommand(session); fResumeCommand = new DsfResumeCommand(session);
fReverseResumeCommand = new GdbReverseResumeCommand(session);
fRestartCommand = new GdbRestartCommand(session, fLaunch); fRestartCommand = new GdbRestartCommand(session, fLaunch);
fTerminateCommand = new DsfTerminateCommand(session); fTerminateCommand = new DsfTerminateCommand(session);
fConnectCommand = new GdbConnectCommand(session); fConnectCommand = new GdbConnectCommand(session);
@ -122,19 +141,25 @@ public class GdbAdapterFactory
fSuspendTrigger = new DsfSuspendTrigger(session, fLaunch); fSuspendTrigger = new DsfSuspendTrigger(session, fLaunch);
fModelSelectionPolicyFactory = new DefaultDsfModelSelectionPolicyFactory(); fModelSelectionPolicyFactory = new DefaultDsfModelSelectionPolicyFactory();
fRefreshAllTarget = new DefaultRefreshAllTarget(); fRefreshAllTarget = new DefaultRefreshAllTarget();
fReverseToggleTarget = new GdbReverseToggleCommand(session);
session.registerModelAdapter(ISteppingModeTarget.class, fSteppingModeTarget); session.registerModelAdapter(ISteppingModeTarget.class, fSteppingModeTarget);
session.registerModelAdapter(IStepIntoHandler.class, fStepIntoCommand); session.registerModelAdapter(IStepIntoHandler.class, fStepIntoCommand);
session.registerModelAdapter(IReverseStepIntoHandler.class, fReverseStepIntoCommand);
session.registerModelAdapter(IStepOverHandler.class, fStepOverCommand); session.registerModelAdapter(IStepOverHandler.class, fStepOverCommand);
session.registerModelAdapter(IReverseStepOverHandler.class, fReverseStepOverCommand);
session.registerModelAdapter(IStepReturnHandler.class, fStepReturnCommand); session.registerModelAdapter(IStepReturnHandler.class, fStepReturnCommand);
session.registerModelAdapter(IUncallHandler.class, fUncallCommand);
session.registerModelAdapter(ISuspendHandler.class, fSuspendCommand); session.registerModelAdapter(ISuspendHandler.class, fSuspendCommand);
session.registerModelAdapter(IResumeHandler.class, fResumeCommand); session.registerModelAdapter(IResumeHandler.class, fResumeCommand);
session.registerModelAdapter(IReverseResumeHandler.class, fReverseResumeCommand);
session.registerModelAdapter(IRestart.class, fRestartCommand); session.registerModelAdapter(IRestart.class, fRestartCommand);
session.registerModelAdapter(ITerminateHandler.class, fTerminateCommand); session.registerModelAdapter(ITerminateHandler.class, fTerminateCommand);
session.registerModelAdapter(IConnect.class, fConnectCommand); session.registerModelAdapter(IConnect.class, fConnectCommand);
session.registerModelAdapter(IDisconnectHandler.class, fDisconnectCommand); session.registerModelAdapter(IDisconnectHandler.class, fDisconnectCommand);
session.registerModelAdapter(IModelSelectionPolicyFactory.class, fModelSelectionPolicyFactory); session.registerModelAdapter(IModelSelectionPolicyFactory.class, fModelSelectionPolicyFactory);
session.registerModelAdapter(IRefreshAllTarget.class, fRefreshAllTarget); session.registerModelAdapter(IRefreshAllTarget.class, fRefreshAllTarget);
session.registerModelAdapter(IReverseToggleHandler.class, fReverseToggleTarget);
fDebugModelProvider = new IDebugModelProvider() { fDebugModelProvider = new IDebugModelProvider() {
// @see org.eclipse.debug.core.model.IDebugModelProvider#getModelIdentifiers() // @see org.eclipse.debug.core.model.IDebugModelProvider#getModelIdentifiers()
@ -165,27 +190,37 @@ public class GdbAdapterFactory
session.unregisterModelAdapter(ISteppingModeTarget.class); session.unregisterModelAdapter(ISteppingModeTarget.class);
session.unregisterModelAdapter(IStepIntoHandler.class); session.unregisterModelAdapter(IStepIntoHandler.class);
session.unregisterModelAdapter(IReverseStepIntoHandler.class);
session.unregisterModelAdapter(IStepOverHandler.class); session.unregisterModelAdapter(IStepOverHandler.class);
session.unregisterModelAdapter(IReverseStepOverHandler.class);
session.unregisterModelAdapter(IStepReturnHandler.class); session.unregisterModelAdapter(IStepReturnHandler.class);
session.unregisterModelAdapter(IUncallHandler.class);
session.unregisterModelAdapter(ISuspendHandler.class); session.unregisterModelAdapter(ISuspendHandler.class);
session.unregisterModelAdapter(IResumeHandler.class); session.unregisterModelAdapter(IResumeHandler.class);
session.unregisterModelAdapter(IReverseResumeHandler.class);
session.unregisterModelAdapter(IRestart.class); session.unregisterModelAdapter(IRestart.class);
session.unregisterModelAdapter(ITerminateHandler.class); session.unregisterModelAdapter(ITerminateHandler.class);
session.unregisterModelAdapter(IConnect.class); session.unregisterModelAdapter(IConnect.class);
session.unregisterModelAdapter(IDisconnectHandler.class); session.unregisterModelAdapter(IDisconnectHandler.class);
session.unregisterModelAdapter(IModelSelectionPolicyFactory.class); session.unregisterModelAdapter(IModelSelectionPolicyFactory.class);
session.unregisterModelAdapter(IRefreshAllTarget.class); session.unregisterModelAdapter(IRefreshAllTarget.class);
session.unregisterModelAdapter(IReverseToggleHandler.class);
fStepIntoCommand.dispose(); fStepIntoCommand.dispose();
fReverseStepIntoCommand.dispose();
fStepOverCommand.dispose(); fStepOverCommand.dispose();
fReverseStepOverCommand.dispose();
fStepReturnCommand.dispose(); fStepReturnCommand.dispose();
fUncallCommand.dispose();
fSuspendCommand.dispose(); fSuspendCommand.dispose();
fResumeCommand.dispose(); fResumeCommand.dispose();
fReverseResumeCommand.dispose();
fRestartCommand.dispose(); fRestartCommand.dispose();
fTerminateCommand.dispose(); fTerminateCommand.dispose();
fConnectCommand.dispose(); fConnectCommand.dispose();
fDisconnectCommand.dispose(); fDisconnectCommand.dispose();
fSuspendTrigger.dispose(); fSuspendTrigger.dispose();
fReverseToggleTarget.dispose();
} }
} }

View file

@ -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<Boolean> canReverseQuery = new Query<Boolean>() {
@Override
public void execute(DataRequestMonitor<Boolean> 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<Object> reverseStepQuery = new Query<Object>() {
@Override
public void execute(DataRequestMonitor<Object> 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();
}

View file

@ -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<Boolean> canReverseResume = new Query<Boolean>() {
@Override
public void execute(DataRequestMonitor<Boolean> 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<Object> reverseResume = new Query<Object>() {
@Override
public void execute(DataRequestMonitor<Object> 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;
}
}

View file

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

View file

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

View file

@ -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<Boolean> canSetReverseMode = new Query<Boolean>() {
@Override
public void execute(DataRequestMonitor<Boolean> 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<Object> setReverseMode = new Query<Object>() {
@Override
public void execute(final DataRequestMonitor<Object> rm) {
final IReverseRunControl runControl = fTracker.getService(IReverseRunControl.class);
if (runControl != null) {
runControl.isReverseModeEnabled(dmc,
new DataRequestMonitor<Boolean>(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<Boolean> isToggledQuery = new Query<Boolean>() {
@Override
public void execute(final DataRequestMonitor<Boolean> 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;
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -10,7 +10,8 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.debug.core, org.eclipse.debug.core,
org.eclipse.cdt.core, org.eclipse.cdt.core,
org.eclipse.cdt.debug.core, org.eclipse.cdt.debug.core,
org.eclipse.core.variables org.eclipse.core.variables,
org.eclipse.jface
Bundle-ActivationPolicy: lazy Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-RequiredExecutionEnvironment: J2SE-1.5
Export-Package: org.eclipse.cdt.dsf.gdb, Export-Package: org.eclipse.cdt.dsf.gdb,

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -10,6 +10,7 @@
* Ericsson - Modified for additional functionality * Ericsson - Modified for additional functionality
* Ericsson - Version 7.0 * 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; 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.IRunControl;
import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext; 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.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.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext; import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
import org.eclipse.cdt.dsf.mi.service.IMIProcesses; import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
import org.eclipse.cdt.dsf.mi.service.MIRunControl; 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.cdt.dsf.service.DsfSession;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status; 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 IGDBBackend fGdb;
private IMIProcesses fProcService; private IMIProcesses fProcService;
private boolean fReverseSupported = true;
private boolean fReverseStepping = false;
private boolean fReverseModeEnabled = false;
public GDBRunControl_7_0(DsfSession session) { public GDBRunControl_7_0(DsfSession session) {
super(session); super(session);
@ -55,7 +71,8 @@ public class GDBRunControl_7_0 extends MIRunControl {
fGdb = getServicesTracker().getService(IGDBBackend.class); fGdb = getServicesTracker().getService(IGDBBackend.class);
fProcService = getServicesTracker().getService(IMIProcesses.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<String,String>()); new Hashtable<String,String>());
requestMonitor.done(); requestMonitor.done();
} }
@ -113,4 +130,195 @@ public class GDBRunControl_7_0 extends MIRunControl {
} }
}); });
} }
public void canReverseResume(IExecutionDMContext context, DataRequestMonitor<Boolean> rm) {
rm.setData(fReverseModeEnabled && doCanResume(context));
rm.done();
}
public void canReverseStep(IExecutionDMContext context, StepType stepType, DataRequestMonitor<Boolean> 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<MIInfo>(getExecutor(), rm));
// temporary
final MIExecReverseContinue finalcmd = cmd;
final IExecutionDMContext finaldmc = context;
getConnection().queueCommand(
new RawCommand(finaldmc, "set exec-direction reverse"),
new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
@Override
public void handleSuccess() {
getConnection().queueCommand(finalcmd, new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
@Override
public void handleSuccess() {
getConnection().queueCommand(
new RawCommand(finaldmc, "set exec-direction forward"),
new DataRequestMonitor<MIInfo>(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<MIInfo> 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<MIInfo> finalcmd = cmd;
final IExecutionDMContext finaldmc = context;
getConnection().queueCommand(
new RawCommand(finaldmc, "set exec-direction reverse"),
new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
@Override
public void handleSuccess() {
getConnection().queueCommand(finalcmd, new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
@Override
public void handleSuccess() {
getConnection().queueCommand(
new RawCommand(finaldmc, "set exec-direction forward"),
new DataRequestMonitor<MIInfo>(getExecutor(), rm));
}
});
}
});
// end temporary
}
public void canEnableReverseMode(ICommandControlDMContext context, DataRequestMonitor<Boolean> rm) {
rm.setData(fReverseSupported);
rm.done();
}
public void isReverseModeEnabled(ICommandControlDMContext context, DataRequestMonitor<Boolean> 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<MIInfo>(getExecutor(), rm) {
@Override
public void handleSuccess() {
setReverseModeEnabled(true);
rm.done();
}
});
} else {
getConnection().queueCommand(
new RawCommand(context, "stoprecord"), //$NON-NLS-1$
new DataRequestMonitor<MIInfo>(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));
}
} }

View file

@ -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<Boolean> rm);
void reverseResume(IExecutionDMContext context, RequestMonitor requestMonitor);
boolean isReverseStepping(IExecutionDMContext context);
void canReverseStep(IExecutionDMContext context, StepType stepType, DataRequestMonitor<Boolean> rm);
void reverseStep(IExecutionDMContext context, StepType stepType, RequestMonitor requestMonitor);
void canEnableReverseMode(ICommandControlDMContext context, DataRequestMonitor<Boolean> rm);
void isReverseModeEnabled(ICommandControlDMContext context, DataRequestMonitor<Boolean> rm);
void enableReverseMode(ICommandControlDMContext context, boolean enable, RequestMonitor rm);
}

View file

@ -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.debug.service.command.ICommandControlService;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch; 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.IGDBBackend;
import org.eclipse.cdt.dsf.gdb.service.SessionType; import org.eclipse.cdt.dsf.gdb.service.SessionType;
import org.eclipse.cdt.dsf.mi.service.IMIBackend; import org.eclipse.cdt.dsf.mi.service.IMIBackend;
@ -258,14 +259,14 @@ public class GDBControl_7_0 extends AbstractMIControl implements IGDBControl {
return true; return true;
} }
/* /**
* Start the program. * Start the program.
*/ */
public void start(GdbLaunch launch, final RequestMonitor requestMonitor) { public void start(GdbLaunch launch, final RequestMonitor requestMonitor) {
startOrRestart(launch, false, requestMonitor); startOrRestart(launch, false, requestMonitor);
} }
/* /**
* Before restarting the inferior, we must re-initialize its input/output streams * 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. * 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); startOrRestart(launch, true, requestMonitor);
} }
/* /**
* Insert breakpoint at entry if set, and start or restart the program. * 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) { protected void startOrRestart(final GdbLaunch launch, boolean restart, final RequestMonitor requestMonitor) {
if (fMIBackend.getIsAttachSession()) { if (fMIBackend.getIsAttachSession()) {
@ -307,7 +309,20 @@ public class GDBControl_7_0 extends AbstractMIControl implements IGDBControl {
return; return;
} }
final DataRequestMonitor<MIInfo> execMonitor = new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor); final DataRequestMonitor<MIInfo> execMonitor = new DataRequestMonitor<MIInfo>(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) { if (!stopInMain) {
// Just start the program. // 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. * This method creates a new inferior process object based on the current Pty or output stream.
*/ */
public void createInferiorProcess() { public void createInferiorProcess() {

View file

@ -265,9 +265,9 @@ public class MIRunControl extends AbstractDsfService implements IRunControl, ICa
// State flags // State flags
private boolean fSuspended = true; private boolean fSuspended = true;
private boolean fResumePending = false; protected boolean fResumePending = false;
private boolean fStepping = false; private boolean fStepping = false;
private boolean fTerminated = false; protected boolean fTerminated = false;
private StateChangeReason fStateChangeReason; private StateChangeReason fStateChangeReason;
private IExecutionDMContext fStateChangeTriggeringContext; private IExecutionDMContext fStateChangeTriggeringContext;
@ -316,6 +316,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl, ICa
} }
public CommandCache getCache() { return fMICommandCache; } public CommandCache getCache() { return fMICommandCache; }
public ICommandControlService getConnection() { return fConnection; }
public IMIExecutionDMContext createMIExecutionContext(IContainerDMContext container, int threadId) { public IMIExecutionDMContext createMIExecutionContext(IContainerDMContext container, int threadId) {
return new MIExecutionDMC(getSession().getId(), container, threadId); return new MIExecutionDMC(getSession().getId(), container, threadId);
@ -473,7 +474,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl, ICa
rm.done(); rm.done();
} }
private boolean doCanResume(IExecutionDMContext context) { protected boolean doCanResume(IExecutionDMContext context) {
return !fTerminated && isSuspended(context) && !fResumePending; return !fTerminated && isSuspended(context) && !fResumePending;
} }
@ -602,11 +603,11 @@ public class MIRunControl extends AbstractDsfService implements IRunControl, ICa
break; break;
case STEP_RETURN: case STEP_RETURN:
// The -exec-finish command operates on the selected stack frame, but here we always // 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. // context to use with the MI command.
// We get a local instance of the stack service because the stack service can be shut // 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 // 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); MIStack stackService = getServicesTracker().getService(MIStack.class);
if (stackService != null) { if (stackService != null) {
IFrameDMContext topFrameDmc = stackService.createFrameDMContext(dmc, 0); IFrameDMContext topFrameDmc = stackService.createFrameDMContext(dmc, 0);

View file

@ -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<MIInfo> {
public MIExecReverseContinue(IExecutionDMContext dmc) {
super(dmc, "-exec-continue"); //$NON-NLS-1$
}
}

View file

@ -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<MIInfo> {
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$
}
}

View file

@ -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<MIInfo> {
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$
}
}

View file

@ -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<MIInfo> {
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$
}
}

View file

@ -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<MIInfo> {
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$
}
}

View file

@ -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<MIInfo> {
public MIExecUncall(IFrameDMContext dmc) {
super(dmc, "-exec-finish"); //$NON-NLS-1$
}
}