diff options
author | Alena Laskavaia | 2010-03-11 15:39:03 +0000 |
---|---|---|
committer | Alena Laskavaia | 2010-03-11 15:39:03 +0000 |
commit | 4deee6b2186e3e512d4d9d3d8467a7898ea207cc (patch) | |
tree | 3f701a642818eab4bc9ca392be5bacd1ee10194a | |
parent | 53b6af27b0b523a0177dfcff2ceaca477789a91a (diff) | |
download | org.eclipse.cdt-4deee6b2186e3e512d4d9d3d8467a7898ea207cc.tar.gz org.eclipse.cdt-4deee6b2186e3e512d4d9d3d8467a7898ea207cc.tar.xz org.eclipse.cdt-4deee6b2186e3e512d4d9d3d8467a7898ea207cc.zip |
[248593] - dsf-gdb integration for jTag launch (applied patch)
8 files changed, 829 insertions, 15 deletions
diff --git a/jtag/org.eclipse.cdt.debug.gdbjtag.core/META-INF/MANIFEST.MF b/jtag/org.eclipse.cdt.debug.gdbjtag.core/META-INF/MANIFEST.MF index cdc9e7f7527..127b0f2202f 100644 --- a/jtag/org.eclipse.cdt.debug.gdbjtag.core/META-INF/MANIFEST.MF +++ b/jtag/org.eclipse.cdt.debug.gdbjtag.core/META-INF/MANIFEST.MF @@ -11,7 +11,9 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.cdt.debug.core, org.eclipse.cdt.debug.mi.core, org.eclipse.cdt.core, - org.eclipse.core.variables + org.eclipse.core.variables, + org.eclipse.cdt.dsf.gdb, + org.eclipse.cdt.dsf Eclipse-LazyStart: true Export-Package: org.eclipse.cdt.debug.gdbjtag.core, org.eclipse.cdt.debug.gdbjtag.core.jtagdevice diff --git a/jtag/org.eclipse.cdt.debug.gdbjtag.core/plugin.properties b/jtag/org.eclipse.cdt.debug.gdbjtag.core/plugin.properties index fcec69ff003..11c30f76c87 100644 --- a/jtag/org.eclipse.cdt.debug.gdbjtag.core/plugin.properties +++ b/jtag/org.eclipse.cdt.debug.gdbjtag.core/plugin.properties @@ -14,3 +14,8 @@ pluginName=Eclipse GDB Hardware Debug Core Plug-in providerName=Eclipse CDT JTagDevice.name=JTAG Device + +launchDelegate.jtag.name=Standard GDB Hardware Debugging +launchDelegate.jtag.description=Jtag hardware debugging using the standard debugger Framework (CDI). +launchDelegate.jtagDsf.name=GDB (DSF) Hardware Debugging +launchDelegate.jtagDsf.description=Jtag hardware debugging using the Debugger Services Framework (DSF). diff --git a/jtag/org.eclipse.cdt.debug.gdbjtag.core/plugin.xml b/jtag/org.eclipse.cdt.debug.gdbjtag.core/plugin.xml index 3a4dff0fec8..f661d7db273 100644 --- a/jtag/org.eclipse.cdt.debug.gdbjtag.core/plugin.xml +++ b/jtag/org.eclipse.cdt.debug.gdbjtag.core/plugin.xml @@ -6,6 +6,8 @@ point="org.eclipse.debug.core.launchConfigurationTypes"> <launchConfigurationType delegate="org.eclipse.cdt.debug.gdbjtag.core.GDBJtagLaunchConfigurationDelegate" + delegateDescription="%launchDelegate.jtag.description" + delegateName="%launchDelegate.jtag.name" id="org.eclipse.cdt.debug.gdbjtag.launchConfigurationType" modes="debug" name="%launchConfig.name" @@ -13,5 +15,18 @@ sourceLocatorId="org.eclipse.cdt.debug.core.sourceLocator" sourcePathComputerId="org.eclipse.cdt.debug.core.sourcePathComputer"/> </extension> + <extension + point="org.eclipse.debug.core.launchDelegates"> + <launchDelegate + delegate="org.eclipse.cdt.debug.gdbjtag.core.GDBJtagDSFLaunchConfigurationDelegate" + delegateDescription="%launchDelegate.jtagDsf.description" + id="org.eclipse.cdt.dsf.gdb.launch.jtagCLaunch" + modes="debug" + name="%launchDelegate.jtagDsf.name" + sourceLocatorId="org.eclipse.cdt.debug.core.sourceLocator" + sourcePathComputerId="org.eclipse.cdt.debug.core.sourcePathComputer" + type="org.eclipse.cdt.debug.gdbjtag.launchConfigurationType"> + </launchDelegate> + </extension> </plugin> diff --git a/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/Activator.java b/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/Activator.java index fdad83e91be..04dc5d9c3ee 100644 --- a/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/Activator.java +++ b/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/Activator.java @@ -8,6 +8,7 @@ * Contributors: * QNX Software Systems - initial API and implementation * Andy Jin - Hardware debugging UI improvements, bug 229946 + * Andy Jin (QNX) - Added DSF debugging, bug 248593 *******************************************************************************/ package org.eclipse.cdt.debug.gdbjtag.core; @@ -25,7 +26,7 @@ public class Activator extends Plugin { // The shared instance private static Activator plugin; - + /** * The constructor */ @@ -35,14 +36,6 @@ public class Activator extends Plugin { /* * (non-Javadoc) - * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) - */ - public void start(BundleContext context) throws Exception { - super.start(context); - } - - /* - * (non-Javadoc) * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) */ public void stop(BundleContext context) throws Exception { @@ -65,14 +58,18 @@ public class Activator extends Plugin { public static String getUniqueIdentifier() { return PLUGIN_ID; } - + + public static BundleContext getBundleContext() { + return getDefault().getBundle().getBundleContext(); + } + /** * Logs the specified status with this plug-in's log. * * @param status status to log */ - public static void log( IStatus status ) { - getDefault().getLog().log( status ); + public static void log(IStatus status) { + getDefault().getLog().log(status); } - + } diff --git a/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/GDBJtagDSFFinalLaunchSequence.java b/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/GDBJtagDSFFinalLaunchSequence.java new file mode 100644 index 00000000000..e5c3c8812df --- /dev/null +++ b/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/GDBJtagDSFFinalLaunchSequence.java @@ -0,0 +1,741 @@ +/******************************************************************************* + * Copyright (c) 2007 - 2010 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 (Andy Jin) - Initial implementation for Jtag debugging + *******************************************************************************/ +package org.eclipse.cdt.debug.gdbjtag.core; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; + +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.debug.internal.core.sourcelookup.CSourceLookupDirector; +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.DsfExecutor; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.concurrent.Sequence; +import org.eclipse.cdt.dsf.datamodel.DataModelInitializedEvent; +import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext; +import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants; +import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch; +import org.eclipse.cdt.dsf.gdb.launching.LaunchMessages; +import org.eclipse.cdt.dsf.gdb.service.IGDBBackend; +import org.eclipse.cdt.dsf.gdb.service.SessionType; +import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl; +import org.eclipse.cdt.dsf.mi.service.CSourceLookup; +import org.eclipse.cdt.dsf.mi.service.IMIProcesses; +import org.eclipse.cdt.dsf.mi.service.MIBreakpointsManager; +import org.eclipse.cdt.dsf.mi.service.command.CommandFactory; +import org.eclipse.cdt.dsf.mi.service.command.commands.CLICommand; +import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; +import org.eclipse.cdt.dsf.service.DsfServicesTracker; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.variables.VariablesPlugin; +import org.eclipse.debug.core.ILaunchConfiguration; + +/** + * 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> + */ +public class GDBJtagDSFFinalLaunchSequence extends Sequence { + + Step[] fSteps = new Step[] { + /* + * Create the service tracker for later use + */ + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + fTracker = new DsfServicesTracker(Activator.getBundleContext(), fLaunch.getSession().getId()); + requestMonitor.done(); + } + @Override + public void rollBack(RequestMonitor requestMonitor) { + if (fTracker != null) fTracker.dispose(); + fTracker = null; + requestMonitor.done(); + }}, + /* + * Fetch the GDBBackend service for later use + */ + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + fGDBBackend = fTracker.getService(IGDBBackend.class); + if (fGDBBackend == null) { + requestMonitor.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot obtain GDBBackend service", null)); //$NON-NLS-1$ + } + + requestMonitor.done(); + }}, + /* + * Fetch the control service for later use + */ + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + fCommandControl = fTracker.getService(IGDBControl.class); + if (fCommandControl == null) { + requestMonitor.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot obtain control service", null)); //$NON-NLS-1$ + } + + fCommandFactory = fCommandControl.getCommandFactory(); + + requestMonitor.done(); + }}, + /* + * Fetch the process service for later use + */ + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + fProcService = fTracker.getService(IMIProcesses.class); + if (fProcService == null) { + requestMonitor.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot obtain process service", null)); //$NON-NLS-1$ + } + + requestMonitor.done(); + }}, + /* + * Source the gdbinit file specified in the launch + */ + new Step() { @Override + public void execute(final RequestMonitor requestMonitor) { + try { + final String gdbinitFile = fGDBBackend.getGDBInitFile(); + + if (gdbinitFile != null && gdbinitFile.length() > 0) { + fCommandControl.queueCommand( + fCommandFactory.createCLISource(fCommandControl.getContext(), gdbinitFile), + new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor) { + @Override + protected void handleCompleted() { + // If the gdbinitFile is the default, then it may not exist and we + // should not consider this an error. + // If it is not the default, then the user must have specified it and + // we want to warn the user if we can't find it. + if (!gdbinitFile.equals(IGDBLaunchConfigurationConstants.DEBUGGER_GDB_INIT_DEFAULT )) { + requestMonitor.setStatus(getStatus()); + } + requestMonitor.done(); + } + }); + } else { + requestMonitor.done(); + } + } catch (CoreException e) { + requestMonitor.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot get gdbinit option", e)); //$NON-NLS-1$ + requestMonitor.done(); + } + }}, + /* + * Specify the arguments to the executable file + */ + new Step() { @Override + public void execute(final RequestMonitor requestMonitor) { + try { + String args = fGDBBackend.getProgramArguments(); + + if (args != null) { + fCommandControl.queueCommand( + fCommandFactory.createMIGDBSetArgs(fCommandControl.getContext(), args), + new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor)); + } else { + requestMonitor.done(); + } + } catch (CoreException e) { + requestMonitor.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot get inferior arguments", e)); //$NON-NLS-1$ + requestMonitor.done(); + } + }}, + /* + * Specify GDB's working directory + */ + new Step() { @Override + public void execute(final RequestMonitor requestMonitor) { + IPath dir = null; + try { + dir = fGDBBackend.getGDBWorkingDirectory(); + } catch (CoreException e) { + requestMonitor.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot get working directory", e)); //$NON-NLS-1$ + requestMonitor.done(); + return; + } + + if (dir != null) { + fCommandControl.queueCommand( + fCommandFactory.createMIEnvironmentCD(fCommandControl.getContext(), dir.toPortableString()), + new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor)); + } else { + requestMonitor.done(); + } + }}, + /* + * Specify environment variables if needed + */ + new Step() { @Override + public void execute(final RequestMonitor requestMonitor) { + boolean clear = false; + Properties properties = new Properties(); + try { + clear = fGDBBackend.getClearEnvironment(); + properties = fGDBBackend.getEnvironmentVariables(); + } catch (CoreException e) { + requestMonitor.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot get environment information", e)); //$NON-NLS-1$ + requestMonitor.done(); + return; + } + + if (clear == true || properties.size() > 0) { + fCommandControl.setEnvironment(properties, clear, requestMonitor); + } else { + requestMonitor.done(); + } + }}, + /* + * Enable non-stop mode if necessary + */ + new Step() { @Override + public void execute(final RequestMonitor requestMonitor) { + boolean isNonStop = false; + try { + isNonStop = fLaunch.getLaunchConfiguration().getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP, + IGDBLaunchConfigurationConstants.DEBUGGER_NON_STOP_DEFAULT); + } catch (CoreException e) { + } + + // GDBs that don't support non-stop don't allow you to set it to false. + // We really should set it to false when GDB supports it though. + // Something to fix later. + if (isNonStop) { + // The raw commands should not be necessary in the official GDB release + fCommandControl.queueCommand( + fCommandFactory.createMIGDBSetTargetAsync(fCommandControl.getContext(), true), + new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor) { + @Override + protected void handleSuccess() { + fCommandControl.queueCommand( + fCommandFactory.createMIGDBSetPagination(fCommandControl.getContext(), false), + new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor) { + @Override + protected void handleSuccess() { + fCommandControl.queueCommand( + fCommandFactory.createMIGDBSetNonStop(fCommandControl.getContext(), true), + new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor)); + } + }); + } + }); + } else { + requestMonitor.done(); + } + }}, + /* + * Tell GDB to automatically load or not the shared library symbols + */ + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + try { + boolean autolib = fLaunch.getLaunchConfiguration().getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_AUTO_SOLIB, + IGDBLaunchConfigurationConstants.DEBUGGER_AUTO_SOLIB_DEFAULT); + fCommandControl.queueCommand( + fCommandFactory.createMIGDBSetAutoSolib(fCommandControl.getContext(), autolib), + new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor)); + } catch (CoreException e) { + requestMonitor.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot set shared library option", e)); //$NON-NLS-1$ + requestMonitor.done(); + } + }}, + /* + * Set the shared library paths + */ + new Step() { @Override + public void execute(final RequestMonitor requestMonitor) { + try { + List<String> p = fGDBBackend.getSharedLibraryPaths(); + + if (p.size() > 0) { + String[] paths = p.toArray(new String[p.size()]); + fCommandControl.queueCommand( + fCommandFactory.createMIGDBSetSolibSearchPath(fCommandControl.getContext(), paths), + new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor) { + @Override + protected void handleSuccess() { + // Sysroot is not available in GDB6.6 and will make the launch fail in that case. + // Let's remove it for now + requestMonitor.done(); +// // If we are able to set the solib-search-path, +// // we should disable the sysroot variable, as indicated +// // in the GDB documentation. This is to avoid the sysroot +// // variable finding libraries that were not meant to be found. +// fCommandControl.queueCommand( +// new MIGDBSetSysroot(fCommandControl.getContext()), +// new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor)); + }; + }); + } else { + requestMonitor.done(); + } + } catch (CoreException e) { + requestMonitor.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot set share library paths", e)); //$NON-NLS-1$ + requestMonitor.done(); + } + }}, + /* + * Setup the source paths + */ + new Step() { @Override + public void execute(RequestMonitor requestMonitor) { + CSourceLookup sourceLookup = fTracker.getService(CSourceLookup.class); + CSourceLookupDirector locator = (CSourceLookupDirector)fLaunch.getSourceLocator(); + ISourceLookupDMContext sourceLookupDmc = (ISourceLookupDMContext)fCommandControl.getContext(); + + sourceLookup.setSourceLookupPath(sourceLookupDmc, locator.getSourceContainers(), requestMonitor); + }}, + + // Below steps are specific to JTag hardware debugging + + /* + * Retrieve the JTag device + */ + new Step() { + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.concurrent.Sequence.Step#execute(org.eclipse.cdt.dsf.concurrent.RequestMonitor) + */ + @Override + public void execute(RequestMonitor rm) { + try { + fGdbJtagDevice = getGDBJtagDevice(fLaunch.getLaunchConfiguration()); + } catch (NullPointerException e) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot get Jtag device", e)); //$NON-NLS-1$ + } catch (CoreException e) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot get Jtag device", e)); //$NON-NLS-1$ + } + rm.done(); + } + }, + /* + * Hook up to remote target + */ + new Step() { + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.concurrent.Sequence.Step#execute(org.eclipse.cdt.dsf.concurrent.RequestMonitor) + */ + @Override + public void execute(RequestMonitor rm) { + if (fGdbJtagDevice != null) { + + ILaunchConfiguration config = fLaunch.getLaunchConfiguration(); + try { + if (config.getAttribute(IGDBJtagConstants.ATTR_USE_REMOTE_TARGET, IGDBJtagConstants.DEFAULT_USE_REMOTE_TARGET)) { + String ipAddress = config.getAttribute(IGDBJtagConstants.ATTR_IP_ADDRESS, IGDBJtagConstants.DEFAULT_IP_ADDRESS); + int portNumber = config.getAttribute(IGDBJtagConstants.ATTR_PORT_NUMBER, IGDBJtagConstants.DEFAULT_PORT_NUMBER); + ArrayList<String> commands = new ArrayList<String>(); + fGdbJtagDevice.doRemote(ipAddress, portNumber, commands); + fCommandControl.queueCommand( + new CLICommand<MIInfo>(fCommandControl.getContext(), composeCommand(commands)), + new DataRequestMonitor<MIInfo>(getExecutor(), rm)); + } + } catch (CoreException e) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot connect to remote target", e)); //$NON-NLS-1$ + rm.done(); + } + } + } + }, + /* + * Run device-specific code to reset the board + */ + new Step() { + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.concurrent.Sequence.Step#execute(org.eclipse.cdt.dsf.concurrent.RequestMonitor) + */ + @Override + public void execute(RequestMonitor rm) { + if (fGdbJtagDevice != null) { + ILaunchConfiguration config = fLaunch.getLaunchConfiguration(); + try { + if (config.getAttribute(IGDBJtagConstants.ATTR_DO_RESET, true)) { + ArrayList<String> commands = new ArrayList<String>(); + fGdbJtagDevice.doReset(commands); + fCommandControl.queueCommand( + new CLICommand<MIInfo>(fCommandControl.getContext(), composeCommand(commands)), + new DataRequestMonitor<MIInfo>(getExecutor(), rm)); + } + } catch (CoreException e) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot reset the remote target", e)); //$NON-NLS-1$ + rm.done(); + } + } + } + }, + /* + * Run device-specific code to delay the startup + */ + new Step() { + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.concurrent.Sequence.Step#execute(org.eclipse.cdt.dsf.concurrent.RequestMonitor) + */ + @Override + public void execute(RequestMonitor rm) { + if (fGdbJtagDevice != null) { + ILaunchConfiguration config = fLaunch.getLaunchConfiguration(); + int defaultDelay = fGdbJtagDevice.getDefaultDelay(); + try { + ArrayList<String> commands = new ArrayList<String>(); + fGdbJtagDevice.doDelay(config.getAttribute(IGDBJtagConstants.ATTR_DELAY, defaultDelay), commands); + fCommandControl.queueCommand( + new CLICommand<MIInfo>(fCommandControl.getContext(), composeCommand(commands)), + new DataRequestMonitor<MIInfo>(getExecutor(), rm)); + } catch (CoreException e) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot delay the remote target", e)); //$NON-NLS-1$ + rm.done(); + } + } + } + }, + /* + * Run device-specific code to halt the board + */ + new Step() { + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.concurrent.Sequence.Step#execute(org.eclipse.cdt.dsf.concurrent.RequestMonitor) + */ + @Override + public void execute(RequestMonitor rm) { + if (fGdbJtagDevice != null) { + ILaunchConfiguration config = fLaunch.getLaunchConfiguration(); + try { + if (config.getAttribute(IGDBJtagConstants.ATTR_DO_HALT, true)) { + ArrayList<String> commands = new ArrayList<String>(); + fGdbJtagDevice.doHalt(commands); + fCommandControl.queueCommand( + new CLICommand<MIInfo>(fCommandControl.getContext(), composeCommand(commands)), + new DataRequestMonitor<MIInfo>(getExecutor(), rm)); + } + } catch (CoreException e) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot halt the remote target", e)); //$NON-NLS-1$ + rm.done(); + } + } + } + }, + /* + * Execute any user defined init commands + */ + new Step() { + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.concurrent.Sequence.Step#execute(org.eclipse.cdt.dsf.concurrent.RequestMonitor) + */ + @Override + public void execute(RequestMonitor rm) { + if (fGdbJtagDevice != null) { + ILaunchConfiguration config = fLaunch.getLaunchConfiguration(); + try { + String userCmd = config.getAttribute(IGDBJtagConstants.ATTR_INIT_COMMANDS, ""); //$NON-NLS-1$ + userCmd = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(userCmd); + String[] commands = userCmd.split("\\r?\\n"); //$NON-NLS-1$ + for (int i = 0; i < commands.length; ++i) { + fCommandControl.queueCommand( + new CLICommand<MIInfo>(fCommandControl.getContext(), commands[i]), + new DataRequestMonitor<MIInfo>(getExecutor(), rm)); + } + } 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 + */ + new Step() { + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.concurrent.Sequence.Step#execute(org.eclipse.cdt.dsf.concurrent.RequestMonitor) + */ + @Override + public void execute(RequestMonitor rm) { + if (fGdbJtagDevice != null) { + ILaunchConfiguration config = fLaunch.getLaunchConfiguration(); + try { + if (config.getAttribute(IGDBJtagConstants.ATTR_LOAD_IMAGE, IGDBJtagConstants.DEFAULT_LOAD_IMAGE)) { + // Escape windows path separator characters TWICE, once for Java and once for GDB. + String imageFileName = config.getAttribute(IGDBJtagConstants.ATTR_IMAGE_FILE_NAME, ""); //$NON-NLS-1$ + if (imageFileName.length() > 0) { + imageFileName = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(imageFileName).replace("\\", "\\\\"); //$NON-NLS-1$ //$NON-NLS-2$ + String imageOffset = (imageFileName.endsWith(".elf")) ? "" : "0x" + config.getAttribute(IGDBJtagConstants.ATTR_IMAGE_OFFSET, ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + ArrayList<String> commands = new ArrayList<String>(); + fGdbJtagDevice.doLoadImage(imageFileName, imageOffset, commands); + fCommandControl.queueCommand( + new CLICommand<MIInfo>(fCommandControl.getContext(), composeCommand(commands)), + new DataRequestMonitor<MIInfo>(getExecutor(), rm)); + } + } + } catch (CoreException e) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot load image", e)); //$NON-NLS-1$ + rm.done(); + } + } + } + }, + /* + * Execute symbol loading + */ + new Step() { + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.concurrent.Sequence.Step#execute(org.eclipse.cdt.dsf.concurrent.RequestMonitor) + */ + @Override + public void execute(RequestMonitor rm) { + if (fGdbJtagDevice != null) { + ILaunchConfiguration config = fLaunch.getLaunchConfiguration(); + try { + if (config.getAttribute(IGDBJtagConstants.ATTR_LOAD_SYMBOLS, IGDBJtagConstants.DEFAULT_LOAD_SYMBOLS)) { + // Escape windows path separator characters TWICE, once for Java and once for GDB. + String symbolsFileName = config.getAttribute(IGDBJtagConstants.ATTR_SYMBOLS_FILE_NAME, ""); //$NON-NLS-1$ + if (symbolsFileName.length() > 0) { + symbolsFileName = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(symbolsFileName).replace("\\", "\\\\"); //$NON-NLS-1$ //$NON-NLS-2$ + String symbolsOffset = "0x" + config.getAttribute(IGDBJtagConstants.ATTR_SYMBOLS_OFFSET, ""); //$NON-NLS-1$ //$NON-NLS-2$ + ArrayList<String> commands = new ArrayList<String>(); + fGdbJtagDevice.doLoadSymbol(symbolsFileName, symbolsOffset, commands); + fCommandControl.queueCommand( + new CLICommand<MIInfo>(fCommandControl.getContext(), composeCommand(commands)), + new DataRequestMonitor<MIInfo>(getExecutor(), rm)); + } + } + } catch (CoreException e) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot load symbol", e)); //$NON-NLS-1$ + rm.done(); + } + } + } + }, + /* + * Start tracking the breakpoints once we know we are connected to the target (necessary for remote debugging) + */ + new Step() { @Override + public void execute(final RequestMonitor requestMonitor) { + if (fSessionType != SessionType.CORE) { + MIBreakpointsManager bpmService = fTracker.getService(MIBreakpointsManager.class); + IBreakpointsTargetDMContext breakpointDmc = (IBreakpointsTargetDMContext)fCommandControl.getContext(); + + bpmService.startTrackingBreakpoints(breakpointDmc, requestMonitor); + } else { + requestMonitor.done(); + } + }}, + /* + * Set the program counter + */ + new Step() { + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.concurrent.Sequence.Step#execute(org.eclipse.cdt.dsf.concurrent.RequestMonitor) + */ + @Override + public void execute(RequestMonitor rm) { + if (fGdbJtagDevice != null) { + ILaunchConfiguration config = fLaunch.getLaunchConfiguration(); + try { + if (config.getAttribute(IGDBJtagConstants.ATTR_SET_PC_REGISTER, IGDBJtagConstants.DEFAULT_SET_PC_REGISTER)) { + String pcRegister = config.getAttribute(IGDBJtagConstants.ATTR_PC_REGISTER, config.getAttribute(IGDBJtagConstants.ATTR_IMAGE_OFFSET, "")); //$NON-NLS-1$ + ArrayList<String> commands = new ArrayList<String>(); + fGdbJtagDevice.doSetPC(pcRegister, commands); + fCommandControl.queueCommand( + new CLICommand<MIInfo>(fCommandControl.getContext(), composeCommand(commands)), + new DataRequestMonitor<MIInfo>(getExecutor(), rm)); + } + } catch (CoreException e) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot set program counter", e)); //$NON-NLS-1$ + rm.done(); + } + } + } + }, + /* + * Execute the stop script + */ + new Step() { + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.concurrent.Sequence.Step#execute(org.eclipse.cdt.dsf.concurrent.RequestMonitor) + */ + @Override + public void execute(RequestMonitor rm) { + if (fGdbJtagDevice != null) { + ILaunchConfiguration config = fLaunch.getLaunchConfiguration(); + try { + if (config.getAttribute(IGDBJtagConstants.ATTR_SET_STOP_AT, IGDBJtagConstants.DEFAULT_SET_STOP_AT)) { + String stopAt = config.getAttribute(IGDBJtagConstants.ATTR_STOP_AT, ""); //$NON-NLS-1$ + ArrayList<String> commands = new ArrayList<String>(); + fGdbJtagDevice.doStopAt(stopAt, commands); + fCommandControl.queueCommand( + new CLICommand<MIInfo>(fCommandControl.getContext(), composeCommand(commands)), + new DataRequestMonitor<MIInfo>(getExecutor(), rm)); + } + } catch (CoreException e) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot run the stop script", e)); //$NON-NLS-1$ + rm.done(); + } + } + } + }, + /* + * Execute the resume script + */ + new Step() { + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.concurrent.Sequence.Step#execute(org.eclipse.cdt.dsf.concurrent.RequestMonitor) + */ + @Override + public void execute(RequestMonitor rm) { + if (fGdbJtagDevice != null) { + ILaunchConfiguration config = fLaunch.getLaunchConfiguration(); + try { + if (config.getAttribute(IGDBJtagConstants.ATTR_SET_RESUME, IGDBJtagConstants.DEFAULT_SET_RESUME)) { + ArrayList<String> commands = new ArrayList<String>(); + fGdbJtagDevice.doContinue(commands); + fCommandControl.queueCommand( + new CLICommand<MIInfo>(fCommandControl.getContext(), composeCommand(commands)), + new DataRequestMonitor<MIInfo>(getExecutor(), rm)); + } + } catch (CoreException e) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot resume the remote target", e)); //$NON-NLS-1$ + rm.done(); + } + } + } + }, + /* + * Run any user defined commands to start debugging + */ + new Step() { + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.concurrent.Sequence.Step#execute(org.eclipse.cdt.dsf.concurrent.RequestMonitor) + */ + @Override + public void execute(RequestMonitor rm) { + if (fGdbJtagDevice != null) { + ILaunchConfiguration config = fLaunch.getLaunchConfiguration(); + try { + String userCmd = config.getAttribute(IGDBJtagConstants.ATTR_RUN_COMMANDS, ""); //$NON-NLS-1$ + userCmd = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(userCmd); + String[] commands = userCmd.split("\\r?\\n"); //$NON-NLS-1$ + for (int i = 0; i < commands.length; ++i) { + fCommandControl.queueCommand( + new CLICommand<MIInfo>(fCommandControl.getContext(), commands[i]), + new DataRequestMonitor<MIInfo>(getExecutor(), rm)); + } + } 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(); + } + } + } + }, + + /* + * Indicate that the Data Model has been filled. This will trigger the Debug view to expand. + */ + new Step() { + @Override + public void execute(final RequestMonitor requestMonitor) { + fLaunch.getSession().dispatchEvent(new DataModelInitializedEvent(fCommandControl.getContext()), + fCommandControl.getProperties()); + requestMonitor.done(); + } + }, + /* + * Cleanup + */ + new Step() { + @Override + public void execute(final RequestMonitor requestMonitor) { + fTracker.dispose(); + fTracker = null; + requestMonitor.done(); + } + }, + }; + + GdbLaunch fLaunch; + SessionType fSessionType; + boolean fAttach; + + private IGDBControl fCommandControl; + private IGDBBackend fGDBBackend; + private IMIProcesses fProcService; + private CommandFactory fCommandFactory; + private IGDBJtagDevice fGdbJtagDevice; + + DsfServicesTracker fTracker; + + public GDBJtagDSFFinalLaunchSequence(DsfExecutor executor, GdbLaunch launch, SessionType sessionType, boolean attach, IProgressMonitor pm) { + super(executor, pm, LaunchMessages.getString("FinalLaunchSequence.0"), LaunchMessages.getString("FinalLaunchSequence.1")); //$NON-NLS-1$ //$NON-NLS-2$ + fLaunch = launch; + fSessionType = sessionType; + fAttach = attach; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.gdb.launching.FinalLaunchSequence#getSteps() + */ + @Override + public Step[] getSteps() { + return fSteps; + } + + /** + * @param config + * @return IGDBJtagDevice the selected Jtag device + * @throws CoreException + * @throws NullPointerException + */ + private IGDBJtagDevice getGDBJtagDevice (ILaunchConfiguration config) + throws CoreException, NullPointerException { + IGDBJtagDevice gdbJtagDevice = null; + String jtagDeviceName = config.getAttribute(IGDBJtagConstants.ATTR_JTAG_DEVICE, ""); //$NON-NLS-1$ + GDBJtagDeviceContribution[] availableDevices = GDBJtagDeviceContributionFactory. + getInstance().getGDBJtagDeviceContribution(); + for (int i = 0; i < availableDevices.length; i++) { + if (jtagDeviceName.equals(availableDevices[i].getDeviceName())) { + gdbJtagDevice = availableDevices[i].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(); + } +} diff --git a/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/GDBJtagDSFLaunchConfigurationDelegate.java b/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/GDBJtagDSFLaunchConfigurationDelegate.java new file mode 100644 index 00000000000..6bc2f2065f9 --- /dev/null +++ b/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/GDBJtagDSFLaunchConfigurationDelegate.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2007 - 2010 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: + * QNX Software Systems - Initial implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.gdbjtag.core; + +/** + * @author Andy Jin + * + */ + +import org.eclipse.cdt.dsf.concurrent.DsfExecutor; +import org.eclipse.cdt.dsf.concurrent.Sequence; +import org.eclipse.cdt.dsf.concurrent.ThreadSafe; +import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch; +import org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate; +import org.eclipse.cdt.dsf.gdb.service.SessionType; +import org.eclipse.core.runtime.IProgressMonitor; + +/** + * The launch configuration delegate for the Jtag hardware debugging using + * the DSF/GDB debugger framework. + * <p> + * This delegate only supports the org.eclipse.cdt.debug.gdbjtag.launchConfigurationType + * launch configuration types. + * <p> + * It extends the standard DSF/GDB launch delegate <code>GdbLaunchDelegate</code> + * but overrides the <code>getFinalLaunchSequence</code> method to return the Jtag + * hardware debugging specific launch sequence. + */ +@ThreadSafe +public class GDBJtagDSFLaunchConfigurationDelegate extends GdbLaunchDelegate { + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate#getFinalLaunchSequence(org.eclipse.cdt.dsf.concurrent.DsfExecutor, org.eclipse.cdt.dsf.gdb.launching.GdbLaunch, org.eclipse.cdt.dsf.gdb.service.SessionType, boolean, org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + protected Sequence getFinalLaunchSequence(DsfExecutor executor, + GdbLaunch launch, SessionType type, boolean attach, + IProgressMonitor pm) { + return new GDBJtagDSFFinalLaunchSequence(executor, launch, type, attach, pm); + } + +} diff --git a/jtag/org.eclipse.cdt.debug.gdbjtag.ui/META-INF/MANIFEST.MF b/jtag/org.eclipse.cdt.debug.gdbjtag.ui/META-INF/MANIFEST.MF index 745a372d9c6..b48296e1fcb 100644 --- a/jtag/org.eclipse.cdt.debug.gdbjtag.ui/META-INF/MANIFEST.MF +++ b/jtag/org.eclipse.cdt.debug.gdbjtag.ui/META-INF/MANIFEST.MF @@ -16,7 +16,8 @@ Require-Bundle: org.eclipse.ui, org.eclipse.core.variables, org.eclipse.cdt.managedbuilder.ui, org.eclipse.ui.ide, - org.eclipse.cdt.debug.core + org.eclipse.cdt.debug.core, + org.eclipse.cdt.dsf.gdb Eclipse-LazyStart: true Bundle-Vendor: %providerName Export-Package: org.eclipse.cdt.debug.gdbjtag.ui diff --git a/jtag/org.eclipse.cdt.debug.gdbjtag.ui/src/org/eclipse/cdt/debug/gdbjtag/ui/GDBJtagDebuggerTab.java b/jtag/org.eclipse.cdt.debug.gdbjtag.ui/src/org/eclipse/cdt/debug/gdbjtag/ui/GDBJtagDebuggerTab.java index 3be698dd72f..937412e49d8 100644 --- a/jtag/org.eclipse.cdt.debug.gdbjtag.ui/src/org/eclipse/cdt/debug/gdbjtag/ui/GDBJtagDebuggerTab.java +++ b/jtag/org.eclipse.cdt.debug.gdbjtag.ui/src/org/eclipse/cdt/debug/gdbjtag/ui/GDBJtagDebuggerTab.java @@ -9,6 +9,7 @@ * QNX Software Systems - Initial API and implementation * Andy Jin - Hardware debugging UI improvements, bug 229946 * Anna Dushistova(MontaVista) - Hardware Debugging: Host name or ip address not saving in the debug configuration, bug 241279 + * Andy Jin (QNX) - Added DSF debugging, bug 248593 *******************************************************************************/ package org.eclipse.cdt.debug.gdbjtag.ui; @@ -24,6 +25,7 @@ import org.eclipse.cdt.debug.mi.core.IMILaunchConfigurationConstants; import org.eclipse.cdt.debug.mi.core.MIPlugin; import org.eclipse.cdt.debug.mi.core.command.factories.CommandFactoryDescriptor; import org.eclipse.cdt.debug.mi.core.command.factories.CommandFactoryManager; +import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants; import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; @@ -387,6 +389,7 @@ public class GDBJtagDebuggerTab extends AbstractLaunchConfigurationTab { public void performApply(ILaunchConfigurationWorkingCopy configuration) { configuration.setAttribute(IMILaunchConfigurationConstants.ATTR_DEBUG_NAME, gdbCommand.getText().trim()); + configuration.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUG_NAME, gdbCommand.getText().trim()); // DSF configuration.setAttribute(IMILaunchConfigurationConstants.ATTR_DEBUGGER_COMMAND_FACTORY, commandFactory.getText()); configuration.setAttribute(IMILaunchConfigurationConstants.ATTR_DEBUGGER_PROTOCOL, miProtocol.getText()); configuration.setAttribute(IMILaunchConfigurationConstants.ATTR_DEBUGGER_VERBOSE_MODE, verboseMode.getSelection()); |