From 2c82390e875e9e62ae38171b93cf5ffaa2423971 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Tue, 15 Apr 2008 16:38:17 +0000 Subject: [PATCH] Bug 202343 Launch for for Attaching to a running --- plugins/org.eclipse.dd.gdb.launch/plugin.xml | 23 ++++++- .../internal/ui/launching/CDebuggerTab.java | 2 +- .../GdbAttachLaunchConfigurationTabGroup.java | 36 +++++++++++ .../launching/FinalLaunchSequence.java | 60 ++++++++++++------- .../launching/GdbLaunchDelegate.java | 52 +++++++++++++--- .../service/command/commands/CLIAttach.java | 24 ++++++++ .../commands/MIFileExecAndSymbols.java | 35 +++++++++++ 7 files changed, 201 insertions(+), 31 deletions(-) create mode 100644 plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbAttachLaunchConfigurationTabGroup.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIAttach.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileExecAndSymbols.java diff --git a/plugins/org.eclipse.dd.gdb.launch/plugin.xml b/plugins/org.eclipse.dd.gdb.launch/plugin.xml index b6505cd3a7d..2d39667f867 100644 --- a/plugins/org.eclipse.dd.gdb.launch/plugin.xml +++ b/plugins/org.eclipse.dd.gdb.launch/plugin.xml @@ -7,7 +7,7 @@ delegate="org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunchDelegate" public="true" sourcePathComputerId="org.eclipse.cdt.debug.core.sourcePathComputer" - name="Local C/C++ Application (Experimental - DSF)" + name="C/C++ Local Application (Experimental - DSF)" id="org.eclipse.dd.gdb.launch.localCLaunch" modes="debug"> @@ -15,7 +15,16 @@ delegate="org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunchDelegate" id="org.eclipse.dd.gdb.launch.remoteCLaunch" modes="debug" - name="Remote C/C++ Application (Experimental - DSF)" + name="C/C++ Remote Application (Experimental - DSF)" + public="true" + sourceLocatorId="org.eclipse.cdt.debug.core.sourceLocator" + sourcePathComputerId="org.eclipse.cdt.debug.core.sourcePathComputer"> + + @@ -33,6 +42,11 @@ id="org.eclipse.dd.gdb.launch.remoteRunLaunchTabGroup" type="org.eclipse.dd.gdb.launch.remoteCLaunch"> + + @@ -46,5 +60,10 @@ icon="icons/full/obj16/c_app.gif" id="org.eclipse.dd.gdb.launch.remoteRunLaunchImage"> + + diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java index 514b5350e73..a381b9d2b8c 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/CDebuggerTab.java @@ -217,7 +217,7 @@ public class CDebuggerTab extends AbstractCDebuggerTab { (mode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN) && debugConfigs[i].getName().equals("gdb/mi") && debugConfigs[i].supportsMode(mode)) || //$NON-NLS-1$ (mode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH) - && debugConfigs[i].getName().equals("gdb Debugger") && debugConfigs[i].supportsMode(mode))) { //$NON-NLS-1$ + && debugConfigs[i].getName().equals("gdb/mi") && debugConfigs[i].supportsMode(mode))) { //$NON-NLS-1$ String debuggerPlatform = debugConfigs[i].getPlatform(); if (validatePlatform(config, debugConfigs[i])) { list.add(debugConfigs[i]); diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbAttachLaunchConfigurationTabGroup.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbAttachLaunchConfigurationTabGroup.java new file mode 100644 index 00000000000..6f19c451d0f --- /dev/null +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbAttachLaunchConfigurationTabGroup.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2008 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.dd.gdb.internal.ui.launching; + +import org.eclipse.cdt.launch.ui.CMainTab; +import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType; +import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup; +import org.eclipse.debug.ui.CommonTab; +import org.eclipse.debug.ui.ILaunchConfigurationDialog; +import org.eclipse.debug.ui.ILaunchConfigurationTab; +import org.eclipse.debug.ui.sourcelookup.SourceLookupTab; + +public class GdbAttachLaunchConfigurationTabGroup extends AbstractLaunchConfigurationTabGroup { + + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.ILaunchConfigurationTabGroup#createTabs(org.eclipse.debug.ui.ILaunchConfigurationDialog, java.lang.String) + */ + public void createTabs(ILaunchConfigurationDialog dialog, String mode) { + ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] { + new CMainTab(true), + new CDebuggerTab(SessionType.ATTACH), + new SourceLookupTab(), + new CommonTab() + }; + setTabs(tabs); + } +} diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java index 1521d46e93c..6d68d6cdc5e 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/FinalLaunchSequence.java @@ -18,6 +18,7 @@ import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; import org.eclipse.cdt.debug.mi.core.IGDBServerMILaunchConfigurationConstants; import org.eclipse.cdt.debug.mi.core.IMILaunchConfigurationConstants; 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.dd.dsf.concurrent.DataRequestMonitor; @@ -37,11 +38,11 @@ import org.eclipse.dd.mi.service.command.commands.MIBreakInsert; import org.eclipse.dd.mi.service.command.commands.MICommand; import org.eclipse.dd.mi.service.command.commands.MIExecContinue; import org.eclipse.dd.mi.service.command.commands.MIExecRun; -import org.eclipse.dd.mi.service.command.commands.MIFileExecFile; -import org.eclipse.dd.mi.service.command.commands.MIFileSymbolFile; +import org.eclipse.dd.mi.service.command.commands.MIFileExecAndSymbols; import org.eclipse.dd.mi.service.command.commands.MIGDBSetAutoSolib; import org.eclipse.dd.mi.service.command.commands.MIGDBSetSolibSearchPath; import org.eclipse.dd.mi.service.command.commands.MIInferiorTTYSet; +import org.eclipse.dd.mi.service.command.commands.CLIAttach; import org.eclipse.dd.mi.service.command.commands.MITargetSelect; import org.eclipse.dd.mi.service.command.output.MIBreakInsertInfo; import org.eclipse.dd.mi.service.command.output.MIInfo; @@ -66,6 +67,11 @@ public class FinalLaunchSequence extends Sequence { */ new Step() { @Override public void execute(RequestMonitor requestMonitor) { + if (fSessionType == SessionType.ATTACH) { + requestMonitor.done(); + return; + } + try { boolean useTerminal = fLaunch.getLaunchConfiguration().getAttribute(ICDTLaunchConfigurationConstants.ATTR_USE_TERMINAL, true); @@ -114,24 +120,19 @@ public class FinalLaunchSequence extends Sequence { } }}, /* - * Specify the executable file to be debugged. + * Specify the executable file to be debugged and read the symbol table. */ new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - fCommandControl.queueCommand( - new MIFileExecFile(fCommandControl.getControlDMContext(), - fCommandControl.getExecutablePath().toOSString()), - new DataRequestMonitor(getExecutor(), requestMonitor)); - }}, - /* - * Read symbol table. - */ - new Step() { @Override - public void execute(RequestMonitor requestMonitor) { - fCommandControl.queueCommand( - new MIFileSymbolFile(fCommandControl.getControlDMContext(), - fCommandControl.getExecutablePath().toOSString()), - new DataRequestMonitor(getExecutor(), requestMonitor)); + public void execute(final RequestMonitor requestMonitor) { + final IPath execPath = fCommandControl.getExecutablePath(); + if (execPath != null && !execPath.isEmpty()) { + fCommandControl.queueCommand( + new MIFileExecAndSymbols(fCommandControl.getControlDMContext(), + execPath.toOSString()), + new DataRequestMonitor(getExecutor(), requestMonitor)); + } else { + requestMonitor.done(); + } }}, /* * Tell GDB to automatically load or not the shared library symbols @@ -185,7 +186,8 @@ public class FinalLaunchSequence extends Sequence { locator.getSourceContainers(), requestMonitor); }}, /* - * If remote debugging, connect to target + * If remote debugging, connect to target. + * If attach session, perform the attach. */ new Step() { private boolean fTcpConnection; @@ -241,7 +243,7 @@ public class FinalLaunchSequence extends Sequence { } return true; } - + @Override public void execute(final RequestMonitor requestMonitor) { if (fSessionType == SessionType.REMOTE) { @@ -263,6 +265,10 @@ public class FinalLaunchSequence extends Sequence { fSerialDevice), new DataRequestMonitor(getExecutor(), requestMonitor)); } + } else if (fSessionType == SessionType.ATTACH) { + fCommandControl.queueCommand( + new CLIAttach(fCommandControl.getControlDMContext(), fPid), + new DataRequestMonitor(getExecutor(), requestMonitor)); } else { requestMonitor.done(); } @@ -314,6 +320,11 @@ public class FinalLaunchSequence extends Sequence { @Override public void execute(final RequestMonitor requestMonitor) { + if (fSessionType == SessionType.ATTACH) { + requestMonitor.done(); + return; + } + final MICommand execCommand; if (fSessionType == SessionType.REMOTE) { // When doing remote debugging, we use -exec-continue instead of -exec-run @@ -349,13 +360,20 @@ public class FinalLaunchSequence extends Sequence { GdbLaunch fLaunch; SessionType fSessionType; + int fPid; GDBControl fCommandControl; public FinalLaunchSequence(DsfExecutor executor, GdbLaunch launch, SessionType type) { super(executor); fLaunch = launch; - fSessionType = type; + fSessionType = type; + } + + // If a pid is specified, it is for an ATTACH type + public FinalLaunchSequence(DsfExecutor executor, GdbLaunch launch, int attachToPid) { + this(executor, launch, SessionType.ATTACH); + fPid = attachToPid; } diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java index 20671367bfe..ded518d0d37 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/GdbLaunchDelegate.java @@ -61,7 +61,7 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate { public final static String GDB_DEBUG_MODEL_ID = "org.eclipse.dd.gdb"; //$NON-NLS-1$ private SessionType fSessionType; - + /* (non-Javadoc) * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor) */ @@ -107,23 +107,42 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate } final GdbLaunch launch = (GdbLaunch)l; - if (fSessionType == SessionType.REMOTE) { monitor.subTask( "Debugging remote C/C++ application" ); //$NON-NLS-1$ } else { monitor.subTask( "Debugging local C/C++ application" ); //$NON-NLS-1$ } + IPath exePath = verifyProgramPath( config ); ICProject project = verifyCProject( config ); if ( exePath != null ) { verifyBinary( project, exePath ); } - setDefaultSourceLocator(launch, config); - monitor.worked( 1 ); - + // If we are attaching, get the process id now, so as to avoid starting the launch + // and canceling it if the user does not put the pid properly. + int pid = -1; + if (fSessionType == SessionType.ATTACH) { + try { + // have we already been given the pid (maybe from a JUnit test launch or something) + pid = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_ATTACH_PROCESS_ID, -1); + } catch (CoreException e) { + // do nothing and fall to below + } + + if (pid == -1) { + pid = promptForProcessID(config); + } + if (pid == -1) { + throw new DebugException(new Status(IStatus.CANCEL, GdbPlugin.PLUGIN_ID, + LaunchMessages.getString("LocalAttachLaunchDelegate.No_Process_ID_selected"))); //$NON-NLS-1$ + } + } + + setDefaultSourceLocator(launch, config); + // Create and invoke the launch sequence to create the debug control and services final ServicesLaunchSequence servicesLaunchSequence = new ServicesLaunchSequence(launch.getSession(), launch, exePath); @@ -165,8 +184,12 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate } // Create and invoke the final launch sequence to setup GDB - final FinalLaunchSequence finalLaunchSequence = - new FinalLaunchSequence(launch.getSession().getExecutor(), launch, fSessionType); + final FinalLaunchSequence finalLaunchSequence; + if (fSessionType == SessionType.ATTACH) { + finalLaunchSequence = new FinalLaunchSequence(launch.getSession().getExecutor(), launch, pid); + } else { + finalLaunchSequence = new FinalLaunchSequence(launch.getSession().getExecutor(), launch, fSessionType); + } launch.getSession().getExecutor().execute(finalLaunchSequence); try { finalLaunchSequence.get(); @@ -200,6 +223,21 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate } } + // Copied from the CDT + protected int promptForProcessID(ILaunchConfiguration config) throws CoreException { + IStatus fPromptStatus = new Status(IStatus.INFO, "org.eclipse.debug.ui", 200, "", null); //$NON-NLS-1$//$NON-NLS-2$ + IStatus processPrompt = new Status(IStatus.INFO, "org.eclipse.cdt.launch", 100, "", null); //$NON-NLS-1$//$NON-NLS-2$ + // consult a status handler + IStatusHandler prompter = DebugPlugin.getDefault().getStatusHandler(fPromptStatus); + if (prompter != null) { + Object result = prompter.handleStatus(processPrompt, config); + if (result instanceof Integer) { + return ((Integer)result).intValue(); + } + } + return -1; + } + /* (non-Javadoc) * @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#getPluginID() diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIAttach.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIAttach.java new file mode 100644 index 00000000000..be79c4538c8 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIAttach.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2008 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.dd.mi.service.command.commands; + +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + +/** + * This command connects to a remote target. + */ +public class CLIAttach extends CLICommand { + + public CLIAttach(IDMContext ctx, int pid) { + super(ctx, "attach " + Integer.toString(pid)); //$NON-NLS-1$ + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileExecAndSymbols.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileExecAndSymbols.java new file mode 100644 index 00000000000..3a5b63acc01 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIFileExecAndSymbols.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2008 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.dd.mi.service.command.commands; + +import org.eclipse.dd.mi.service.command.MIControlDMContext; +import org.eclipse.dd.mi.service.command.output.MIInfo; + + +/** + * -file-exec-and-symbols [FILE] + * + * Specify the executable file to be debugged. Unlike `-file-exec-and-symbols', + * the symbol table is not read from this file. If used without argument, GDB + * clears the information about the executable file. No output is produced, + * except a completion notification. + */ +public class MIFileExecAndSymbols extends MICommand +{ + public MIFileExecAndSymbols(MIControlDMContext dmc, String file) { + super(dmc, "-file-exec-and-symbols", null, new String[] {file}); //$NON-NLS-1$ + } + + public MIFileExecAndSymbols(MIControlDMContext dmc) { + super(dmc, "-file-exec-and-symbols"); //$NON-NLS-1$ + } +}