mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-21 16:05:25 +02:00
Bug 335528: [multi-process] Move startOrRestart to the Processes service
This commit is contained in:
parent
6a815d839a
commit
4881bba10c
11 changed files with 666 additions and 435 deletions
|
@ -19,6 +19,7 @@ import java.nio.charset.CharsetDecoder;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.xml.transform.OutputKeys;
|
import javax.xml.transform.OutputKeys;
|
||||||
import javax.xml.transform.Transformer;
|
import javax.xml.transform.Transformer;
|
||||||
|
@ -673,4 +674,26 @@ public class CDebugUtils {
|
||||||
private static void throwCoreException(String msg, Exception innerException, int code) throws CoreException {
|
private static void throwCoreException(String msg, Exception innerException, int code) throws CoreException {
|
||||||
throw new CoreException(new Status(IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), code, msg, innerException));
|
throw new CoreException(new Status(IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), code, msg, innerException));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic method to fetch an attribute from a Map that has keys of type String. The defaultValue
|
||||||
|
* parameter will be returned if the map does not contain the key, or if the matching value is not
|
||||||
|
* of the correct type.
|
||||||
|
*
|
||||||
|
* @param <V> The type of the value we are looking for. Specified by the type of defaultValue.
|
||||||
|
* @param attributes The map with keys of type String, and values of any type. Cannot be null.
|
||||||
|
* @param key They key for which we want the value.
|
||||||
|
* @param defaultValue The default value to return if the key is not found in the map, or if the value found
|
||||||
|
* is not of the same type as defaultValue. Cannot be null.
|
||||||
|
* @return The value, if found and of the same type as defaultValue. Else, returns defaultValue.
|
||||||
|
* @since 7.1
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <V> V getAttribute(Map<String, ?> attributes, String key, V defaultValue) {
|
||||||
|
Object value = attributes.get(key);
|
||||||
|
if (defaultValue.getClass().isInstance(value)) {
|
||||||
|
return (V)value;
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2006, 2010 Wind River Systems and others.
|
* Copyright (c) 2006, 2011 Wind River Systems 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
|
||||||
|
@ -11,12 +11,19 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.dsf.gdb.internal.ui.actions;
|
package org.eclipse.cdt.dsf.gdb.internal.ui.actions;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
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.DsfRunnable;
|
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
||||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||||
|
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.debug.ui.actions.DsfCommandRunnable;
|
||||||
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
|
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
|
||||||
import org.eclipse.cdt.dsf.gdb.launching.GDBProcess;
|
import org.eclipse.cdt.dsf.gdb.launching.GDBProcess;
|
||||||
import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch;
|
import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch;
|
||||||
|
import org.eclipse.cdt.dsf.gdb.service.IGDBProcesses;
|
||||||
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
|
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
|
||||||
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
|
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
|
||||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||||
|
@ -52,16 +59,26 @@ public class GdbRestartCommand implements IRestartHandler {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fExecutor.submit(new DsfRunnable() {
|
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
|
||||||
public void run() {
|
@Override public void doExecute() {
|
||||||
IGDBControl gdbControl = fTracker.getService(IGDBControl.class);
|
IContainerDMContext containerDmc = DMContexts.getAncestorOfType(getContext(), IContainerDMContext.class);
|
||||||
if (gdbControl != null) {
|
IGDBProcesses procService = fTracker.getService(IGDBProcesses.class);
|
||||||
request.setEnabled(gdbControl.canRestart());
|
|
||||||
|
if (procService != null) {
|
||||||
|
procService.canRestart(
|
||||||
|
containerDmc,
|
||||||
|
new DataRequestMonitor<Boolean>(fExecutor, null) {
|
||||||
|
@Override
|
||||||
|
protected void handleCompleted() {
|
||||||
|
request.setEnabled(isSuccess() && getData());
|
||||||
|
request.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
request.setEnabled(false);
|
request.setEnabled(false);
|
||||||
}
|
|
||||||
request.done();
|
request.done();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,11 +123,20 @@ public class GdbRestartCommand implements IRestartHandler {
|
||||||
|
|
||||||
// Now that we have added the new inferior to the launch,
|
// Now that we have added the new inferior to the launch,
|
||||||
// which creates its console, we can perform the restart safely.
|
// which creates its console, we can perform the restart safely.
|
||||||
fExecutor.submit(new DsfRunnable() {
|
fExecutor.submit(new DsfCommandRunnable(fTracker, fRequest.getElements()[0], fRequest) {
|
||||||
public void run() {
|
@SuppressWarnings("unchecked")
|
||||||
final IGDBControl gdbControl = fTracker.getService(IGDBControl.class);
|
@Override public void doExecute() {
|
||||||
if (gdbControl != null) {
|
IContainerDMContext containerDmc = DMContexts.getAncestorOfType(getContext(), IContainerDMContext.class);
|
||||||
gdbControl.restart(fLaunch, new RequestMonitor(fExecutor, null) {
|
IGDBProcesses procService = fTracker.getService(IGDBProcesses.class);
|
||||||
|
|
||||||
|
if (procService != null) {
|
||||||
|
Map<String, Object> attributes = null;
|
||||||
|
try {
|
||||||
|
attributes = fLaunch.getLaunchConfiguration().getAttributes();
|
||||||
|
} catch (CoreException e) {}
|
||||||
|
|
||||||
|
procService.restart(containerDmc, attributes,
|
||||||
|
new RequestMonitor(fExecutor, null) {
|
||||||
@Override
|
@Override
|
||||||
protected void handleCompleted() {
|
protected void handleCompleted() {
|
||||||
fRequest.done();
|
fRequest.done();
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
package org.eclipse.cdt.dsf.gdb.launching;
|
package org.eclipse.cdt.dsf.gdb.launching;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
|
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
|
||||||
|
@ -26,12 +27,14 @@ import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
||||||
import org.eclipse.cdt.dsf.datamodel.DataModelInitializedEvent;
|
import org.eclipse.cdt.dsf.datamodel.DataModelInitializedEvent;
|
||||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
|
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext;
|
import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext;
|
||||||
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.actions.IConnect;
|
import org.eclipse.cdt.dsf.gdb.actions.IConnect;
|
||||||
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.IGDBBackend;
|
||||||
|
import org.eclipse.cdt.dsf.gdb.service.IGDBProcesses;
|
||||||
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl;
|
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl;
|
||||||
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
|
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
|
||||||
import org.eclipse.cdt.dsf.gdb.service.SessionType;
|
import org.eclipse.cdt.dsf.gdb.service.SessionType;
|
||||||
|
@ -39,6 +42,7 @@ import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
|
||||||
import org.eclipse.cdt.dsf.mi.service.CSourceLookup;
|
import org.eclipse.cdt.dsf.mi.service.CSourceLookup;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
|
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
|
||||||
import org.eclipse.cdt.dsf.mi.service.MIBreakpointsManager;
|
import org.eclipse.cdt.dsf.mi.service.MIBreakpointsManager;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.MIProcesses;
|
||||||
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;
|
||||||
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
|
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
|
||||||
|
@ -682,10 +686,21 @@ public class FinalLaunchSequence extends ReflectionSequence {
|
||||||
* Start executing the program.
|
* Start executing the program.
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Execute
|
@Execute
|
||||||
public void stepStartExecution(final RequestMonitor requestMonitor) {
|
public void stepStartExecution(final RequestMonitor requestMonitor) {
|
||||||
if (fSessionType != SessionType.CORE) {
|
if (fSessionType != SessionType.CORE) {
|
||||||
fCommandControl.start(fLaunch, requestMonitor);
|
Map<String, Object> attributes = null;
|
||||||
|
try {
|
||||||
|
attributes = fLaunch.getLaunchConfiguration().getAttributes();
|
||||||
|
} catch (CoreException e) {}
|
||||||
|
|
||||||
|
IGDBProcesses procService = fTracker.getService(IGDBProcesses.class);
|
||||||
|
IContainerDMContext containerDmc = procService.createContainerContextFromGroupId(fCommandControl.getContext(), MIProcesses.UNIQUE_GROUP_ID);
|
||||||
|
|
||||||
|
// For now, call restart since it does the same as start
|
||||||
|
// but this is just temporary until procService.debugNewProcess is ready
|
||||||
|
procService.restart(containerDmc, attributes, requestMonitor);
|
||||||
} else {
|
} else {
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2008, 2010 Ericsson and others.
|
* Copyright (c) 2008, 2011 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
|
||||||
|
@ -17,23 +17,32 @@ import java.util.Map;
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.IProcessInfo;
|
import org.eclipse.cdt.core.IProcessInfo;
|
||||||
import org.eclipse.cdt.core.IProcessList;
|
import org.eclipse.cdt.core.IProcessList;
|
||||||
|
import org.eclipse.cdt.debug.core.CDebugUtils;
|
||||||
|
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
|
||||||
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.datamodel.DMContexts;
|
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
||||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IProcesses;
|
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext;
|
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IProcesses;
|
||||||
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.ICommand;
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
|
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
|
||||||
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.internal.GdbPlugin;
|
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||||
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.IMICommandControl;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
|
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMIProcessDMContext;
|
import org.eclipse.cdt.dsf.mi.service.IMIProcessDMContext;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
|
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
|
||||||
import org.eclipse.cdt.dsf.mi.service.MIProcesses;
|
import org.eclipse.cdt.dsf.mi.service.MIProcesses;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess;
|
import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.events.MIStoppedEvent;
|
import org.eclipse.cdt.dsf.mi.service.command.events.MIStoppedEvent;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo;
|
||||||
|
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.DsfSession;
|
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
@ -42,7 +51,7 @@ import org.eclipse.core.runtime.Status;
|
||||||
import org.osgi.framework.BundleContext;
|
import org.osgi.framework.BundleContext;
|
||||||
|
|
||||||
|
|
||||||
public class GDBProcesses extends MIProcesses {
|
public class GDBProcesses extends MIProcesses implements IGDBProcesses {
|
||||||
|
|
||||||
private class GDBContainerDMC extends MIContainerDMC
|
private class GDBContainerDMC extends MIContainerDMC
|
||||||
implements IMemoryDMContext
|
implements IMemoryDMContext
|
||||||
|
@ -53,6 +62,8 @@ public class GDBProcesses extends MIProcesses {
|
||||||
}
|
}
|
||||||
|
|
||||||
private IGDBControl fGdb;
|
private IGDBControl fGdb;
|
||||||
|
private IGDBBackend fBackend;
|
||||||
|
private CommandFactory fCommandFactory;
|
||||||
|
|
||||||
// A map of pid to names. It is filled when we get all the
|
// A map of pid to names. It is filled when we get all the
|
||||||
// processes that are running
|
// processes that are running
|
||||||
|
@ -83,10 +94,13 @@ public class GDBProcesses extends MIProcesses {
|
||||||
private void doInitialize(RequestMonitor requestMonitor) {
|
private void doInitialize(RequestMonitor requestMonitor) {
|
||||||
|
|
||||||
fGdb = getServicesTracker().getService(IGDBControl.class);
|
fGdb = getServicesTracker().getService(IGDBControl.class);
|
||||||
|
fBackend = getServicesTracker().getService(IGDBBackend.class);
|
||||||
|
fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory();
|
||||||
|
|
||||||
// Register this service.
|
// Register this service.
|
||||||
register(new String[] { IProcesses.class.getName(),
|
register(new String[] { IProcesses.class.getName(),
|
||||||
IMIProcesses.class.getName(),
|
IMIProcesses.class.getName(),
|
||||||
|
IGDBProcesses.class.getName(),
|
||||||
MIProcesses.class.getName(),
|
MIProcesses.class.getName(),
|
||||||
GDBProcesses.class.getName() },
|
GDBProcesses.class.getName() },
|
||||||
new Hashtable<String, String>());
|
new Hashtable<String, String>());
|
||||||
|
@ -148,8 +162,7 @@ public class GDBProcesses extends MIProcesses {
|
||||||
if (inferior != null) {
|
if (inferior != null) {
|
||||||
String inferiorPidStr = inferior.getPid();
|
String inferiorPidStr = inferior.getPid();
|
||||||
if (inferiorPidStr != null && Integer.parseInt(inferiorPidStr) == pid) {
|
if (inferiorPidStr != null && Integer.parseInt(inferiorPidStr) == pid) {
|
||||||
IGDBBackend backend = getServicesTracker().getService(IGDBBackend.class);
|
name = fBackend.getProgramPath().lastSegment();
|
||||||
name = backend.getProgramPath().lastSegment();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,8 +173,7 @@ public class GDBProcesses extends MIProcesses {
|
||||||
// Until bug 305385 is fixed, the above code will not work, so we assume we
|
// Until bug 305385 is fixed, the above code will not work, so we assume we
|
||||||
// are looking for our own process
|
// are looking for our own process
|
||||||
// assert false : "Don't have entry for process ID: " + pid; //$NON-NLS-1$
|
// assert false : "Don't have entry for process ID: " + pid; //$NON-NLS-1$
|
||||||
IGDBBackend backend = getServicesTracker().getService(IGDBBackend.class);
|
name = fBackend.getProgramPath().lastSegment();
|
||||||
name = backend.getProgramPath().lastSegment();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,8 +260,7 @@ public class GDBProcesses extends MIProcesses {
|
||||||
@Override
|
@Override
|
||||||
public void getRunningProcesses(IDMContext dmc, final DataRequestMonitor<IProcessDMContext[]> rm) {
|
public void getRunningProcesses(IDMContext dmc, final DataRequestMonitor<IProcessDMContext[]> rm) {
|
||||||
final ICommandControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, ICommandControlDMContext.class);
|
final ICommandControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, ICommandControlDMContext.class);
|
||||||
IGDBBackend backend = getServicesTracker().getService(IGDBBackend.class);
|
if (fBackend.getSessionType() == SessionType.LOCAL) {
|
||||||
if (backend.getSessionType() == SessionType.LOCAL) {
|
|
||||||
IProcessList list = null;
|
IProcessList list = null;
|
||||||
try {
|
try {
|
||||||
list = CCorePlugin.getDefault().getProcessList();
|
list = CCorePlugin.getDefault().getProcessList();
|
||||||
|
@ -296,6 +307,113 @@ public class GDBProcesses extends MIProcesses {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 4.0 */
|
||||||
|
public IMIExecutionDMContext[] getExecutionContexts(IMIContainerDMContext containerDmc) {
|
||||||
|
assert false; // This is not being used before GDB 7.0
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 4.0 */
|
||||||
|
public void canRestart(IContainerDMContext containerDmc, DataRequestMonitor<Boolean> rm) {
|
||||||
|
if (fBackend.getIsAttachSession() || fBackend.getSessionType() == SessionType.CORE) {
|
||||||
|
rm.setData(false);
|
||||||
|
rm.done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Before GDB6.8, the Linux gdbserver would restart a new
|
||||||
|
// process when getting a -exec-run but the communication
|
||||||
|
// with GDB had a bug and everything hung.
|
||||||
|
// with GDB6.8 the program restarts properly one time,
|
||||||
|
// but on a second attempt, gdbserver crashes.
|
||||||
|
// So, lets just turn off the Restart for Remote debugging
|
||||||
|
if (fBackend.getSessionType() == SessionType.REMOTE) {
|
||||||
|
rm.setData(false);
|
||||||
|
rm.done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rm.setData(true);
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 4.0 */
|
||||||
|
public void restart(IContainerDMContext containerDmc, Map<String, Object> attributes, RequestMonitor rm) {
|
||||||
|
startOrRestart(containerDmc, attributes, true, rm);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert breakpoint at entry if set, and start or restart the program.
|
||||||
|
*
|
||||||
|
* @since 4.0
|
||||||
|
*/
|
||||||
|
protected void startOrRestart(final IContainerDMContext containerDmc, Map<String, Object> attributes,
|
||||||
|
boolean restart, final RequestMonitor requestMonitor) {
|
||||||
|
if (fBackend.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
final DataRequestMonitor<MIInfo> execMonitor = new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor) {
|
||||||
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
|
if (fBackend.getSessionType() != SessionType.REMOTE) {
|
||||||
|
// Don't send the ContainerStarted event for a remote session because
|
||||||
|
// it has already been done by MIRunControlEventProcessor when receiving
|
||||||
|
// the ^connect
|
||||||
|
getSession().dispatchEvent(new ContainerStartedDMEvent(containerDmc), getProperties());
|
||||||
|
}
|
||||||
|
super.handleSuccess();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final ICommand<MIInfo> execCommand;
|
||||||
|
if (useContinueCommand()) {
|
||||||
|
execCommand = fCommandFactory.createMIExecContinue(containerDmc);
|
||||||
|
} else {
|
||||||
|
execCommand = fCommandFactory.createMIExecRun(containerDmc);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean stopInMain = CDebugUtils.getAttribute(attributes,
|
||||||
|
ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN,
|
||||||
|
false);
|
||||||
|
|
||||||
|
if (!stopInMain) {
|
||||||
|
// Just start the program.
|
||||||
|
fGdb.queueCommand(execCommand, execMonitor);
|
||||||
|
} else {
|
||||||
|
String stopSymbol = CDebugUtils.getAttribute(attributes,
|
||||||
|
ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL,
|
||||||
|
ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT);
|
||||||
|
|
||||||
|
// Insert a breakpoint at the requested stop symbol.
|
||||||
|
IBreakpointsTargetDMContext bpTarget = DMContexts.getAncestorOfType(containerDmc, IBreakpointsTargetDMContext.class);
|
||||||
|
fGdb.queueCommand(
|
||||||
|
fCommandFactory.createMIBreakInsert(bpTarget, 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.
|
||||||
|
fGdb.queueCommand(execCommand, execMonitor);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method indicates if we should use the -exec-continue command
|
||||||
|
* instead of the -exec-run command.
|
||||||
|
* This method can be overridden to allow for customization.
|
||||||
|
* @since 4.0
|
||||||
|
*/
|
||||||
|
protected boolean useContinueCommand() {
|
||||||
|
// When doing remote debugging, we use -exec-continue instead of -exec-run
|
||||||
|
// Restart does not apply to remote sessions
|
||||||
|
return fBackend.getSessionType() == SessionType.REMOTE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2008, 2010 Ericsson and others.
|
* Copyright (c) 2008, 2011 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
|
||||||
|
@ -24,6 +24,7 @@ import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.IProcessInfo;
|
import org.eclipse.cdt.core.IProcessInfo;
|
||||||
import org.eclipse.cdt.core.IProcessList;
|
import org.eclipse.cdt.core.IProcessList;
|
||||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.Immutable;
|
import org.eclipse.cdt.dsf.concurrent.Immutable;
|
||||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.datamodel.AbstractDMContext;
|
import org.eclipse.cdt.dsf.datamodel.AbstractDMContext;
|
||||||
|
@ -981,6 +982,38 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
||||||
fCommandControl.terminate(rm);
|
fCommandControl.terminate(rm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 4.0 */
|
||||||
|
public void canRestart(IContainerDMContext containerDmc, DataRequestMonitor<Boolean> rm) {
|
||||||
|
if (fBackend.getIsAttachSession() || fBackend.getSessionType() == SessionType.CORE) {
|
||||||
|
rm.setData(false);
|
||||||
|
rm.done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Before GDB6.8, the Linux gdbserver would restart a new
|
||||||
|
// process when getting a -exec-run but the communication
|
||||||
|
// with GDB had a bug and everything hung.
|
||||||
|
// with GDB6.8 the program restarts properly one time,
|
||||||
|
// but on a second attempt, gdbserver crashes.
|
||||||
|
// So, lets just turn off the Restart for Remote debugging
|
||||||
|
if (fBackend.getSessionType() == SessionType.REMOTE) {
|
||||||
|
rm.setData(false);
|
||||||
|
rm.done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rm.setData(true);
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 4.0 */
|
||||||
|
public void restart(IContainerDMContext containerDmc, Map<String, Object> attributes, RequestMonitor rm) {
|
||||||
|
ImmediateExecutor.getInstance().execute(
|
||||||
|
new StartOrRestartProcessSequence_7_0(
|
||||||
|
getExecutor(), containerDmc, attributes, true,
|
||||||
|
new DataRequestMonitor<IContainerDMContext>(ImmediateExecutor.getInstance(), rm)));
|
||||||
|
}
|
||||||
|
|
||||||
@DsfServiceEventHandler
|
@DsfServiceEventHandler
|
||||||
public void eventDispatched(final MIThreadGroupCreatedEvent e) {
|
public void eventDispatched(final MIThreadGroupCreatedEvent e) {
|
||||||
IProcessDMContext procDmc = e.getDMContext();
|
IProcessDMContext procDmc = e.getDMContext();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2008, 2010 Ericsson and others.
|
* Copyright (c) 2008, 2011 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
|
||||||
|
@ -11,6 +11,11 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.dsf.gdb.service;
|
package org.eclipse.cdt.dsf.gdb.service;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
|
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
|
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
|
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
|
||||||
|
@ -51,4 +56,25 @@ public interface IGDBProcesses extends IMIProcesses {
|
||||||
*/
|
*/
|
||||||
IMIExecutionDMContext[] getExecutionContexts(IMIContainerDMContext containerDmc);
|
IMIExecutionDMContext[] getExecutionContexts(IMIContainerDMContext containerDmc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the specified process can be restarted.
|
||||||
|
*
|
||||||
|
* @param containerDmc The process that should be restarted
|
||||||
|
* @param rm The requestMonitor that returns if a restart is allowed on the specified process.
|
||||||
|
*
|
||||||
|
* @since 4.0
|
||||||
|
*/
|
||||||
|
void canRestart(IContainerDMContext containerDmc, DataRequestMonitor<Boolean> rm);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request that the specified process be restarted.
|
||||||
|
*
|
||||||
|
* @param containerDmc The process that should be restarted
|
||||||
|
* @param attributes Different attributes that affect the restart operation. This is
|
||||||
|
* usually the launch configuration attributes
|
||||||
|
* @param rm The requetMonitor that indicates that the restart request has been completed.
|
||||||
|
*
|
||||||
|
* @since 4.0
|
||||||
|
*/
|
||||||
|
void restart(IContainerDMContext containerDmc, Map<String, Object> attributes, RequestMonitor rm);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,354 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2011 Ericsson and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Ericsson - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.dsf.gdb.service;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.debug.core.CDebugUtils;
|
||||||
|
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.ReflectionSequence;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.command.ICommand;
|
||||||
|
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
|
||||||
|
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.command.CommandFactory;
|
||||||
|
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.DsfServicesTracker;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class causes a process to start (run for the first time), or to
|
||||||
|
* be restarted. The complexity is due to the handling of reverse debugging,
|
||||||
|
* which this class transparently enables if necessary.
|
||||||
|
*
|
||||||
|
* This sequence is used for GDB >= 7.0 which supports reverse debugging.
|
||||||
|
*
|
||||||
|
* @since 4.0
|
||||||
|
*/
|
||||||
|
public class StartOrRestartProcessSequence_7_0 extends ReflectionSequence {
|
||||||
|
|
||||||
|
private IGDBControl fCommandControl;
|
||||||
|
private CommandFactory fCommandFactory;
|
||||||
|
private IGDBProcesses fProcService;
|
||||||
|
private IReverseRunControl fReverseService;
|
||||||
|
|
||||||
|
private DsfServicesTracker fTracker;
|
||||||
|
|
||||||
|
// This variable will be used to store the original container context,
|
||||||
|
// but once the new process is start (restarted), it will contain the new
|
||||||
|
// container context. This new container context has for parent the process
|
||||||
|
// context, which holds the new pid.
|
||||||
|
private IContainerDMContext fContainerDmc;
|
||||||
|
|
||||||
|
// If the user requested a stop_on_main, this variable will hold the breakpoint
|
||||||
|
private MIBreakpoint fUserBreakpoint;
|
||||||
|
// Since the stop_on_main option allows the user to set the breakpoint on any
|
||||||
|
// symbol, we use this variable to know if the stop_on_main breakpoint was really
|
||||||
|
// on the main() method.
|
||||||
|
private boolean fUserBreakpointIsOnMain;
|
||||||
|
|
||||||
|
private boolean fReverseEnabled;
|
||||||
|
private final Map<String, Object> fAttributes;
|
||||||
|
|
||||||
|
// Indicates if the sequence is being used for a restart or a start
|
||||||
|
private final boolean fRestart;
|
||||||
|
|
||||||
|
// Store the dataRM so that we can fill it with the new container context, which we must return
|
||||||
|
// Although we can access this through Sequence.getRequestMonitor(), we would loose the type-checking.
|
||||||
|
// Therefore, doing it like this is more future-proof.
|
||||||
|
private final DataRequestMonitor<IContainerDMContext> fDataRequestMonitor;
|
||||||
|
|
||||||
|
|
||||||
|
protected IContainerDMContext getContainerContext() {
|
||||||
|
return fContainerDmc;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected MIBreakpoint getUserBreakpoint() {
|
||||||
|
return fUserBreakpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean getUserBreakpointIsOnMain() {
|
||||||
|
return fUserBreakpointIsOnMain;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public StartOrRestartProcessSequence_7_0(DsfExecutor executor, IContainerDMContext containerDmc, Map<String, Object> attributes,
|
||||||
|
boolean restart, DataRequestMonitor<IContainerDMContext> rm) {
|
||||||
|
super(executor, rm);
|
||||||
|
|
||||||
|
assert executor != null;
|
||||||
|
assert containerDmc != null;
|
||||||
|
if (attributes == null) {
|
||||||
|
// If no attributes are specified, simply use an empty map.
|
||||||
|
attributes = new HashMap<String, Object>();
|
||||||
|
}
|
||||||
|
|
||||||
|
fContainerDmc = containerDmc;
|
||||||
|
fAttributes = attributes;
|
||||||
|
fRestart = restart;
|
||||||
|
fDataRequestMonitor = rm;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getExecutionOrder(String group) {
|
||||||
|
if (GROUP_TOP_LEVEL.equals(group)) {
|
||||||
|
|
||||||
|
DsfServicesTracker tracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fContainerDmc.getSessionId());
|
||||||
|
IGDBBackend backend = tracker.getService(IGDBBackend.class);
|
||||||
|
tracker.dispose();
|
||||||
|
|
||||||
|
if (backend.getIsAttachSession()) {
|
||||||
|
// Restart does not apply to attach sessions, so we are only dealing with the
|
||||||
|
// Start case.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
return new String[] {
|
||||||
|
"stepInitializeBaseSequence", //$NON-NLS-1$
|
||||||
|
"stepEnableReverse", //$NON-NLS-1$
|
||||||
|
"stepCleanupBaseSequence", //$NON-NLS-1$
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return new String[] {
|
||||||
|
"stepInitializeBaseSequence", //$NON-NLS-1$
|
||||||
|
"stepInsertStopOnMainBreakpoint", //$NON-NLS-1$
|
||||||
|
"stepSetBreakpointForReverse", //$NON-NLS-1$
|
||||||
|
"stepRunProgram", //$NON-NLS-1$
|
||||||
|
"stepSetReverseOff", //$NON-NLS-1$
|
||||||
|
"stepEnableReverse", //$NON-NLS-1$
|
||||||
|
"stepContinue", //$NON-NLS-1$
|
||||||
|
"stepCleanupBaseSequence", //$NON-NLS-1$
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the members of the {@link StartOrRestartProcessSequence_7_0} class.
|
||||||
|
* This step is mandatory for the rest of the sequence to complete.
|
||||||
|
*/
|
||||||
|
@Execute
|
||||||
|
public void stepInitializeBaseSequence(RequestMonitor rm) {
|
||||||
|
fTracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fContainerDmc.getSessionId());
|
||||||
|
fCommandControl = fTracker.getService(IGDBControl.class);
|
||||||
|
fCommandFactory = fTracker.getService(IMICommandControl.class).getCommandFactory();
|
||||||
|
fProcService = fTracker.getService(IGDBProcesses.class);
|
||||||
|
|
||||||
|
if (fCommandControl == null || fCommandFactory == null || fProcService == null) {
|
||||||
|
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Cannot obtain service", null)); //$NON-NLS-1$
|
||||||
|
rm.done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fReverseService = fTracker.getService(IReverseRunControl.class);
|
||||||
|
if (fReverseService != null) {
|
||||||
|
// Although the option to use reverse debugging could be on, we only check
|
||||||
|
// it if we actually have a reverse debugging service. There is no point
|
||||||
|
// in trying to handle reverse debugging if it is not available.
|
||||||
|
fReverseEnabled = CDebugUtils.getAttribute(fAttributes,
|
||||||
|
IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE,
|
||||||
|
IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rollback method for {@link #stepInitializeBaseSequence()}
|
||||||
|
*/
|
||||||
|
@RollBack("stepInitializeBaseSequence")
|
||||||
|
public void rollBackInitializeBaseSequence(RequestMonitor rm) {
|
||||||
|
if (fTracker != null) fTracker.dispose();
|
||||||
|
fTracker = null;
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the user requested a 'stopOnMain', let's set the temporary breakpoint
|
||||||
|
* where the user specified.
|
||||||
|
*/
|
||||||
|
@Execute
|
||||||
|
public void stepInsertStopOnMainBreakpoint(final RequestMonitor rm) {
|
||||||
|
boolean userRequestedStop = CDebugUtils.getAttribute(fAttributes,
|
||||||
|
ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN,
|
||||||
|
false);
|
||||||
|
|
||||||
|
if (userRequestedStop) {
|
||||||
|
String userStopSymbol = CDebugUtils.getAttribute(fAttributes,
|
||||||
|
ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL,
|
||||||
|
ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT);
|
||||||
|
|
||||||
|
fCommandControl.queueCommand(
|
||||||
|
fCommandFactory.createMIBreakInsert((IBreakpointsTargetDMContext)fCommandControl.getContext(),
|
||||||
|
true, false, null, 0, userStopSymbol, 0),
|
||||||
|
new DataRequestMonitor<MIBreakInsertInfo>(ImmediateExecutor.getInstance(), 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.
|
||||||
|
*/
|
||||||
|
@Execute
|
||||||
|
public void stepSetBreakpointForReverse(final RequestMonitor rm) {
|
||||||
|
if (fReverseEnabled) {
|
||||||
|
fCommandControl.queueCommand(
|
||||||
|
fCommandFactory.createMIBreakInsert((IBreakpointsTargetDMContext)fCommandControl.getContext(),
|
||||||
|
true, false, null, 0, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT, 0),
|
||||||
|
new DataRequestMonitor<MIBreakInsertInfo>(ImmediateExecutor.getInstance(), 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.
|
||||||
|
*/
|
||||||
|
@Execute
|
||||||
|
public void stepRunProgram(final RequestMonitor rm) {
|
||||||
|
ICommand<MIInfo> command;
|
||||||
|
if (useContinueCommand()) {
|
||||||
|
command = fCommandFactory.createMIExecContinue(fContainerDmc);
|
||||||
|
} else {
|
||||||
|
command = fCommandFactory.createMIExecRun(fContainerDmc);
|
||||||
|
}
|
||||||
|
fCommandControl.queueCommand(command, new DataRequestMonitor<MIInfo>(ImmediateExecutor.getInstance(), rm) {
|
||||||
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
|
// Now that the process is started, the pid has been allocated
|
||||||
|
// so we need to fetch the proper container context
|
||||||
|
// We replace our current context which does not have the pid, with one that has the pid.
|
||||||
|
|
||||||
|
if (fContainerDmc instanceof IMIContainerDMContext) {
|
||||||
|
fContainerDmc = fProcService.createContainerContextFromGroupId(fCommandControl.getContext(), ((IMIContainerDMContext)fContainerDmc).getGroupId());
|
||||||
|
// This is the container context that this sequence is supposed to return: set the dataRm
|
||||||
|
fDataRequestMonitor.setData(fContainerDmc);
|
||||||
|
} else {
|
||||||
|
assert false : "Container context was not an IMIContainerDMContext"; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In case of a restart, we must mark reverse debugging as disabled because
|
||||||
|
* GDB has turned it off. We may have to turn it back on after.
|
||||||
|
*/
|
||||||
|
@Execute
|
||||||
|
public void stepSetReverseOff(RequestMonitor rm) {
|
||||||
|
if (fRestart) {
|
||||||
|
GDBRunControl_7_0 reverseService = fTracker.getService(GDBRunControl_7_0.class);
|
||||||
|
if (reverseService != null) {
|
||||||
|
reverseService.setReverseModeEnabled(false);
|
||||||
|
} else {
|
||||||
|
assert false : "Missing reverse runControl service"; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Since we have started the program, we can turn on reverse debugging if needed.
|
||||||
|
* We know the program will stop since we set a breakpoint on main, to enable reverse.
|
||||||
|
*/
|
||||||
|
@Execute
|
||||||
|
public void stepEnableReverse(RequestMonitor rm) {
|
||||||
|
if (fReverseEnabled) {
|
||||||
|
fReverseService.enableReverseMode(fCommandControl.getContext(), true, rm);
|
||||||
|
} else {
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
@Execute
|
||||||
|
public void stepContinue(RequestMonitor rm) {
|
||||||
|
if (fReverseEnabled && !fUserBreakpointIsOnMain) {
|
||||||
|
fCommandControl.queueCommand(fCommandFactory.createMIExecContinue(fContainerDmc),
|
||||||
|
new DataRequestMonitor<MIInfo>(ImmediateExecutor.getInstance(), rm));
|
||||||
|
} else {
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleanup now that the sequence has been run.
|
||||||
|
*/
|
||||||
|
@Execute
|
||||||
|
public void stepCleanupBaseSequence(final RequestMonitor rm) {
|
||||||
|
fTracker.dispose();
|
||||||
|
fTracker = null;
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method indicates if we should use the -exec-continue command
|
||||||
|
* instead of the -exec-run command.
|
||||||
|
* This method can be overridden to allow for customization.
|
||||||
|
*/
|
||||||
|
protected boolean useContinueCommand() {
|
||||||
|
// When doing remote debugging, we use -exec-continue instead of -exec-run
|
||||||
|
// Restart does not apply to remote sessions
|
||||||
|
IGDBBackend backend = fTracker.getService(IGDBBackend.class);
|
||||||
|
if (backend == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return backend.getSessionType() == SessionType.REMOTE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2006, 2010 Wind River Systems and others.
|
* Copyright (c) 2006, 2011 Wind River Systems 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
|
||||||
|
@ -24,7 +24,6 @@ import java.util.Properties;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
|
|
||||||
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
||||||
|
@ -33,22 +32,16 @@ import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
|
||||||
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.AbstractDMEvent;
|
import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
|
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.ICommand;
|
|
||||||
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.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.launching.GdbLaunch;
|
|
||||||
import org.eclipse.cdt.dsf.gdb.service.IGDBBackend;
|
import org.eclipse.cdt.dsf.gdb.service.IGDBBackend;
|
||||||
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.IMIBackend.BackendStateChangedEvent;
|
import org.eclipse.cdt.dsf.mi.service.IMIBackend.BackendStateChangedEvent;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
|
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
|
|
||||||
import org.eclipse.cdt.dsf.mi.service.MIProcesses;
|
|
||||||
import org.eclipse.cdt.dsf.mi.service.MIProcesses.ContainerExitedDMEvent;
|
import org.eclipse.cdt.dsf.mi.service.MIProcesses.ContainerExitedDMEvent;
|
||||||
import org.eclipse.cdt.dsf.mi.service.MIProcesses.ContainerStartedDMEvent;
|
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.AbstractCLIProcess;
|
import org.eclipse.cdt.dsf.mi.service.command.AbstractCLIProcess;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.AbstractMIControl;
|
import org.eclipse.cdt.dsf.mi.service.command.AbstractMIControl;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.CLIEventProcessor;
|
import org.eclipse.cdt.dsf.mi.service.command.CLIEventProcessor;
|
||||||
|
@ -57,18 +50,13 @@ import org.eclipse.cdt.dsf.mi.service.command.MIControlDMContext;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess;
|
import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess.State;
|
import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess.State;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.MIRunControlEventProcessor;
|
import org.eclipse.cdt.dsf.mi.service.command.MIRunControlEventProcessor;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo;
|
|
||||||
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.IStatus;
|
import org.eclipse.core.runtime.IStatus;
|
||||||
import org.eclipse.core.runtime.Platform;
|
import org.eclipse.core.runtime.Platform;
|
||||||
import org.eclipse.core.runtime.Status;
|
import org.eclipse.core.runtime.Status;
|
||||||
import org.eclipse.debug.core.DebugException;
|
|
||||||
import org.eclipse.debug.core.ILaunch;
|
|
||||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||||
import org.osgi.framework.BundleContext;
|
import org.osgi.framework.BundleContext;
|
||||||
|
|
||||||
|
@ -273,122 +261,6 @@ public class GDBControl extends AbstractMIControl implements IGDBControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean canRestart() {
|
|
||||||
if (fMIBackend.getIsAttachSession() || fMIBackend.getSessionType() == SessionType.CORE) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Before GDB6.8, the Linux gdbserver would restart a new
|
|
||||||
// process when getting a -exec-run but the communication
|
|
||||||
// with GDB had a bug and everything hung.
|
|
||||||
// with GDB6.8 the program restarts properly one time,
|
|
||||||
// but on a second attempt, gdbserver crashes.
|
|
||||||
// So, lets just turn off the Restart for Remote debugging
|
|
||||||
if (fMIBackend.getSessionType() == SessionType.REMOTE) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Start the program.
|
|
||||||
*/
|
|
||||||
public void start(GdbLaunch launch, final RequestMonitor requestMonitor) {
|
|
||||||
startOrRestart(launch, false, requestMonitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Before restarting the inferior, we must re-initialize its input/output streams
|
|
||||||
* and create a new inferior process object. Then we can restart the inferior.
|
|
||||||
*/
|
|
||||||
public void restart(final GdbLaunch launch, final RequestMonitor requestMonitor) {
|
|
||||||
startOrRestart(launch, true, requestMonitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Insert breakpoint at entry if set, and start or restart the program.
|
|
||||||
*/
|
|
||||||
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();
|
|
||||||
final IContainerDMContext containerDmc = procService.createContainerContextFromGroupId(fControlDmc, MIProcesses.UNIQUE_GROUP_ID);
|
|
||||||
|
|
||||||
final ICommand<MIInfo> execCommand;
|
|
||||||
if (useContinueCommand(launch, restart)) {
|
|
||||||
execCommand = getCommandFactory().createMIExecContinue(containerDmc);
|
|
||||||
} else {
|
|
||||||
execCommand = getCommandFactory().createMIExecRun(containerDmc);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean stopInMain = false;
|
|
||||||
try {
|
|
||||||
stopInMain = launch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, false );
|
|
||||||
} 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 DataRequestMonitor<MIInfo> execMonitor = new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor) {
|
|
||||||
@Override
|
|
||||||
protected void handleSuccess() {
|
|
||||||
if (fMIBackend.getSessionType() != SessionType.REMOTE) {
|
|
||||||
// Don't send the ContainerStarted event for a remote session because
|
|
||||||
// it has already been done by MIRunControlEventProcessor when receiving
|
|
||||||
// the ^connect
|
|
||||||
getSession().dispatchEvent(new ContainerStartedDMEvent(containerDmc), getProperties());
|
|
||||||
}
|
|
||||||
super.handleSuccess();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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(
|
|
||||||
getCommandFactory().createMIBreakInsert(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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method indicates if we should use the -exec-continue method
|
|
||||||
* instead of the -exec-run method.
|
|
||||||
* This can be overridden to allow for customization.
|
|
||||||
*
|
|
||||||
* @since 4.0
|
|
||||||
*/
|
|
||||||
protected boolean useContinueCommand(ILaunch launch, boolean restart) {
|
|
||||||
// When doing remote debugging, we use -exec-continue instead of -exec-run
|
|
||||||
// Restart does not apply to remote sessions
|
|
||||||
return fMIBackend.getSessionType() == SessionType.REMOTE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This method creates a new inferior process object based on the current Pty or output stream.
|
* This method creates a new inferior process object based on the current Pty or output stream.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2006, 2010 Wind River Systems and others.
|
* Copyright (c) 2006, 2011 Wind River Systems 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
|
||||||
|
@ -24,7 +24,6 @@ import java.util.Properties;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
|
|
||||||
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
||||||
|
@ -33,26 +32,18 @@ import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
|
||||||
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.AbstractDMEvent;
|
import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
|
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.ICommand;
|
|
||||||
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.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.launching.GdbLaunch;
|
|
||||||
import org.eclipse.cdt.dsf.gdb.service.GDBProcesses_7_0.ContainerExitedDMEvent;
|
import org.eclipse.cdt.dsf.gdb.service.GDBProcesses_7_0.ContainerExitedDMEvent;
|
||||||
import org.eclipse.cdt.dsf.gdb.service.GDBProcesses_7_0.ContainerStartedDMEvent;
|
import org.eclipse.cdt.dsf.gdb.service.GDBProcesses_7_0.ContainerStartedDMEvent;
|
||||||
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.IGDBTraceControl.ITraceRecordSelectedChangedDMEvent;
|
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceRecordSelectedChangedDMEvent;
|
||||||
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.IMIBackend.BackendStateChangedEvent;
|
import org.eclipse.cdt.dsf.mi.service.IMIBackend.BackendStateChangedEvent;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
|
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
|
|
||||||
import org.eclipse.cdt.dsf.mi.service.MIProcesses;
|
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.AbstractCLIProcess;
|
import org.eclipse.cdt.dsf.mi.service.command.AbstractCLIProcess;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.AbstractMIControl;
|
import org.eclipse.cdt.dsf.mi.service.command.AbstractMIControl;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.CLIEventProcessor_7_0;
|
import org.eclipse.cdt.dsf.mi.service.command.CLIEventProcessor_7_0;
|
||||||
|
@ -61,19 +52,14 @@ import org.eclipse.cdt.dsf.mi.service.command.MIControlDMContext;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess;
|
import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess.State;
|
import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess.State;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.MIRunControlEventProcessor_7_0;
|
import org.eclipse.cdt.dsf.mi.service.command.MIRunControlEventProcessor_7_0;
|
||||||
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.mi.service.command.output.MIListFeaturesInfo;
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIListFeaturesInfo;
|
||||||
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
|
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
|
||||||
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.IStatus;
|
import org.eclipse.core.runtime.IStatus;
|
||||||
import org.eclipse.core.runtime.Platform;
|
import org.eclipse.core.runtime.Platform;
|
||||||
import org.eclipse.core.runtime.Status;
|
import org.eclipse.core.runtime.Status;
|
||||||
import org.eclipse.debug.core.DebugException;
|
|
||||||
import org.eclipse.debug.core.ILaunch;
|
|
||||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||||
import org.osgi.framework.BundleContext;
|
import org.osgi.framework.BundleContext;
|
||||||
|
|
||||||
|
@ -292,240 +278,6 @@ public class GDBControl_7_0 extends AbstractMIControl implements IGDBControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean canRestart() {
|
|
||||||
if (fMIBackend.getIsAttachSession()|| fMIBackend.getSessionType() == SessionType.CORE) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Before GDB6.8, the Linux gdbserver would restart a new
|
|
||||||
// process when getting a -exec-run but the communication
|
|
||||||
// with GDB had a bug and everything hung.
|
|
||||||
// with GDB6.8 the program restarts properly one time,
|
|
||||||
// but on a second attempt, gdbserver crashes.
|
|
||||||
// So, lets just turn off the Restart for Remote debugging
|
|
||||||
if (fMIBackend.getSessionType() == SessionType.REMOTE) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start the program.
|
|
||||||
*/
|
|
||||||
public void start(GdbLaunch launch, final RequestMonitor requestMonitor) {
|
|
||||||
startOrRestart(launch, false, requestMonitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Before restarting the inferior, we must re-initialize its input/output streams
|
|
||||||
* and create a new inferior process object. Then we can restart the inferior.
|
|
||||||
*/
|
|
||||||
public void restart(final GdbLaunch launch, final RequestMonitor requestMonitor) {
|
|
||||||
startOrRestart(launch, true, requestMonitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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, final boolean restart, RequestMonitor requestMonitor) {
|
|
||||||
boolean tmpReverseEnabled = IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT;
|
|
||||||
try {
|
|
||||||
tmpReverseEnabled = launch.getLaunchConfiguration().getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE,
|
|
||||||
IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT);
|
|
||||||
} catch (CoreException e) {
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
MIBreakpoint fUserBreakpoint = null;
|
|
||||||
boolean fUserBreakpointIsOnMain = false;
|
|
||||||
|
|
||||||
Step[] fSteps = new Step[] {
|
|
||||||
/*
|
|
||||||
* 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) {
|
|
||||||
String userStopSymbol = null;
|
|
||||||
try {
|
|
||||||
userStopSymbol = 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(getCommandFactory().createMIBreakInsert(fControlDmc, true, false, null, 0, userStopSymbol, 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(getCommandFactory().createMIBreakInsert(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. Use either -exec-run or -exec-continue depending
|
|
||||||
* on whether we have remote session or not.
|
|
||||||
*/
|
|
||||||
new Step() {
|
|
||||||
@Override
|
|
||||||
public void execute(RequestMonitor rm) {
|
|
||||||
IMIProcesses procService = getServicesTracker().getService(IMIProcesses.class);
|
|
||||||
fContainerDmc = procService.createContainerContextFromGroupId(fControlDmc, MIProcesses.UNIQUE_GROUP_ID);
|
|
||||||
ICommand<MIInfo> command;
|
|
||||||
|
|
||||||
if (useContinueCommand(launch, restart)) {
|
|
||||||
command = getCommandFactory().createMIExecContinue(fContainerDmc);
|
|
||||||
} else {
|
|
||||||
command = getCommandFactory().createMIExecRun(fContainerDmc);
|
|
||||||
}
|
|
||||||
queueCommand(command, 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(getCommandFactory().createMIExecContinue(fContainerDmc),
|
|
||||||
new DataRequestMonitor<MIInfo>(getExecutor(), rm));
|
|
||||||
} else {
|
|
||||||
rm.done();
|
|
||||||
}
|
|
||||||
}},
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Step[] getSteps() {
|
|
||||||
return fSteps;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method indicates if we should use the -exec-continue method
|
|
||||||
* instead of the -exec-run method.
|
|
||||||
* This can be overridden to allow for customization.
|
|
||||||
*
|
|
||||||
* @since 4.0
|
|
||||||
*/
|
|
||||||
protected boolean useContinueCommand(ILaunch launch, boolean restart) {
|
|
||||||
// When doing remote debugging, we use -exec-continue instead of -exec-run
|
|
||||||
// Restart does not apply to remote sessions
|
|
||||||
return fMIBackend.getSessionType() == SessionType.REMOTE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method creates a new inferior process object based on the current Pty or output stream.
|
* This method creates a new inferior process object based on the current Pty or output stream.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2008, 2010 Ericsson and others.
|
* Copyright (c) 2008, 2011 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 License v1.0
|
* are made available under the terms of the Eclipse License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -17,7 +17,6 @@ import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch;
|
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
|
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.AbstractCLIProcess;
|
import org.eclipse.cdt.dsf.mi.service.command.AbstractCLIProcess;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess;
|
import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess;
|
||||||
|
@ -27,9 +26,6 @@ public interface IGDBControl extends IMICommandControl {
|
||||||
void terminate(final RequestMonitor rm);
|
void terminate(final RequestMonitor rm);
|
||||||
void initInferiorInputOutput(final RequestMonitor requestMonitor);
|
void initInferiorInputOutput(final RequestMonitor requestMonitor);
|
||||||
|
|
||||||
boolean canRestart();
|
|
||||||
void start(GdbLaunch launch, final RequestMonitor requestMonitor);
|
|
||||||
void restart(final GdbLaunch launch, final RequestMonitor requestMonitor);
|
|
||||||
void createInferiorProcess();
|
void createInferiorProcess();
|
||||||
|
|
||||||
boolean isConnected();
|
boolean isConnected();
|
||||||
|
|
|
@ -41,10 +41,10 @@ import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMData;
|
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMData;
|
||||||
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.IGDBProcesses;
|
||||||
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.IMICommandControl;
|
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
|
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
|
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMIRunControl;
|
import org.eclipse.cdt.dsf.mi.service.IMIRunControl;
|
||||||
import org.eclipse.cdt.dsf.mi.service.MIStack;
|
import org.eclipse.cdt.dsf.mi.service.MIStack;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
|
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
|
||||||
|
@ -76,7 +76,7 @@ public class SyncUtil {
|
||||||
private static CommandFactory fCommandFactory;
|
private static CommandFactory fCommandFactory;
|
||||||
|
|
||||||
private static IBreakpointsTargetDMContext fBreakpointsDmc;
|
private static IBreakpointsTargetDMContext fBreakpointsDmc;
|
||||||
private static IMIProcesses fProcessesService;
|
private static IGDBProcesses fProcessesService;
|
||||||
|
|
||||||
// Initialize some common things, once the session has been established
|
// Initialize some common things, once the session has been established
|
||||||
public static void initialize(DsfSession session) throws Exception {
|
public static void initialize(DsfSession session) throws Exception {
|
||||||
|
@ -92,7 +92,7 @@ public class SyncUtil {
|
||||||
fRunControl = tracker.getService(IMIRunControl.class);
|
fRunControl = tracker.getService(IMIRunControl.class);
|
||||||
fStack = tracker.getService(MIStack.class);
|
fStack = tracker.getService(MIStack.class);
|
||||||
fExpressions = tracker.getService(IExpressions.class);
|
fExpressions = tracker.getService(IExpressions.class);
|
||||||
fProcessesService = tracker.getService(IMIProcesses.class);
|
fProcessesService = tracker.getService(IGDBProcesses.class);
|
||||||
fCommandFactory = tracker.getService(IMICommandControl.class).getCommandFactory();
|
fCommandFactory = tracker.getService(IMICommandControl.class).getCommandFactory();
|
||||||
|
|
||||||
fBreakpointsDmc = (IBreakpointsTargetDMContext)fGdbControl.getContext();
|
fBreakpointsDmc = (IBreakpointsTargetDMContext)fGdbControl.getContext();
|
||||||
|
@ -606,13 +606,23 @@ public class SyncUtil {
|
||||||
* Restart the program.
|
* Restart the program.
|
||||||
*/
|
*/
|
||||||
public static void restart(final GdbLaunch launch) throws Throwable {
|
public static void restart(final GdbLaunch launch) throws Throwable {
|
||||||
|
final IContainerDMContext containerDmc = getContainerContext();
|
||||||
|
|
||||||
// Check if restart is allowed
|
// Check if restart is allowed
|
||||||
Query<Boolean> query = new Query<Boolean>() {
|
Query<Boolean> query = new Query<Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
protected void execute(DataRequestMonitor<Boolean> rm) {
|
protected void execute(final DataRequestMonitor<Boolean> rm) {
|
||||||
rm.setData(fGdbControl.canRestart());
|
fProcessesService.canRestart(
|
||||||
|
containerDmc,
|
||||||
|
new DataRequestMonitor<Boolean>(ImmediateExecutor.getInstance(), rm) {
|
||||||
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
|
rm.setData(getData());
|
||||||
rm.done();
|
rm.done();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fGdbControl.getExecutor().execute(query);
|
fGdbControl.getExecutor().execute(query);
|
||||||
|
@ -628,14 +638,20 @@ public class SyncUtil {
|
||||||
MIStoppedEvent.class);
|
MIStoppedEvent.class);
|
||||||
|
|
||||||
// Perform the restart
|
// Perform the restart
|
||||||
Query<Boolean> query2 = new Query<Boolean>() {
|
Query<Object> query2 = new Query<Object>() {
|
||||||
@Override
|
@Override
|
||||||
protected void execute(final DataRequestMonitor<Boolean> rm) {
|
protected void execute(final DataRequestMonitor<Object> rm) {
|
||||||
fGdbControl.initInferiorInputOutput(new RequestMonitor(ImmediateExecutor.getInstance(), rm) {
|
fGdbControl.initInferiorInputOutput(new RequestMonitor(ImmediateExecutor.getInstance(), rm) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
protected void handleSuccess() {
|
protected void handleSuccess() {
|
||||||
fGdbControl.createInferiorProcess();
|
fGdbControl.createInferiorProcess();
|
||||||
fGdbControl.restart(launch, rm);
|
Map<String, Object> attributes = null;
|
||||||
|
try {
|
||||||
|
attributes = launch.getLaunchConfiguration().getAttributes();
|
||||||
|
} catch (CoreException e) {}
|
||||||
|
|
||||||
|
fProcessesService.restart(containerDmc, attributes, rm);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue