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

[258284] This patch allows the user to enable reverse debugging from the launch. I got it all to work except for one case: if the user turns off StopOnMain, but actually has a real breakpoint on main,

then that breakpoint will be ignored when having Reverse on in the launch.
This commit is contained in:
Marc Khouzam 2009-02-09 21:34:16 +00:00
parent 51cf30f09d
commit ea1399cf07
5 changed files with 239 additions and 70 deletions

View file

@ -46,8 +46,10 @@ public class GdbDebuggerPage extends AbstractCDebuggerPage implements Observer {
protected Text fGDBCommandText; protected Text fGDBCommandText;
protected Text fGDBInitText; protected Text fGDBInitText;
protected Button fNonStopCheckBox; protected Button fNonStopCheckBox;
protected Button fReverseCheckBox;
protected Button fVerboseModeButton; protected Button fVerboseModeButton;
private IMILaunchConfigurationComponent fSolibBlock; private IMILaunchConfigurationComponent fSolibBlock;
private boolean fIsInitializing = false; private boolean fIsInitializing = false;
@ -69,6 +71,8 @@ public class GdbDebuggerPage extends AbstractCDebuggerPage implements Observer {
IGDBLaunchConfigurationConstants.DEBUGGER_GDB_INIT_DEFAULT); IGDBLaunchConfigurationConstants.DEBUGGER_GDB_INIT_DEFAULT);
configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP, configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP,
IGDBLaunchConfigurationConstants.DEBUGGER_NON_STOP_DEFAULT); IGDBLaunchConfigurationConstants.DEBUGGER_NON_STOP_DEFAULT);
configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE,
IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT);
configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_VERBOSE_MODE, configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_VERBOSE_MODE,
IGDBLaunchConfigurationConstants.DEBUGGER_VERBOSE_MODE_DEFAULT); IGDBLaunchConfigurationConstants.DEBUGGER_VERBOSE_MODE_DEFAULT);
@ -95,6 +99,8 @@ public class GdbDebuggerPage extends AbstractCDebuggerPage implements Observer {
String gdbCommand = IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT; String gdbCommand = IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT;
String gdbInit = IGDBLaunchConfigurationConstants.DEBUGGER_GDB_INIT_DEFAULT; String gdbInit = IGDBLaunchConfigurationConstants.DEBUGGER_GDB_INIT_DEFAULT;
boolean nonStopMode = IGDBLaunchConfigurationConstants.DEBUGGER_NON_STOP_DEFAULT; boolean nonStopMode = IGDBLaunchConfigurationConstants.DEBUGGER_NON_STOP_DEFAULT;
boolean reverseEnabled = IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT;
boolean verboseMode = IGDBLaunchConfigurationConstants.DEBUGGER_VERBOSE_MODE_DEFAULT; boolean verboseMode = IGDBLaunchConfigurationConstants.DEBUGGER_VERBOSE_MODE_DEFAULT;
try { try {
@ -116,6 +122,14 @@ public class GdbDebuggerPage extends AbstractCDebuggerPage implements Observer {
} }
catch(CoreException e) { catch(CoreException e) {
} }
try {
reverseEnabled = configuration.getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE,
IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT);
}
catch(CoreException e) {
}
try { try {
verboseMode = configuration.getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_VERBOSE_MODE, verboseMode = configuration.getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_VERBOSE_MODE,
IGDBLaunchConfigurationConstants.DEBUGGER_VERBOSE_MODE_DEFAULT ); IGDBLaunchConfigurationConstants.DEBUGGER_VERBOSE_MODE_DEFAULT );
@ -128,6 +142,7 @@ public class GdbDebuggerPage extends AbstractCDebuggerPage implements Observer {
fGDBCommandText.setText(gdbCommand); fGDBCommandText.setText(gdbCommand);
fGDBInitText.setText(gdbInit); fGDBInitText.setText(gdbInit);
fNonStopCheckBox.setSelection(nonStopMode); fNonStopCheckBox.setSelection(nonStopMode);
fReverseCheckBox.setSelection(reverseEnabled);
fVerboseModeButton.setSelection(verboseMode); fVerboseModeButton.setSelection(verboseMode);
setInitializing(false); setInitializing(false);
@ -140,6 +155,8 @@ public class GdbDebuggerPage extends AbstractCDebuggerPage implements Observer {
fGDBInitText.getText().trim()); fGDBInitText.getText().trim());
configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP, configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP,
fNonStopCheckBox.getSelection()); fNonStopCheckBox.getSelection());
configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE,
fReverseCheckBox.getSelection());
configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_VERBOSE_MODE, configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_VERBOSE_MODE,
fVerboseModeButton.getSelection() ); fVerboseModeButton.getSelection() );
@ -291,6 +308,16 @@ public class GdbDebuggerPage extends AbstractCDebuggerPage implements Observer {
} }
}); });
// TODO: Ideally, this field should be disabled if the back-end doesn't support reverse debugging
// TODO: Find a way to determine if reverse is supported (i.e. find the GDB version) then grey out the check box if necessary
fReverseCheckBox = ControlFactory.createCheckBox(subComp, LaunchUIMessages.getString("GDBDebuggerPage.14")); //$NON-NLS-1$
fReverseCheckBox.addSelectionListener( new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
updateLaunchConfigurationDialog();
}
});
fVerboseModeButton = ControlFactory.createCheckBox( subComp, LaunchUIMessages.getString( "StandardGDBDebuggerPage.13" ) ); //$NON-NLS-1$ fVerboseModeButton = ControlFactory.createCheckBox( subComp, LaunchUIMessages.getString( "StandardGDBDebuggerPage.13" ) ); //$NON-NLS-1$
fVerboseModeButton.addSelectionListener(new SelectionAdapter() { fVerboseModeButton.addSelectionListener(new SelectionAdapter() {
@Override @Override
@ -312,8 +339,10 @@ public class GdbDebuggerPage extends AbstractCDebuggerPage implements Observer {
fNonStopCheckBox.setLayoutData(gd); fNonStopCheckBox.setLayoutData(gd);
gd = new GridData(); gd = new GridData();
gd.horizontalSpan = 3; gd.horizontalSpan = 3;
fVerboseModeButton.setLayoutData(gd); fReverseCheckBox.setLayoutData(gd);
gd = new GridData();
gd.horizontalSpan = 3;
fVerboseModeButton.setLayoutData(gd);
// Grayed out until bug 249227 is resolved // Grayed out until bug 249227 is resolved
// //
fVerboseModeButton.setVisible(false); fVerboseModeButton.setVisible(false);

View file

@ -25,6 +25,7 @@ GDBDebuggerPage.10=Shared Libraries
GDBDebuggerPage.11=Protocol: GDBDebuggerPage.11=Protocol:
GDBDebuggerPage.12=Default GDBDebuggerPage.12=Default
GDBDebuggerPage.13=Non-stop mode (Note: Requires non-stop GDB) GDBDebuggerPage.13=Non-stop mode (Note: Requires non-stop GDB)
GDBDebuggerPage.14=Enable Reverse Debugging at startup (Note: Requires Reverse GDB)
StandardGDBDebuggerPage.0=Debugger executable must be specified. StandardGDBDebuggerPage.0=Debugger executable must be specified.
StandardGDBDebuggerPage.1=GDB Debugger Options StandardGDBDebuggerPage.1=GDB Debugger Options
StandardGDBDebuggerPage.2=Main StandardGDBDebuggerPage.2=Main

View file

@ -82,6 +82,12 @@ public class IGDBLaunchConfigurationConstants {
*/ */
public static final String ATTR_DEBUGGER_VERBOSE_MODE = GdbPlugin.PLUGIN_ID + ".verboseMode"; //$NON-NLS-1$ public static final String ATTR_DEBUGGER_VERBOSE_MODE = GdbPlugin.PLUGIN_ID + ".verboseMode"; //$NON-NLS-1$
/**
* Launch configuration attribute key. Boolean value to enable reverse debugging at launch time.
* @since 2.0
*/
public static final String ATTR_DEBUGGER_REVERSE = GdbPlugin.PLUGIN_ID + ".REVERSE"; //$NON-NLS-1$
/** /**
* Launch configuration attribute value. The key is ATTR_DEBUG_NAME. * Launch configuration attribute value. The key is ATTR_DEBUG_NAME.
*/ */
@ -114,4 +120,10 @@ public class IGDBLaunchConfigurationConstants {
* @since 1.1 * @since 1.1
*/ */
public static final boolean DEBUGGER_VERBOSE_MODE_DEFAULT = false; public static final boolean DEBUGGER_VERBOSE_MODE_DEFAULT = false;
/**
* Launch configuration attribute value. The key is ATTR_DEBUGGER_REVERSE.
* @since 2.0
*/
public static final boolean DEBUGGER_REVERSE_DEFAULT = false;
} }

View file

@ -184,7 +184,7 @@ public class GDBRunControl_7_0 extends MIRunControl implements IReverseRunContro
public void handleSuccess() { public void handleSuccess() {
getConnection().queueCommand(finalcmd, new DataRequestMonitor<MIInfo>(getExecutor(), rm) { getConnection().queueCommand(finalcmd, new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
@Override @Override
public void handleSuccess() { public void handleCompleted() {
getConnection().queueCommand( getConnection().queueCommand(
new RawCommand(finaldmc, "set exec-direction forward"), new RawCommand(finaldmc, "set exec-direction forward"),
new DataRequestMonitor<MIInfo>(getExecutor(), rm)); new DataRequestMonitor<MIInfo>(getExecutor(), rm));
@ -266,7 +266,7 @@ public class GDBRunControl_7_0 extends MIRunControl implements IReverseRunContro
public void handleSuccess() { public void handleSuccess() {
getConnection().queueCommand(finalcmd, new DataRequestMonitor<MIInfo>(getExecutor(), rm) { getConnection().queueCommand(finalcmd, new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
@Override @Override
public void handleSuccess() { public void handleCompleted() {
getConnection().queueCommand( getConnection().queueCommand(
new RawCommand(finaldmc, "set exec-direction forward"), new RawCommand(finaldmc, "set exec-direction forward"),
new DataRequestMonitor<MIInfo>(getExecutor(), rm)); new DataRequestMonitor<MIInfo>(getExecutor(), rm));

View file

@ -28,10 +28,12 @@ import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControl; 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.IGDBLaunchConfigurationConstants;
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.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.IReverseRunControl;
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;
import org.eclipse.cdt.dsf.mi.service.IMIProcesses; import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
@ -51,9 +53,9 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecRun;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBExit; import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBExit;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIInferiorTTYSet; import org.eclipse.cdt.dsf.mi.service.command.commands.MIInferiorTTYSet;
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo; import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakpoint;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession; import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.utils.pty.PTY; import org.eclipse.cdt.utils.pty.PTY;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
@ -277,77 +279,202 @@ public class GDBControl_7_0 extends AbstractMIControl implements IGDBControl {
/** /**
* 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. * Note that restart does not apply to remote or attach sessions.
*
* If we want to enable Reverse debugging from the start of the program we do the following:
* attachSession => enable reverse
* else => set temp bp on main, run, enable reverse, continue if bp on main was not requested by user
*/ */
protected void startOrRestart(final GdbLaunch launch, boolean restart, final RequestMonitor requestMonitor) { protected void startOrRestart(final GdbLaunch launch, boolean restart, RequestMonitor requestMonitor) {
if (fMIBackend.getIsAttachSession()) { boolean tmpReverseEnabled = IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT;
// When attaching to a running process, we do not need to set a breakpoint or
// start the program; it is left up to the user.
requestMonitor.done();
return;
}
DsfServicesTracker servicesTracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), getSession().getId());
IMIProcesses procService = servicesTracker.getService(IMIProcesses.class);
servicesTracker.dispose();
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, MIProcesses.UNIQUE_GROUP_ID);
final IContainerDMContext containerDmc = procService.createContainerContext(procDmc, MIProcesses.UNIQUE_GROUP_ID);
final MICommand<MIInfo> execCommand;
if (fMIBackend.getSessionType() == SessionType.REMOTE) {
// When doing remote debugging, we use -exec-continue instead of -exec-run
execCommand = new MIExecContinue(containerDmc);
} else {
execCommand = new MIExecRun(containerDmc, new String[0]);
}
boolean stopInMain = false;
try { try {
stopInMain = launch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, false ); tmpReverseEnabled = launch.getLaunchConfiguration().getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE,
IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT);
} catch (CoreException e) { } catch (CoreException e) {
requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot retrieve stop at entry point boolean", e)); //$NON-NLS-1$
requestMonitor.done();
return;
} }
final boolean reverseEnabled = tmpReverseEnabled;
if (fMIBackend.getIsAttachSession()) {
// Restart does not apply to attach sessions.
//
// When attaching to a running process, we do not need to set a breakpoint or
// start the program; it is left up to the user.
// We only need to turn on Reverse Debugging if requested.
if (reverseEnabled) {
IReverseRunControl reverseService = getServicesTracker().getService(IReverseRunControl.class);
if (reverseService != null) {
reverseService.enableReverseMode(fControlDmc, true, requestMonitor);
return;
}
}
requestMonitor.done();
return;
}
final DataRequestMonitor<MIInfo> execMonitor = new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor) { // When it is not an attach session, it gets a little more complicated
@Override // so let's use a sequence.
public void handleSuccess() { getExecutor().execute(new Sequence(getExecutor(), requestMonitor) {
DsfServicesTracker servicesTracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), getSession().getId()); IContainerDMContext fContainerDmc;
GDBRunControl_7_0 reverseService = servicesTracker.getService(GDBRunControl_7_0.class); MICommand<MIInfo> fExecCommand;
servicesTracker.dispose(); String fUserStopSymbol = null;
MIBreakpoint fUserBreakpoint = null;
boolean fUserBreakpointIsOnMain = false;
Step[] fSteps = new Step[] {
/*
* Figure out if we should use 'exec-continue' or '-exec-run'.
*/
new Step() {
@Override
public void execute(RequestMonitor rm) {
IMIProcesses procService = getServicesTracker().getService(IMIProcesses.class);
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, MIProcesses.UNIQUE_GROUP_ID);
fContainerDmc = procService.createContainerContext(procDmc, MIProcesses.UNIQUE_GROUP_ID);
if (reverseService != null) { if (fMIBackend.getSessionType() == SessionType.REMOTE) {
// When starting or restarting a program, reverse mode is automatically disabled // Restart does not apply to remote sessions
reverseService.setReverseModeEnabled(false); //
} // When doing remote debugging, we use -exec-continue instead of -exec-run
requestMonitor.done(); fExecCommand = new MIExecContinue(fContainerDmc);
} } else {
}; fExecCommand = new MIExecRun(fContainerDmc, new String[0]);
}
if (!stopInMain) { rm.done();
// Just start the program. }},
queueCommand(execCommand, execMonitor); /*
} else { * If the user requested a 'stopOnMain', let's set the temporary breakpoint
String stopSymbol = null; * where the user specified.
try { */
stopSymbol = launch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT ); new Step() {
} catch (CoreException e) { @Override
requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.CONFIGURATION_INVALID, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$ public void execute(final RequestMonitor rm) {
requestMonitor.done(); boolean userRequestedStop = false;
return; try {
} userRequestedStop = launch.getLaunchConfiguration().getAttribute(
ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN,
// Insert a breakpoint at the requested stop symbol. false);
queueCommand( } catch (CoreException e) {
new MIBreakInsert(fControlDmc, true, false, null, 0, stopSymbol, 0), rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot retrieve stop at entry point boolean", e)); //$NON-NLS-1$
new DataRequestMonitor<MIBreakInsertInfo>(getExecutor(), requestMonitor) { rm.done();
@Override return;
protected void handleSuccess() { }
// After the break-insert is done, execute the -exec-run or -exec-continue command.
queueCommand(execCommand, execMonitor); if (userRequestedStop) {
} try {
}); fUserStopSymbol = launch.getLaunchConfiguration().getAttribute(
} ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL,
ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT);
} catch (CoreException e) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.CONFIGURATION_INVALID, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$
rm.done();
return;
}
queueCommand(new MIBreakInsert(fControlDmc, true, false, null, 0, fUserStopSymbol, 0),
new DataRequestMonitor<MIBreakInsertInfo>(getExecutor(), rm) {
@Override
public void handleSuccess() {
if (getData() != null) {
MIBreakpoint[] breakpoints = getData().getMIBreakpoints();
if (breakpoints.length > 0) {
fUserBreakpoint = breakpoints[0];
}
}
rm.done();
}
});
} else {
rm.done();
}
}},
/*
* If reverse debugging, set a breakpoint on main to be able to enable reverse
* as early as possible.
* If the user has requested a stop at the same point, we could skip this breakpoint
* however, we have to first set it to find out! So, we just leave it.
*/
new Step() {
@Override
public void execute(final RequestMonitor rm) {
if (reverseEnabled) {
queueCommand(new MIBreakInsert(fControlDmc, true, false, null, 0,
ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT, 0),
new DataRequestMonitor<MIBreakInsertInfo>(getExecutor(), rm) {
@Override
public void handleSuccess() {
if (getData() != null) {
MIBreakpoint[] breakpoints = getData().getMIBreakpoints();
if (breakpoints.length > 0 && fUserBreakpoint != null) {
fUserBreakpointIsOnMain = breakpoints[0].getAddress().equals(fUserBreakpoint.getAddress());
}
}
rm.done();
}
});
} else {
rm.done();
}
}},
/*
* Now, run the program.
*/
new Step() {
@Override
public void execute(RequestMonitor rm) {
queueCommand(fExecCommand, new DataRequestMonitor<MIInfo>(getExecutor(), rm));
}},
/*
* In case of a restart, reverse debugging should be marked as off here because
* GDB will have turned it off. We may turn it back on after.
*/
new Step() {
@Override
public void execute(RequestMonitor rm) {
// Although it only makes sense for a restart, it doesn't hurt
// do to it all the time.
GDBRunControl_7_0 reverseService = getServicesTracker().getService(GDBRunControl_7_0.class);
if (reverseService != null) {
reverseService.setReverseModeEnabled(false);
}
rm.done();
}},
/*
* Since we have started the program, we can turn on reverse debugging if needed
*/
new Step() {
@Override
public void execute(RequestMonitor rm) {
if (reverseEnabled) {
IReverseRunControl reverseService = getServicesTracker().getService(IReverseRunControl.class);
if (reverseService != null) {
reverseService.enableReverseMode(fControlDmc, true, rm);
return;
}
}
rm.done();
}},
/*
* Finally, if we are enabling reverse, and the userSymbolStop is not on main,
* we should do a continue because we are currently stopped on main but that
* is not what the user requested
*/
new Step() {
@Override
public void execute(RequestMonitor rm) {
if (reverseEnabled && !fUserBreakpointIsOnMain) {
queueCommand(new MIExecContinue(fContainerDmc),
new DataRequestMonitor<MIInfo>(getExecutor(), rm));
} else {
rm.done();
}
}},
};
@Override
public Step[] getSteps() {
return fSteps;
}
});
} }
/** /**