mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-22 14:12:10 +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:
parent
7d0117d24e
commit
f6f53aa705
3 changed files with 100 additions and 59 deletions
|
@ -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));
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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();
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue