1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-01 06:05:24 +02:00

Bug 478740: Improve overriding of GDBProcesses service

This also propagates the fix to Bug 487144 to GDB 7.10, which we had
missed.

Change-Id: I1b1819d40a43e6667d2e0a0fdb4045b1a000a086
This commit is contained in:
Marc Khouzam 2016-03-05 05:16:53 -05:00 committed by Gerrit Code Review @ Eclipse.org
parent 1f3ff86ea0
commit 219cf56e7f
3 changed files with 71 additions and 253 deletions

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2008, 2015 Ericsson and others. * Copyright (c) 2008, 2016 Ericsson and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -1156,24 +1156,7 @@ public class GDBProcesses_7_0 extends AbstractDsfService
new Step() { new Step() {
@Override @Override
public void execute(RequestMonitor rm) { public void execute(RequestMonitor rm) {
IReverseRunControl reverseService = getServicesTracker().getService(IReverseRunControl.class); doReverseDebugStep(procCtx, rm);
if (reverseService != null) {
ILaunch launch = procCtx.getAdapter(ILaunch.class);
if (launch != null) {
try {
boolean reverseEnabled =
launch.getLaunchConfiguration().getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE,
IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT);
if (reverseEnabled) {
reverseService.enableReverseMode(fCommandControl.getContext(), true, rm);
return;
}
} catch (CoreException e) {
// Ignore, just don't set reverse
}
}
}
rm.done();
} }
}, },
}; };
@ -1186,6 +1169,29 @@ public class GDBProcesses_7_0 extends AbstractDsfService
} }
} }
/** @since 5.0 */
protected void doReverseDebugStep(final IProcessDMContext procCtx, RequestMonitor rm) {
// Turn on reverse debugging if it was enabled as a launch option
IReverseRunControl reverseService = getServicesTracker().getService(IReverseRunControl.class);
if (reverseService != null) {
ILaunch launch = procCtx.getAdapter(ILaunch.class);
if (launch != null) {
try {
boolean reverseEnabled =
launch.getLaunchConfiguration().getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE,
IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT);
if (reverseEnabled) {
reverseService.enableReverseMode(fCommandControl.getContext(), true, rm);
return;
}
} catch (CoreException e) {
// Ignore, just don't set reverse
}
}
}
rm.done();
}
/** @since 4.0 */ /** @since 4.0 */
protected boolean doCanDetachDebuggerFromProcess() { protected boolean doCanDetachDebuggerFromProcess() {
return fNumConnected > 0; return fNumConnected > 0;

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2015 Intel Corporation and others. * Copyright (c) 2015, 2016 Intel Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -10,37 +10,19 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service; package org.eclipse.cdt.dsf.gdb.service;
import java.util.Hashtable;
import java.util.Map; import java.util.Map;
import org.eclipse.cdt.debug.core.model.IChangeReverseMethodHandler.ReverseTraceMethod; import org.eclipse.cdt.debug.core.model.IChangeReverseMethodHandler.ReverseTraceMethod;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfExecutor; import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
import org.eclipse.cdt.dsf.concurrent.ImmediateDataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor; import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.concurrent.Sequence; import org.eclipse.cdt.dsf.concurrent.Sequence;
import org.eclipse.cdt.dsf.datamodel.DMContexts; import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IMultiDetach;
import org.eclipse.cdt.dsf.debug.service.IMultiTerminate;
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext;
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.ICommandControlService.ICommandControlDMContext; import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants; import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants; import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
import org.eclipse.cdt.dsf.mi.service.IMIProcessDMContext;
import org.eclipse.cdt.dsf.mi.service.IMIRunControl;
import org.eclipse.cdt.dsf.mi.service.IMIRunControl.MIRunMode;
import org.eclipse.cdt.dsf.mi.service.MIBreakpointsManager;
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
import org.eclipse.cdt.dsf.mi.service.command.output.MIAddInferiorInfo;
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.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
@ -55,44 +37,10 @@ import org.eclipse.debug.core.ILaunch;
*/ */
public class GDBProcesses_7_10 extends GDBProcesses_7_4 { public class GDBProcesses_7_10 extends GDBProcesses_7_4 {
private CommandFactory fCommandFactory;
private IGDBControl fCommandControl;
public GDBProcesses_7_10(DsfSession session) { public GDBProcesses_7_10(DsfSession session) {
super(session); super(session);
} }
@Override
public void initialize(final RequestMonitor requestMonitor) {
super.initialize(new ImmediateRequestMonitor(requestMonitor) {
@Override
protected void handleSuccess() {
doInitialize(requestMonitor);
}
});
}
/**
* This method initializes this service after our superclass's initialize()
* method succeeds.
*
* @param requestMonitor
* The call-back object to notify when this service's
* initialization is done.
*/
private void doInitialize(RequestMonitor requestMonitor) {
register(new String[]{ IMultiDetach.class.getName(), IMultiTerminate.class.getName() }, new Hashtable<String,String>());
fCommandControl = getServicesTracker().getService(IGDBControl.class);
fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory();
requestMonitor.done();
}
@Override
public void attachDebuggerToProcess(IProcessDMContext procCtx, DataRequestMonitor<IDMContext> rm) {
attachDebuggerToProcess(procCtx, null, rm);
}
@Override @Override
protected Sequence getStartOrRestartProcessSequence(DsfExecutor executor, IContainerDMContext containerDmc, protected Sequence getStartOrRestartProcessSequence(DsfExecutor executor, IContainerDMContext containerDmc,
Map<String, Object> attributes, boolean restart, Map<String, Object> attributes, boolean restart,
@ -101,166 +49,49 @@ public class GDBProcesses_7_10 extends GDBProcesses_7_4 {
} }
@Override @Override
public void attachDebuggerToProcess(final IProcessDMContext procCtx, final String binaryPath, final DataRequestMonitor<IDMContext> dataRm) { protected void doReverseDebugStep(IProcessDMContext procCtx, RequestMonitor rm) {
if (procCtx instanceof IMIProcessDMContext) { // Select reverse debugging mode to what was enabled as a launch option
if (!doIsDebuggerAttachSupported()) { IReverseRunControl2 reverseService = getServicesTracker().getService(IReverseRunControl2.class);
dataRm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Attach not supported.", null)); //$NON-NLS-1$ if (reverseService != null) {
dataRm.done(); ILaunch launch = procCtx.getAdapter(ILaunch.class);
return; if (launch != null) {
} try {
ICommandControlDMContext controlContext = DMContexts.getAncestorOfType(procCtx, ICommandControlDMContext.class);
// Use a sequence for better control of each step String reverseMode =
ImmediateExecutor.getInstance().execute(new Sequence(getExecutor(), dataRm) { launch.getLaunchConfiguration().getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE_MODE,
private IMIContainerDMContext fContainerDmc; IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_MODE_DEFAULT);
if (reverseMode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_MODE_SOFTWARE)) {
private Step[] steps = new Step[] { reverseService.enableReverseMode(controlContext, ReverseTraceMethod.FULL_TRACE, rm);
// If this is not the very first inferior, we first need create the new inferior }
new Step() { else if (reverseMode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_MODE_HARDWARE)) {
@Override String defaultValue = Platform.getPreferencesService().getString(GdbPlugin.PLUGIN_ID,
public void execute(final RequestMonitor rm) { IGdbDebugPreferenceConstants.PREF_REVERSE_TRACE_METHOD_HARDWARE,
if (isInitialProcess()) { IGdbDebugPreferenceConstants.PREF_REVERSE_TRACE_METHOD_GDB_TRACE, null);
// If it is the first inferior, GDB has already created it for us
// We really should get the id from GDB instead of hard-coding it ReverseTraceMethod traceMethod = ReverseTraceMethod.GDB_TRACE;
fContainerDmc = createContainerContext(procCtx, "i1"); //$NON-NLS-1$ if (defaultValue.equals(IGdbDebugPreferenceConstants.PREF_REVERSE_TRACE_METHOD_BRANCH_TRACE)) {
rm.done(); traceMethod = ReverseTraceMethod.BRANCH_TRACE;
return; } else if (defaultValue.equals(IGdbDebugPreferenceConstants.PREF_REVERSE_TRACE_METHOD_PROCESSOR_TRACE)) {
} traceMethod = ReverseTraceMethod.PROCESSOR_TRACE;
}
ICommandControlDMContext controlDmc = DMContexts.getAncestorOfType(procCtx, ICommandControlDMContext.class);
fCommandControl.queueCommand( reverseService.enableReverseMode(controlContext, traceMethod, rm);
fCommandFactory.createMIAddInferior(controlDmc), }
new ImmediateDataRequestMonitor<MIAddInferiorInfo>(rm) { else {
@Override rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unexpected Reverse debugging mode " + reverseMode, null)); //$NON-NLS-1$
protected void handleSuccess() { }
final String groupId = getData().getGroupId(); } catch (CoreException e) {
if (groupId == null || groupId.trim().length() == 0) { // Ignore, just don't set reverse method
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid gdb group id.", null)); //$NON-NLS-1$ rm.done();
} else { }
fContainerDmc = createContainerContext(procCtx, groupId); } else {
} // Ignore, just don't set reverse method
rm.done(); rm.done();
} }
}); } else {
} // If we don't have an IReverseRunControl2 service, fall-back to our previous behavior
}, super.doReverseDebugStep(procCtx, rm);
new Step() { }
@Override
public void execute(final RequestMonitor rm) {
// Now, set the binary to be used.
if (binaryPath != null) {
fCommandControl.queueCommand(
fCommandFactory.createMIFileExecAndSymbols(fContainerDmc, binaryPath),
new ImmediateDataRequestMonitor<MIInfo>(rm) {
@Override
protected void handleCompleted() {
super.handleCompleted();
};
});
return;
}
rm.done();
}
},
// Now, actually do the attach
new Step() {
@Override
public void execute(RequestMonitor rm) {
// For non-stop mode, we do a non-interrupting attach
// Bug 333284
boolean shouldInterrupt = true;
IMIRunControl runControl = getServicesTracker().getService(IMIRunControl.class);
if (runControl != null && runControl.getRunMode() == MIRunMode.NON_STOP) {
shouldInterrupt = false;
}
fCommandControl.queueCommand(
fCommandFactory.createMITargetAttach(fContainerDmc, ((IMIProcessDMContext)procCtx).getProcId(), shouldInterrupt),
new ImmediateDataRequestMonitor<MIInfo>(rm));
}
},
// Initialize memory data for this process.
new Step() {
@Override
public void execute(RequestMonitor rm) {
IGDBMemory memory = getServicesTracker().getService(IGDBMemory.class);
IMemoryDMContext memContext = DMContexts.getAncestorOfType(fContainerDmc, IMemoryDMContext.class);
if (memory == null || memContext == null) {
rm.done();
return;
}
memory.initializeMemoryData(memContext, rm);
}
},
// Start tracking this process' breakpoints.
new Step() {
@Override
public void execute(RequestMonitor rm) {
MIBreakpointsManager bpmService = getServicesTracker().getService(MIBreakpointsManager.class);
bpmService.startTrackingBpForProcess(fContainerDmc, rm);
}
},
// Select reverse debugging mode to what was enabled as a launch option
new Step() {
@Override
public void execute(RequestMonitor rm) {
IReverseRunControl2 reverseService = getServicesTracker().getService(IReverseRunControl2.class);
if (reverseService != null) {
ILaunch launch = procCtx.getAdapter(ILaunch.class);
if (launch != null) {
try {
String reverseMode =
launch.getLaunchConfiguration().getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE_MODE,
IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_MODE_DEFAULT);
if (reverseMode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_MODE_SOFTWARE)) {
reverseService.enableReverseMode(fCommandControl.getContext(), ReverseTraceMethod.FULL_TRACE, rm);
return;
}
else if (reverseMode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_MODE_HARDWARE)) {
String defaultValue = Platform.getPreferencesService().getString(GdbPlugin.PLUGIN_ID,
IGdbDebugPreferenceConstants.PREF_REVERSE_TRACE_METHOD_HARDWARE,
IGdbDebugPreferenceConstants.PREF_REVERSE_TRACE_METHOD_GDB_TRACE, null);
if (defaultValue.equals(IGdbDebugPreferenceConstants.PREF_REVERSE_TRACE_METHOD_BRANCH_TRACE)) {
reverseService.enableReverseMode(fCommandControl.getContext(), ReverseTraceMethod.BRANCH_TRACE, rm); // Branch Trace
} else if (defaultValue.equals(IGdbDebugPreferenceConstants.PREF_REVERSE_TRACE_METHOD_PROCESSOR_TRACE)) {
reverseService.enableReverseMode(fCommandControl.getContext(), ReverseTraceMethod.PROCESSOR_TRACE, rm); // Processor Trace
} else {
reverseService.enableReverseMode(fCommandControl.getContext(), ReverseTraceMethod.GDB_TRACE, rm); // GDB Selected Option
}
return;
}
else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid Trace Method Selected", null)); //$NON-NLS-1$
rm.done();
return;
}
} catch (CoreException e) {
// Ignore, just don't set reverse method
}
}
}
rm.done();
}
},
// Store the fully formed container context so it can be returned to the caller
// and mark that we are not dealing with the first process anymore.
new Step() {
@Override
public void execute(RequestMonitor rm) {
dataRm.setData(fContainerDmc);
setIsInitialProcess(false);
rm.done();
}
},
};
@Override public Step[] getSteps() { return steps; }
});
} else {
dataRm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid process context.", null)); //$NON-NLS-1$
dataRm.done();
}
} }
} }

View file

@ -10,7 +10,6 @@
* Marc Khouzam (Ericsson) - Workaround for Bug 352998 * Marc Khouzam (Ericsson) - Workaround for Bug 352998
* Marc Khouzam (Ericsson) - Update breakpoint handling for GDB >= 7.4 (Bug 389945) * Marc Khouzam (Ericsson) - Update breakpoint handling for GDB >= 7.4 (Bug 389945)
* Alvaro Sanchez-Leon (Ericsson) - Breakpoint Enable does not work after restarting the application (Bug 456959) * Alvaro Sanchez-Leon (Ericsson) - Breakpoint Enable does not work after restarting the application (Bug 456959)
* Intel Corporation - Added Reverse Debugging BTrace support
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service; package org.eclipse.cdt.dsf.gdb.service;
@ -446,24 +445,7 @@ public class GDBProcesses_7_2 extends GDBProcesses_7_1 implements IMultiTerminat
new Step() { new Step() {
@Override @Override
public void execute(RequestMonitor rm) { public void execute(RequestMonitor rm) {
IReverseRunControl reverseService = getServicesTracker().getService(IReverseRunControl.class); doReverseDebugStep(procCtx, rm);
if (reverseService != null) {
ILaunch launch = procCtx.getAdapter(ILaunch.class);
if (launch != null) {
try {
boolean reverseEnabled =
launch.getLaunchConfiguration().getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE,
IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT);
if (reverseEnabled) {
reverseService.enableReverseMode(fCommandControl.getContext(), true, rm);
return;
}
} catch (CoreException e) {
// Ignore, just don't set reverse
}
}
}
rm.done();
} }
}, },
// Store the fully formed container context so it can be returned to the caller // Store the fully formed container context so it can be returned to the caller
@ -487,8 +469,7 @@ public class GDBProcesses_7_2 extends GDBProcesses_7_1 implements IMultiTerminat
} }
} }
/** @since 5.0 */ private void connectToTarget(IProcessDMContext procCtx, RequestMonitor rm) {
protected void connectToTarget(IProcessDMContext procCtx, RequestMonitor rm) {
ILaunch launch = procCtx.getAdapter(ILaunch.class); ILaunch launch = procCtx.getAdapter(ILaunch.class);
assert launch != null; assert launch != null;
if (launch != null) { if (launch != null) {