blob: 0748f3921269a69450b8ce9e6bf47213475234eb [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2014 QNX Software Systems 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 this class is based on
* QNX Software Systems - Initial implementation for Jtag debugging
* Sage Electronic Engineering, LLC - bug 305943
* - API generalization to become transport-independent (allow
* connections via serial ports and pipes).
* John Dallaway - Wrong groupId during initialization (Bug 349736)
* Marc Khouzam (Ericsson) - Updated to extend FinalLaunchSequence instead of copying it (bug 324101)
* William Riley (Renesas) - Memory viewing broken (Bug 413483)
* Marc Khouzam (Ericsson) - Cannot disable Delay command (bug 413437)
*******************************************************************************/
package org.eclipse.cdt.debug.gdbjtag.core;
/**
* @author Andy Jin
*
*/
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.eclipse.cdt.debug.core.CDebugUtils;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.debug.gdbjtag.core.jtagdevice.GDBJtagDeviceContribution;
import org.eclipse.cdt.debug.gdbjtag.core.jtagdevice.GDBJtagDeviceContributionFactory;
import org.eclipse.cdt.debug.gdbjtag.core.jtagdevice.IGDBJtagDevice;
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
import org.eclipse.cdt.dsf.concurrent.ImmediateDataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitorWithProgress;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext;
import org.eclipse.cdt.dsf.gdb.launching.FinalLaunchSequence;
import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch;
import org.eclipse.cdt.dsf.gdb.service.IGDBBackend;
import org.eclipse.cdt.dsf.gdb.service.IGDBMemory;
import org.eclipse.cdt.dsf.gdb.service.SessionType;
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
import org.eclipse.cdt.dsf.mi.service.MIBreakpointsManager;
import org.eclipse.cdt.dsf.mi.service.MIProcesses;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLICommand;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.utils.CommandLineUtil;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.variables.VariablesPlugin;
/**
* The final launch sequence for the Jtag hardware debugging using the
* DSF/GDB debugger framework.
* <p>
* This class is based on the implementation of the standard DSF/GDB debugging
* <code>org.eclipse.cdt.dsf.gdb.launching.FinalLaunchSequence</code>
* <p>
* It adds Jtag hardware debugging specific steps to initialize remote target
* and start the remote Jtag debugging.
* <p>
* @since 7.0
*/
public class GDBJtagDSFFinalLaunchSequence extends FinalLaunchSequence {
/** utility method; cuts down on clutter */
private void queueCommands(List<String> commands, RequestMonitor rm) {
if (!commands.isEmpty()) {
fCommandControl.queueCommand(
new CLICommand<MIInfo>(fCommandControl.getContext(), composeCommand(commands)),
new DataRequestMonitor<MIInfo>(getExecutor(), rm));
}
else {
rm.done();
}
}
private IGDBControl fCommandControl;
private IGDBBackend fGDBBackend;
private IMIProcesses fProcService;
private IGDBJtagDevice fGdbJtagDevice;
private DsfServicesTracker fTracker;
private IMIContainerDMContext fContainerCtx;
/**
* @since 8.2
*/
public GDBJtagDSFFinalLaunchSequence(DsfSession session, Map<String, Object> attributes, RequestMonitorWithProgress rm) {
super(session, attributes, rm);
}
public GDBJtagDSFFinalLaunchSequence(DsfExecutor executor, GdbLaunch launch, SessionType sessionType, boolean attach, RequestMonitorWithProgress rm) {
this(launch.getSession(), getAttributes(launch), rm);
}
@SuppressWarnings("unchecked")
private static Map<String, Object> getAttributes(GdbLaunch launch) {
try {
return launch.getLaunchConfiguration().getAttributes();
} catch (CoreException e) {
}
return new HashMap<String, Object>();
}
/** @since 8.2 */
protected IMIContainerDMContext getContainerContext() {
return fContainerCtx;
}
/** @since 8.2 */
protected void setContainerContext(IMIContainerDMContext ctx) {
fContainerCtx = ctx;
}
/** @since 8.2 */
protected static final String GROUP_JTAG = "GROUP_JTAG";
@Override
protected String[] getExecutionOrder(String group) {
if (GROUP_TOP_LEVEL.equals(group)) {
// Initialize the list with the base class' steps
// We need to create a list that we can modify, which is why we create our own ArrayList.
List<String> orderList = new ArrayList<String>(Arrays.asList(super.getExecutionOrder(GROUP_TOP_LEVEL)));
// First, remove all steps of the base class that we don't want to use.
orderList.removeAll(Arrays.asList(new String[] {
"stepNewProcess", //$NON-NLS-1$
}));
// Now insert our steps before the data model initialized event is sent
orderList.add(orderList.indexOf("stepDataModelInitializationComplete"), GROUP_JTAG);
return orderList.toArray(new String[orderList.size()]);
}
// Finally, deal with our groups and their steps.
if (GROUP_JTAG.equals(group)) {
return new String[] {
"stepInitializeJTAGFinalLaunchSequence",
"stepRetrieveJTAGDevice", //$NON-NLS-1$
"stepLoadSymbols", //$NON-NLS-1$
"stepConnectToTarget", //$NON-NLS-1$
"stepResetBoard", //$NON-NLS-1$
"stepDelayStartup", //$NON-NLS-1$
"stepHaltBoard", //$NON-NLS-1$
"stepUserInitCommands", //$NON-NLS-1$
"stepLoadImage", //$NON-NLS-1$
"stepUpdateContainer", //$NON-NLS-1$
"stepInitializeMemory", //$NON-NLS-1$
"stepSetArguments", //$NON-NLS-1$
"stepSetEnvironmentVariables", //$NON-NLS-1$
"stepStartTrackingBreakpoints", //$NON-NLS-1$
"stepSetProgramCounter", //$NON-NLS-1$
"stepStopScript", //$NON-NLS-1$
"stepResumeScript", //$NON-NLS-1$
"stepUserDebugCommands", //$NON-NLS-1$
"stepJTAGCleanup", //$NON-NLS-1$
};
}
// For any subgroups of the base class
return super.getExecutionOrder(group);
}
/**
* Initialize the members of the class.
* This step is mandatory for the rest of the sequence to complete.
* @since 8.2
*/
@Execute
public void stepInitializeJTAGFinalLaunchSequence(RequestMonitor rm) {
fTracker = new DsfServicesTracker(Activator.getBundleContext(), getSession().getId());
fGDBBackend = fTracker.getService(IGDBBackend.class);
if (fGDBBackend == null) {
rm.done(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot obtain GDBBackend service", null)); //$NON-NLS-1$
return;
}
fCommandControl = fTracker.getService(IGDBControl.class);
if (fCommandControl == null) {
rm.done(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot obtain control service", null)); //$NON-NLS-1$
return;
}
fProcService = fTracker.getService(IMIProcesses.class);
if (fProcService == null) {
rm.done(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot obtain process service", null)); //$NON-NLS-1$
return;
}
// When we are starting to debug a new process, the container is the default process used by GDB.
// We don't have a pid yet, so we can simply create the container with the UNIQUE_GROUP_ID
setContainerContext(fProcService.createContainerContextFromGroupId(fCommandControl.getContext(), MIProcesses.UNIQUE_GROUP_ID));
rm.done();
}
/**
* Rollback method for {@link #stepInitializeJTAGFinalLaunchSequence()}
* @since 4.0
*/
@RollBack("stepInitializeJTAGFinalLaunchSequence")
public void rollBackInitializeFinalLaunchSequence(RequestMonitor rm) {
if (fTracker != null) fTracker.dispose();
fTracker = null;
rm.done();
}
/*
* Retrieve the IGDBJtagDevice instance
*/
/** @since 8.2 */
@Execute
public void stepRetrieveJTAGDevice(final RequestMonitor rm) {
Exception exception = null;
try {
fGdbJtagDevice = getGDBJtagDevice();
} catch (NullPointerException e) {
exception = e;
}
if (fGdbJtagDevice == null) {
// Abort the launch
rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot get Jtag device", exception)); //$NON-NLS-1$
}
rm.done();
}
/*
* Execute symbol loading
*/
/** @since 8.2 */
@Execute
public void stepLoadSymbols(final RequestMonitor rm) {
try {
if (CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_LOAD_SYMBOLS, IGDBJtagConstants.DEFAULT_LOAD_SYMBOLS)) {
String symbolsFileName = null;
// New setting in Helios. Default is true. Check for existence
// in order to support older launch configs
if (getAttributes().containsKey(IGDBJtagConstants.ATTR_USE_PROJ_BINARY_FOR_SYMBOLS) &&
CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_USE_PROJ_BINARY_FOR_SYMBOLS, IGDBJtagConstants.DEFAULT_USE_PROJ_BINARY_FOR_SYMBOLS)) {
IPath programFile = fGDBBackend.getProgramPath();
if (programFile != null) {
symbolsFileName = programFile.toOSString();
}
}
else {
symbolsFileName = CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_SYMBOLS_FILE_NAME, IGDBJtagConstants.DEFAULT_SYMBOLS_FILE_NAME);
if (symbolsFileName.length() > 0) {
symbolsFileName = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(symbolsFileName);
} else {
symbolsFileName = null;
}
}
if (symbolsFileName == null) {
rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, Messages.getString("GDBJtagDebugger.err_no_img_file"), null)); //$NON-NLS-1$
rm.done();
return;
}
// Escape windows path separator characters TWICE, once for Java and once for GDB.
symbolsFileName = symbolsFileName.replace("\\", "\\\\"); //$NON-NLS-1$ //$NON-NLS-2$
String symbolsOffset = CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_SYMBOLS_OFFSET, IGDBJtagConstants.DEFAULT_SYMBOLS_OFFSET);
if (symbolsOffset.length() > 0) {
symbolsOffset = "0x" + symbolsOffset;
}
List<String> commands = new ArrayList<String>();
fGdbJtagDevice.doLoadSymbol(symbolsFileName, symbolsOffset, commands);
queueCommands(commands, rm);
} else {
rm.done();
}
} catch (CoreException e) {
rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot load symbol", e)); //$NON-NLS-1$
rm.done();
}
}
/*
* Hook up to remote target
*/
/** @since 8.2 */
@SuppressWarnings("deprecation")
@Execute
public void stepConnectToTarget(final RequestMonitor rm) {
try {
if (CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_USE_REMOTE_TARGET, IGDBJtagConstants.DEFAULT_USE_REMOTE_TARGET)) {
List<String> commands = new ArrayList<String>();
if (fGdbJtagDevice instanceof IGDBJtagConnection) {
URI uri = new URI(CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_CONNECTION, IGDBJtagConstants.DEFAULT_CONNECTION));
IGDBJtagConnection device = (IGDBJtagConnection)fGdbJtagDevice;
device.doRemote(uri.getSchemeSpecificPart(), commands);
} else {
// Handle legacy network device contributions that don't understand URIs
String ipAddress = CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_IP_ADDRESS, IGDBJtagConstants.DEFAULT_IP_ADDRESS);
int portNumber = CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_PORT_NUMBER, IGDBJtagConstants.DEFAULT_PORT_NUMBER);
fGdbJtagDevice.doRemote(ipAddress, portNumber, commands);
}
queueCommands(commands, rm);
} else {
rm.done();
}
} catch (URISyntaxException e) {
rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Invalid remote target connection syntax", e)); //$NON-NLS-1$
rm.done();
}
}
/*
* Run device-specific code to reset the board
*/
/** @since 8.2 */
@Execute
public void stepResetBoard(final RequestMonitor rm) {
if (CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_DO_RESET, IGDBJtagConstants.DEFAULT_DO_RESET)) {
List<String> commands = new ArrayList<String>();
fGdbJtagDevice.doReset(commands);
queueCommands(commands, rm);
} else {
rm.done();
}
}
/*
* Run device-specific code to delay the startup
*/
/** @since 8.2 */
@Execute
public void stepDelayStartup(final RequestMonitor rm) {
// The delay is also controlled by the RESET attribute.
if (CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_DO_RESET, IGDBJtagConstants.DEFAULT_DO_RESET)) {
int defaultDelay = fGdbJtagDevice.getDefaultDelay();
List<String> commands = new ArrayList<String>();
fGdbJtagDevice.doDelay(CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_DELAY, defaultDelay), commands);
queueCommands(commands, rm);
} else {
rm.done();
}
}
/*
* Run device-specific code to halt the board
*/
/** @since 8.2 */
@Execute
public void stepHaltBoard(final RequestMonitor rm) {
if (CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_DO_HALT, IGDBJtagConstants.DEFAULT_DO_HALT)) {
List<String> commands = new ArrayList<String>();
fGdbJtagDevice.doHalt(commands);
queueCommands(commands, rm);
} else {
rm.done();
}
}
/*
* Execute any user defined init commands
*/
/** @since 8.2 */
@Execute
public void stepUserInitCommands(final RequestMonitor rm) {
try {
String userCmd = CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_INIT_COMMANDS, IGDBJtagConstants.DEFAULT_INIT_COMMANDS);
userCmd = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(userCmd);
if (userCmd.length() > 0) {
String[] commands = userCmd.split("\\r?\\n"); //$NON-NLS-1$
CountingRequestMonitor crm = new CountingRequestMonitor(getExecutor(), rm);
crm.setDoneCount(commands.length);
for (int i = 0; i < commands.length; ++i) {
fCommandControl.queueCommand(
new CLICommand<MIInfo>(fCommandControl.getContext(), commands[i]),
new DataRequestMonitor<MIInfo>(getExecutor(), crm));
}
}
else {
rm.done();
}
} catch (CoreException e) {
rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot run user defined init commands", e)); //$NON-NLS-1$
rm.done();
}
}
/*
* Execute image loading
*/
/** @since 8.2 */
@Execute
public void stepLoadImage(final RequestMonitor rm) {
try {
String imageFileName = null;
if (CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_LOAD_IMAGE, IGDBJtagConstants.DEFAULT_LOAD_IMAGE)) {
// New setting in Helios. Default is true. Check for existence
// in order to support older launch configs
if (getAttributes().containsKey(IGDBJtagConstants.ATTR_USE_PROJ_BINARY_FOR_IMAGE) &&
CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_USE_PROJ_BINARY_FOR_IMAGE, IGDBJtagConstants.DEFAULT_USE_PROJ_BINARY_FOR_IMAGE)) {
IPath programFile = fGDBBackend.getProgramPath();
if (programFile != null) {
imageFileName = programFile.toOSString();
}
}
else {
imageFileName = CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_IMAGE_FILE_NAME, IGDBJtagConstants.DEFAULT_IMAGE_FILE_NAME);
if (imageFileName.length() > 0) {
imageFileName = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(imageFileName);
} else {
imageFileName = null;
}
}
if (imageFileName == null) {
rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, Messages.getString("GDBJtagDebugger.err_no_img_file"), null)); //$NON-NLS-1$
rm.done();
return;
}
// Escape windows path separator characters TWICE, once for Java and once for GDB.
imageFileName = imageFileName.replace("\\", "\\\\"); //$NON-NLS-1$ //$NON-NLS-2$
String imageOffset = CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_IMAGE_OFFSET, IGDBJtagConstants.DEFAULT_IMAGE_OFFSET);
if (imageOffset.length() > 0) {
imageOffset = (imageFileName.endsWith(".elf")) ? "" : "0x" + CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_IMAGE_OFFSET, IGDBJtagConstants.DEFAULT_IMAGE_OFFSET); //$NON-NLS-2$
}
List<String> commands = new ArrayList<String>();
fGdbJtagDevice.doLoadImage(imageFileName, imageOffset, commands);
queueCommands(commands, rm);
}
else {
rm.done();
}
} catch (CoreException e) {
rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot load image", e)); //$NON-NLS-1$
rm.done();
}
}
/**
* Now that we are connected to the target, we should update
* our container to properly fill in its pid.
* @since 8.2
*/
@Execute
public void stepUpdateContainer(RequestMonitor rm) {
String groupId = getContainerContext().getGroupId();
setContainerContext(fProcService.createContainerContextFromGroupId(fCommandControl.getContext(), groupId));
rm.done();
}
/**
* Specify the arguments to the program that will be run.
* @since 8.2
*/
@Execute
public void stepSetArguments(RequestMonitor rm) {
try {
String args = CDebugUtils.getAttribute(
getAttributes(),
ICDTLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS,
""); //$NON-NLS-1$
if (args.length() != 0) {
args = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(args);
String[] argArray = CommandLineUtil.argumentsToArray(args);
fCommandControl.queueCommand(
fCommandControl.getCommandFactory().createMIGDBSetArgs(getContainerContext(), argArray),
new ImmediateDataRequestMonitor<MIInfo>(rm));
} else {
rm.done();
}
} catch (CoreException e) {
rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot get inferior arguments", e)); //$NON-NLS-1$
rm.done();
}
}
/**
* Specify environment variables if needed
* @since 8.2
*/
@Execute
public void stepSetEnvironmentVariables(RequestMonitor rm) {
boolean clear = false;
Properties properties = new Properties();
try {
// here we need to pass the proper container context
clear = fGDBBackend.getClearEnvironment();
properties = fGDBBackend.getEnvironmentVariables();
} catch (CoreException e) {
rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot get environment information", e)); //$NON-NLS-1$
rm.done();
return;
}
if (clear == true || properties.size() > 0) {
fCommandControl.setEnvironment(properties, clear, rm);
} else {
rm.done();
}
}
/*
* Start tracking the breakpoints once we know we are connected to the target (necessary for remote debugging)
*/
/** @since 8.2 */
@Execute
public void stepStartTrackingBreakpoints(final RequestMonitor rm) {
MIBreakpointsManager bpmService = fTracker.getService(MIBreakpointsManager.class);
bpmService.startTrackingBpForProcess(getContainerContext(), rm);
}
/*
* Set the program counter
*/
/** @since 8.2 */
@Execute
public void stepSetProgramCounter(final RequestMonitor rm) {
if (CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_SET_PC_REGISTER, IGDBJtagConstants.DEFAULT_SET_PC_REGISTER)) {
String pcRegister = CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_PC_REGISTER, CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_IMAGE_OFFSET, IGDBJtagConstants.DEFAULT_PC_REGISTER));
List<String> commands = new ArrayList<String>();
fGdbJtagDevice.doSetPC(pcRegister, commands);
queueCommands(commands, rm);
} else {
rm.done();
}
}
/*
* Execute the stop script
*/
/** @since 8.2 */
@Execute
public void stepStopScript(final RequestMonitor rm) {
if (CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_SET_STOP_AT, IGDBJtagConstants.DEFAULT_SET_STOP_AT)) {
String stopAt = CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_STOP_AT, IGDBJtagConstants.DEFAULT_STOP_AT);
List<String> commands = new ArrayList<String>();
fGdbJtagDevice.doStopAt(stopAt, commands);
queueCommands(commands, rm);
} else {
rm.done();
}
}
/*
* Execute the resume script
*/
/** @since 8.2 */
@Execute
public void stepResumeScript(final RequestMonitor rm) {
if (CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_SET_RESUME, IGDBJtagConstants.DEFAULT_SET_RESUME)) {
List<String> commands = new ArrayList<String>();
fGdbJtagDevice.doContinue(commands);
queueCommands(commands, rm);
} else {
rm.done();
}
}
/*
* Run any user defined commands to start debugging
*/
/** @since 8.2 */
@Execute
public void stepUserDebugCommands(final RequestMonitor rm) {
try {
String userCmd = CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_RUN_COMMANDS, IGDBJtagConstants.DEFAULT_RUN_COMMANDS);
if (userCmd.length() > 0) {
userCmd = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(userCmd);
String[] commands = userCmd.split("\\r?\\n"); //$NON-NLS-1$
CountingRequestMonitor crm = new CountingRequestMonitor(getExecutor(), rm);
crm.setDoneCount(commands.length);
for (int i = 0; i < commands.length; ++i) {
fCommandControl.queueCommand(
new CLICommand<MIInfo>(fCommandControl.getContext(), commands[i]),
new DataRequestMonitor<MIInfo>(getExecutor(), crm));
}
}
else {
rm.done();
}
} catch (CoreException e) {
rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot run user defined run commands", e)); //$NON-NLS-1$
rm.done();
}
}
private IGDBJtagDevice getGDBJtagDevice () {
IGDBJtagDevice gdbJtagDevice = null;
String jtagDeviceName = CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_JTAG_DEVICE, IGDBJtagConstants.DEFAULT_JTAG_DEVICE);
GDBJtagDeviceContribution[] availableDevices = GDBJtagDeviceContributionFactory.getInstance().getGDBJtagDeviceContribution();
for (GDBJtagDeviceContribution availableDevice : availableDevices) {
if (jtagDeviceName.equals(availableDevice.getDeviceName())) {
gdbJtagDevice = availableDevice.getDevice();
break;
}
}
return gdbJtagDevice;
}
/**
* @param commands
* @return String commands in String format
*/
private String composeCommand(Collection<String> commands) {
if (commands.isEmpty())
return null;
StringBuffer sb = new StringBuffer();
Iterator<String> it = commands.iterator();
while (it.hasNext()) {
sb.append(it.next());
}
return sb.toString();
}
/**
* Cleanup now that the sequence has been run.
* @since 8.2
*/
@Execute
public void stepJTAGCleanup(final RequestMonitor requestMonitor) {
fTracker.dispose();
fTracker = null;
requestMonitor.done();
}
/**
* Initialize the memory service with the data for given process.
* @since 8.3
*/
@Execute
public void stepInitializeMemory(final RequestMonitor rm) {
IGDBMemory memory = fTracker.getService(IGDBMemory.class);
IMemoryDMContext memContext = DMContexts.getAncestorOfType(getContainerContext(), IMemoryDMContext.class);
if (memory == null || memContext == null) {
rm.done();
return;
}
memory.initializeMemoryData(memContext, rm);
}
}