1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-22 06:02:11 +02:00

Bug 511243 - MI async mode shall not be activated for all cases when

using GDB 7.12

This solution makes the following changes:

* With GDB 7.12, use async mode as long as the Full GDB console is
supported or if the launch is configured for Non stop mode

* with GDB 7.12, don't always use MI to interrupt the service, use the
CLI when the async mode is off

Change-Id: I92c466e028b400f9054298739cd80efac18bd03a
This commit is contained in:
Alvaro Sanchez-Leon 2017-01-27 15:52:20 -05:00 committed by Gerrit Code Review @ Eclipse.org
parent 7d0117d24e
commit f6f53aa705
3 changed files with 100 additions and 59 deletions

View file

@ -19,6 +19,7 @@ import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitorWithProgress; import org.eclipse.cdt.dsf.concurrent.RequestMonitorWithProgress;
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants; 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.service.IGDBBackend;
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl; import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory; import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
@ -36,6 +37,7 @@ public class FinalLaunchSequence_7_12 extends FinalLaunchSequence_7_7 {
private IGDBControl fCommandControl; private IGDBControl fCommandControl;
private CommandFactory fCommandFactory; private CommandFactory fCommandFactory;
private Map<String, Object> fAttributes; private Map<String, Object> fAttributes;
private IGDBBackend fGdbBackEnd;
public FinalLaunchSequence_7_12(DsfSession session, Map<String, Object> attributes, public FinalLaunchSequence_7_12(DsfSession session, Map<String, Object> attributes,
RequestMonitorWithProgress rm) { RequestMonitorWithProgress rm) {
@ -76,6 +78,8 @@ public class FinalLaunchSequence_7_12 extends FinalLaunchSequence_7_7 {
DsfServicesTracker tracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), DsfServicesTracker tracker = new DsfServicesTracker(GdbPlugin.getBundleContext(),
getSession().getId()); getSession().getId());
fCommandControl = tracker.getService(IGDBControl.class); fCommandControl = tracker.getService(IGDBControl.class);
fGdbBackEnd = tracker.getService(IGDBBackend.class);
tracker.dispose(); tracker.dispose();
if (fCommandControl == null) { if (fCommandControl == null) {
@ -90,20 +94,37 @@ public class FinalLaunchSequence_7_12 extends FinalLaunchSequence_7_7 {
} }
private boolean isNonStop() {
boolean isNonStop = CDebugUtils.getAttribute(fAttributes,
IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP,
LaunchUtils.getIsNonStopModeDefault());
return isNonStop;
}
@Execute @Execute
public void stepSetTargetAsync(RequestMonitor requestMonitor) { public void stepSetTargetAsync(RequestMonitor requestMonitor) {
// Use target async when interfacing with GDB 7.12 or higher if (fCommandControl == null || fGdbBackEnd == null) {
// this will allow us to use the new enhanced GDB Full CLI console requestMonitor.done();
return;
}
// Use target async for non-stop mode or when the
// Full GDB CLI console is being used.
// Otherwise Explicitly set target-async to off
boolean asyncOn = false;
if (isNonStop() || fGdbBackEnd.isFullGdbConsoleSupported()) {
asyncOn = true;
}
fCommandControl.queueCommand( fCommandControl.queueCommand(
fCommandFactory.createMIGDBSetTargetAsync(fCommandControl.getContext(), true), fCommandFactory.createMIGDBSetTargetAsync(fCommandControl.getContext(), asyncOn),
new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor) { new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor) {
@Override @Override
protected void handleError() { protected void handleError() {
// We should only be calling this for GDB >= 7.12, // Accept errors for older GDBs
// but just in case, accept errors for older GDBs requestMonitor.done();
requestMonitor.done(); }
} });
});
} }
/** /**
@ -127,15 +148,13 @@ public class FinalLaunchSequence_7_12 extends FinalLaunchSequence_7_7 {
@Override @Override
@Execute @Execute
public void stepSetNonStop(final RequestMonitor requestMonitor) { public void stepSetNonStop(final RequestMonitor requestMonitor) {
boolean isNonStop = CDebugUtils.getAttribute(fAttributes, if (isNonStop()) {
IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP,
LaunchUtils.getIsNonStopModeDefault());
if (isNonStop) {
// GDBs that don't support non-stop don't allow you to set it to false. // GDBs that don't support non-stop don't allow you to set it to false.
// We really should set it to false when GDB supports it though. // We really should set it to false when GDB supports it though.
// Something to fix later. // Something to fix later.
// Note that disabling pagination is taken care of elsewhere // Note: The base class is setting pagination to off, this is only necessary when
// using the Full GDB console (The basic console is started in MI mode and does not paginate).
// When the Full GDB console is used, pagination is set to off when GDB is started.
fCommandControl.queueCommand( fCommandControl.queueCommand(
fCommandFactory.createMIGDBSetNonStop(fCommandControl.getContext(), true), fCommandFactory.createMIGDBSetNonStop(fCommandControl.getContext(), true),
new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor)); new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor));

View file

@ -43,6 +43,7 @@ import org.eclipse.core.runtime.jobs.Job;
public class GDBRunControl_7_12 extends GDBRunControl_7_10 { public class GDBRunControl_7_12 extends GDBRunControl_7_10 {
private IMICommandControl fCommandControl; private IMICommandControl fCommandControl;
private CommandFactory fCommandFactory; private CommandFactory fCommandFactory;
private IGDBBackend fGDBBackEnd;
private Map<String, EnableReverseAtLocOperation> fBpIdToReverseOpMap = new HashMap<>(); private Map<String, EnableReverseAtLocOperation> fBpIdToReverseOpMap = new HashMap<>();
public GDBRunControl_7_12(DsfSession session) { public GDBRunControl_7_12(DsfSession session) {
@ -61,6 +62,8 @@ public class GDBRunControl_7_12 extends GDBRunControl_7_10 {
private void doInitialize(final RequestMonitor rm) { private void doInitialize(final RequestMonitor rm) {
fCommandControl = getServicesTracker().getService(IMICommandControl.class); fCommandControl = getServicesTracker().getService(IMICommandControl.class);
fGDBBackEnd = getServicesTracker().getService(IGDBBackend.class);
fCommandFactory = fCommandControl.getCommandFactory(); fCommandFactory = fCommandControl.getCommandFactory();
register(new String[]{ GDBRunControl_7_12.class.getName() }, register(new String[]{ GDBRunControl_7_12.class.getName() },
@ -87,32 +90,48 @@ public class GDBRunControl_7_12 extends GDBRunControl_7_10 {
} }
private void doSuspend(IExecutionDMContext context, final RequestMonitor rm) { private void doSuspend(IExecutionDMContext context, final RequestMonitor rm) {
// Start the job before sending the interrupt command // We use the MI interrupt command when working in async mode.
// to make sure we don't miss the *stopped event // Since this run control service is specifically for all-stop mode,
final MonitorSuspendJob monitorJob = new MonitorSuspendJob(0, rm); // the only possibility to be running asynchronously is if the Full GDB console
fCommandControl.queueCommand(fCommandFactory.createMIExecInterrupt(context), // is being used.
new ImmediateDataRequestMonitor<MIInfo>() { if (fGDBBackEnd.isFullGdbConsoleSupported()) {
@Override // Start the job before sending the interrupt command
protected void handleSuccess() { // to make sure we don't miss the *stopped event
// Nothing to do in the case of success, the monitoring job final MonitorSuspendJob monitorJob = new MonitorSuspendJob(0, rm);
// will take care of completing the RM once it gets the fCommandControl.queueCommand(fCommandFactory.createMIExecInterrupt(context),
// *stopped event. new ImmediateDataRequestMonitor<MIInfo>() {
} @Override
protected void handleSuccess() {
// Nothing to do in the case of success, the monitoring job
// will take care of completing the RM once it gets the
// *stopped event.
}
@Override @Override
protected void handleFailure() { protected void handleFailure() {
// In case of failure, we must cancel the monitoring job // In case of failure, we must cancel the monitoring job
// and indicate the failure in the rm. // and indicate the failure in the rm.
monitorJob.cleanAndCancel(); monitorJob.cleanAndCancel();
rm.done(getStatus()); rm.done(getStatus());
} }
}); });
} else {
// Asynchronous mode is off
super.suspend(context, rm);
}
} }
@Override @Override
public boolean isTargetAcceptingCommands() { public boolean isTargetAcceptingCommands() {
// Async mode is on when running with GDB 7.12 or higher // We shall directly return true if the async mode is ON,
return true; // Since this run control service is specifically for all-stop mode,
// The only possibility to be running asynchronously is if the Full GDB console
// is being used.
if (fGDBBackEnd.isFullGdbConsoleSupported()) {
return true;
}
return super.isTargetAcceptingCommands();
} }
/** /**

View file

@ -15,6 +15,7 @@ import java.util.Map;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor; import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitorWithProgress; import org.eclipse.cdt.dsf.concurrent.RequestMonitorWithProgress;
import org.eclipse.cdt.dsf.gdb.service.IGDBBackend;
import org.eclipse.cdt.dsf.mi.service.IMICommandControl; import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
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.DsfServicesTracker; import org.eclipse.cdt.dsf.service.DsfServicesTracker;
@ -51,27 +52,29 @@ public class GDBJtagDSFFinalLaunchSequence_7_12 extends GDBJtagDSFFinalLaunchSeq
@Execute @Execute
public void stepSetTargetAsync(RequestMonitor rm) { public void stepSetTargetAsync(RequestMonitor rm) {
DsfServicesTracker tracker = new DsfServicesTracker(Activator.getBundleContext(), // Processing this request after sourcing the gdbinit file to make sure the user
getSession().getId()); // cannot change this behavior
IMICommandControl commandControl = tracker.getService(IMICommandControl.class); DsfServicesTracker tracker = new DsfServicesTracker(Activator.getBundleContext(),
tracker.dispose(); getSession().getId());
IMICommandControl commandControl = tracker.getService(IMICommandControl.class);
IGDBBackend gdbBackEnd = tracker.getService(IGDBBackend.class);
tracker.dispose();
if (commandControl != null) { if (commandControl != null && gdbBackEnd != null) {
// Use target async when interfacing with GDB 7.12 or higher // Use target async when interfacing with the full GDB console (i.e. minimum GDB version 7.12)
// this will allow us to use the new enhanced GDB Full CLI console // otherwise explicitly set it to off.
commandControl.queueCommand( commandControl.queueCommand(
commandControl.getCommandFactory().createMIGDBSetTargetAsync(commandControl.getContext(), true), commandControl.getCommandFactory().createMIGDBSetTargetAsync(commandControl.getContext(), gdbBackEnd.isFullGdbConsoleSupported()),
new DataRequestMonitor<MIInfo>(getExecutor(), rm) { new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
@Override @Override
protected void handleError() { protected void handleError() {
// We should only be calling this for GDB >= 7.12, // Accept errors for older GDBs
// but just in case, accept errors for older GDBs rm.done();
rm.done(); }
} });
}); } else {
} else { // Should not happen
// Should never happen but accept errors in this case rm.done();
rm.done(); }
}
} }
} }