mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 17:05:26 +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:
parent
51cf30f09d
commit
ea1399cf07
5 changed files with 239 additions and 70 deletions
|
@ -46,8 +46,10 @@ public class GdbDebuggerPage extends AbstractCDebuggerPage implements Observer {
|
|||
protected Text fGDBCommandText;
|
||||
protected Text fGDBInitText;
|
||||
protected Button fNonStopCheckBox;
|
||||
protected Button fReverseCheckBox;
|
||||
protected Button fVerboseModeButton;
|
||||
|
||||
|
||||
private IMILaunchConfigurationComponent fSolibBlock;
|
||||
private boolean fIsInitializing = false;
|
||||
|
||||
|
@ -69,6 +71,8 @@ public class GdbDebuggerPage extends AbstractCDebuggerPage implements Observer {
|
|||
IGDBLaunchConfigurationConstants.DEBUGGER_GDB_INIT_DEFAULT);
|
||||
configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP,
|
||||
IGDBLaunchConfigurationConstants.DEBUGGER_NON_STOP_DEFAULT);
|
||||
configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE,
|
||||
IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT);
|
||||
configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_VERBOSE_MODE,
|
||||
IGDBLaunchConfigurationConstants.DEBUGGER_VERBOSE_MODE_DEFAULT);
|
||||
|
||||
|
@ -95,6 +99,8 @@ public class GdbDebuggerPage extends AbstractCDebuggerPage implements Observer {
|
|||
String gdbCommand = IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT;
|
||||
String gdbInit = IGDBLaunchConfigurationConstants.DEBUGGER_GDB_INIT_DEFAULT;
|
||||
boolean nonStopMode = IGDBLaunchConfigurationConstants.DEBUGGER_NON_STOP_DEFAULT;
|
||||
boolean reverseEnabled = IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT;
|
||||
|
||||
boolean verboseMode = IGDBLaunchConfigurationConstants.DEBUGGER_VERBOSE_MODE_DEFAULT;
|
||||
|
||||
try {
|
||||
|
@ -116,6 +122,14 @@ public class GdbDebuggerPage extends AbstractCDebuggerPage implements Observer {
|
|||
}
|
||||
catch(CoreException e) {
|
||||
}
|
||||
|
||||
try {
|
||||
reverseEnabled = configuration.getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE,
|
||||
IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT);
|
||||
}
|
||||
catch(CoreException e) {
|
||||
}
|
||||
|
||||
try {
|
||||
verboseMode = configuration.getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_VERBOSE_MODE,
|
||||
IGDBLaunchConfigurationConstants.DEBUGGER_VERBOSE_MODE_DEFAULT );
|
||||
|
@ -128,6 +142,7 @@ public class GdbDebuggerPage extends AbstractCDebuggerPage implements Observer {
|
|||
fGDBCommandText.setText(gdbCommand);
|
||||
fGDBInitText.setText(gdbInit);
|
||||
fNonStopCheckBox.setSelection(nonStopMode);
|
||||
fReverseCheckBox.setSelection(reverseEnabled);
|
||||
fVerboseModeButton.setSelection(verboseMode);
|
||||
|
||||
setInitializing(false);
|
||||
|
@ -140,6 +155,8 @@ public class GdbDebuggerPage extends AbstractCDebuggerPage implements Observer {
|
|||
fGDBInitText.getText().trim());
|
||||
configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP,
|
||||
fNonStopCheckBox.getSelection());
|
||||
configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE,
|
||||
fReverseCheckBox.getSelection());
|
||||
configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_VERBOSE_MODE,
|
||||
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.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
|
@ -312,8 +339,10 @@ public class GdbDebuggerPage extends AbstractCDebuggerPage implements Observer {
|
|||
fNonStopCheckBox.setLayoutData(gd);
|
||||
gd = new GridData();
|
||||
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
|
||||
//
|
||||
fVerboseModeButton.setVisible(false);
|
||||
|
|
|
@ -25,6 +25,7 @@ GDBDebuggerPage.10=Shared Libraries
|
|||
GDBDebuggerPage.11=Protocol:
|
||||
GDBDebuggerPage.12=Default
|
||||
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.1=GDB Debugger Options
|
||||
StandardGDBDebuggerPage.2=Main
|
||||
|
|
|
@ -82,6 +82,12 @@ public class IGDBLaunchConfigurationConstants {
|
|||
*/
|
||||
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.
|
||||
*/
|
||||
|
@ -114,4 +120,10 @@ public class IGDBLaunchConfigurationConstants {
|
|||
* @since 1.1
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -184,7 +184,7 @@ public class GDBRunControl_7_0 extends MIRunControl implements IReverseRunContro
|
|||
public void handleSuccess() {
|
||||
getConnection().queueCommand(finalcmd, new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
public void handleSuccess() {
|
||||
public void handleCompleted() {
|
||||
getConnection().queueCommand(
|
||||
new RawCommand(finaldmc, "set exec-direction forward"),
|
||||
new DataRequestMonitor<MIInfo>(getExecutor(), rm));
|
||||
|
@ -266,7 +266,7 @@ public class GDBRunControl_7_0 extends MIRunControl implements IReverseRunContro
|
|||
public void handleSuccess() {
|
||||
getConnection().queueCommand(finalcmd, new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
public void handleSuccess() {
|
||||
public void handleCompleted() {
|
||||
getConnection().queueCommand(
|
||||
new RawCommand(finaldmc, "set exec-direction forward"),
|
||||
new DataRequestMonitor<MIInfo>(getExecutor(), rm));
|
||||
|
|
|
@ -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.command.ICommandControl;
|
||||
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.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.IReverseRunControl;
|
||||
import org.eclipse.cdt.dsf.gdb.service.SessionType;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMIBackend;
|
||||
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.MIInferiorTTYSet;
|
||||
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.service.DsfServiceEventHandler;
|
||||
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.cdt.utils.pty.PTY;
|
||||
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.
|
||||
* 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) {
|
||||
if (fMIBackend.getIsAttachSession()) {
|
||||
// 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;
|
||||
protected void startOrRestart(final GdbLaunch launch, boolean restart, RequestMonitor requestMonitor) {
|
||||
boolean tmpReverseEnabled = IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT;
|
||||
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) {
|
||||
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) {
|
||||
@Override
|
||||
public void handleSuccess() {
|
||||
DsfServicesTracker servicesTracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), getSession().getId());
|
||||
GDBRunControl_7_0 reverseService = servicesTracker.getService(GDBRunControl_7_0.class);
|
||||
servicesTracker.dispose();
|
||||
// When it is not an attach session, it gets a little more complicated
|
||||
// so let's use a sequence.
|
||||
getExecutor().execute(new Sequence(getExecutor(), requestMonitor) {
|
||||
IContainerDMContext fContainerDmc;
|
||||
MICommand<MIInfo> fExecCommand;
|
||||
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) {
|
||||
// When starting or restarting a program, reverse mode is automatically disabled
|
||||
reverseService.setReverseModeEnabled(false);
|
||||
}
|
||||
requestMonitor.done();
|
||||
}
|
||||
};
|
||||
|
||||
if (!stopInMain) {
|
||||
// Just start the program.
|
||||
queueCommand(execCommand, execMonitor);
|
||||
} else {
|
||||
String stopSymbol = null;
|
||||
try {
|
||||
stopSymbol = launch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT );
|
||||
} catch (CoreException e) {
|
||||
requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.CONFIGURATION_INVALID, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$
|
||||
requestMonitor.done();
|
||||
return;
|
||||
}
|
||||
|
||||
// Insert a breakpoint at the requested stop symbol.
|
||||
queueCommand(
|
||||
new MIBreakInsert(fControlDmc, true, false, null, 0, stopSymbol, 0),
|
||||
new DataRequestMonitor<MIBreakInsertInfo>(getExecutor(), requestMonitor) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
// After the break-insert is done, execute the -exec-run or -exec-continue command.
|
||||
queueCommand(execCommand, execMonitor);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (fMIBackend.getSessionType() == SessionType.REMOTE) {
|
||||
// Restart does not apply to remote sessions
|
||||
//
|
||||
// When doing remote debugging, we use -exec-continue instead of -exec-run
|
||||
fExecCommand = new MIExecContinue(fContainerDmc);
|
||||
} else {
|
||||
fExecCommand = new MIExecRun(fContainerDmc, new String[0]);
|
||||
}
|
||||
rm.done();
|
||||
}},
|
||||
/*
|
||||
* If the user requested a 'stopOnMain', let's set the temporary breakpoint
|
||||
* where the user specified.
|
||||
*/
|
||||
new Step() {
|
||||
@Override
|
||||
public void execute(final RequestMonitor rm) {
|
||||
boolean userRequestedStop = false;
|
||||
try {
|
||||
userRequestedStop = launch.getLaunchConfiguration().getAttribute(
|
||||
ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN,
|
||||
false);
|
||||
} catch (CoreException e) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot retrieve stop at entry point boolean", e)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue