From 02a8fc8a6ab3df31c26a95ae8174f5bc1cd25c95 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Thu, 15 May 2008 19:44:14 +0000 Subject: [PATCH] Bug 231129 Enhances the launch code to allow for a RemoteAttach as part of the current Attach launch configuration type. --- plugins/org.eclipse.dd.gdb.launch/plugin.xml | 2 +- .../ui/launching/AbstractCDebuggerTab.java | 2 + .../internal/ui/launching/CDebuggerTab.java | 178 ++++++++++-------- .../GdbAttachLaunchConfigurationTabGroup.java | 4 +- ...dbLocalRunLaunchConfigurationTabGroup.java | 2 +- ...bRemoteRunLaunchConfigurationTabGroup.java | 2 +- .../ui/launching/ProcessPrompter.java | 127 +++++++------ .../IGDBLaunchConfigurationConstants.java | 1 + .../launching/FinalLaunchSequence.java | 138 ++++++++++++-- .../launching/GdbLaunchDelegate.java | 77 +++----- .../launching/LaunchMessages.properties | 2 +- .../launching/ServicesLaunchSequence.java | 29 +-- .../service/command/GDBControl.java | 20 +- .../service/command/GDBInferiorProcess.java | 10 +- .../commands/CLIMonitorListProcesses.java | 46 +++++ .../output/CLIMonitorListProcessesInfo.java | 99 ++++++++++ .../gdb/launching/TestLaunchDelegate.java | 4 +- 17 files changed, 499 insertions(+), 244 deletions(-) create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIMonitorListProcesses.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/CLIMonitorListProcessesInfo.java diff --git a/plugins/org.eclipse.dd.gdb.launch/plugin.xml b/plugins/org.eclipse.dd.gdb.launch/plugin.xml index 2d39667f867..0ea08aa80c8 100644 --- a/plugins/org.eclipse.dd.gdb.launch/plugin.xml +++ b/plugins/org.eclipse.dd.gdb.launch/plugin.xml @@ -24,7 +24,7 @@ delegate="org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunchDelegate" id="org.eclipse.dd.gdb.launch.attachCLaunch" modes="debug" - name="C/C++ Attach to Local Application (Experimental - DSF)" + name="C/C++ Attach to Running Application (Experimental - DSF)" public="true" sourceLocatorId="org.eclipse.cdt.debug.core.sourceLocator" sourcePathComputerId="org.eclipse.cdt.debug.core.sourcePathComputer"> diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/AbstractCDebuggerTab.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/AbstractCDebuggerTab.java index ea4240eec1f..8f77b55ea1e 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/AbstractCDebuggerTab.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/AbstractCDebuggerTab.java @@ -293,6 +293,8 @@ public abstract class AbstractCDebuggerTab extends CLaunchConfigurationTab { fPageUpdated = false; if (select != -1) { fDCombo.select(select); + } else { + fDCombo.select(0); } //The behaviour is undefined for if the callbacks should be triggered // for this, 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 755a5627570..a37d046061e 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 @@ -43,6 +43,7 @@ import org.eclipse.core.runtime.Path; import org.eclipse.dd.gdb.internal.provisional.IGDBLaunchConfigurationConstants; import org.eclipse.dd.gdb.internal.provisional.launching.LaunchMessages; import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType; +import org.eclipse.dd.gdb.internal.ui.GdbUIPlugin; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.jface.dialogs.Dialog; @@ -63,7 +64,6 @@ import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.PlatformUI; public class CDebuggerTab extends AbstractCDebuggerTab { @@ -85,6 +85,7 @@ public class CDebuggerTab extends AbstractCDebuggerTab { * * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) */ + @Override protected Control createDialogArea(Composite parent) { Composite composite = (Composite)super.createDialogArea(parent); Group group = new Group(composite, SWT.NONE); @@ -100,13 +101,14 @@ public class CDebuggerTab extends AbstractCDebuggerTab { return composite; } + @Override protected void okPressed() { saveValues(); super.okPressed(); } private void initialize() { - Map attr = getAdvancedAttributes(); + Map attr = getAdvancedAttributes(); Object varBookkeeping = attr.get(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_VARIABLE_BOOKKEEPING); fVarBookKeeping.setSelection( (varBookkeeping instanceof Boolean) ? !((Boolean)varBookkeeping).booleanValue() : true); Object regBookkeeping = attr.get(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_REGISTER_BOOKKEEPING); @@ -114,7 +116,7 @@ public class CDebuggerTab extends AbstractCDebuggerTab { } private void saveValues() { - Map attr = getAdvancedAttributes(); + Map attr = getAdvancedAttributes(); Boolean varBookkeeping = Boolean.valueOf( !fVarBookKeeping.getSelection() ); attr.put(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_VARIABLE_BOOKKEEPING, varBookkeeping); Boolean regBookkeeping = Boolean.valueOf( !fRegBookKeeping.getSelection() ); @@ -127,28 +129,30 @@ public class CDebuggerTab extends AbstractCDebuggerTab { * * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell) */ + @Override protected void configureShell(Shell newShell) { super.configureShell(newShell); newShell.setText(LaunchMessages.getString("CDebuggerTab.Advanced_Options_Dialog_Title")); //$NON-NLS-1$ } } - - final protected SessionType fSessionType; + + protected boolean fAttachMode = false; + protected boolean fRemoteMode = false; protected Button fAdvancedButton; protected Button fStopInMain; protected Text fStopInMainSymbol; - protected Button fAttachButton; - private Map fAdvancedAttributes = new HashMap(5); + private Map fAdvancedAttributes = new HashMap(5); private ScrolledComposite fContainer; private Composite fContents; - public CDebuggerTab(SessionType type) { - fSessionType = type; - + public CDebuggerTab(SessionType sessionType, boolean attach) { + if (sessionType == SessionType.REMOTE) fRemoteMode = true; + fAttachMode = attach; + // If the default debugger has not been set, use the MI debugger. // The MI plug-in also does this, but it may not have been loaded yet. Bug 158391. ICDebugConfiguration dc = CDebugCorePlugin.getDefault().getDefaultDefaultDebugConfiguration(); @@ -157,6 +161,7 @@ public class CDebuggerTab extends AbstractCDebuggerTab { } } + @Override public void createControl(Composite parent) { fContainer = new ScrolledComposite( parent, SWT.V_SCROLL | SWT.H_SCROLL ); fContainer.setLayoutData(new GridData(GridData.FILL_BOTH)); @@ -166,15 +171,15 @@ public class CDebuggerTab extends AbstractCDebuggerTab { fContents = new Composite( fContainer, SWT.NONE ); setControl(fContainer); - /*GdbUILaunchPlugin.getDefault()*/PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), + GdbUIPlugin.getDefault().getWorkbench().getHelpSystem().setHelp(getControl(), ICDTLaunchHelpContextIds.LAUNCH_CONFIGURATION_DIALOG_DEBBUGER_TAB); - int numberOfColumns = (fSessionType == SessionType.ATTACH) ? 2 : 1; + int numberOfColumns = (fAttachMode) ? 2 : 1; GridLayout layout = new GridLayout(numberOfColumns, false); fContents.setLayout(layout); GridData gd = new GridData( GridData.BEGINNING, GridData.CENTER, true, false ); fContents.setLayoutData(gd); - createDebuggerCombo(fContents, (fSessionType == SessionType.ATTACH) ? 1 : 2 ); + createDebuggerCombo(fContents, (fAttachMode) ? 1 : 2 ); createOptionsComposite(fContents); createDebuggerGroup(fContents, 2); @@ -183,26 +188,18 @@ public class CDebuggerTab extends AbstractCDebuggerTab { protected void loadDebuggerComboBox(ILaunchConfiguration config, String selection) { ICDebugConfiguration[] debugConfigs; - String configPlatform = getPlatform(config); +// String configPlatform = getPlatform(config); debugConfigs = CDebugCorePlugin.getDefault().getActiveDebugConfigurations(); Arrays.sort(debugConfigs, new Comparator() { public int compare(ICDebugConfiguration c1, ICDebugConfiguration c2) { return Collator.getInstance().compare(c1.getName(), c2.getName()); } }); - List list = new ArrayList(); - String mode; - if (fSessionType == SessionType.ATTACH) { - mode = ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH; - } else if (fSessionType == SessionType.REMOTE) { - mode = IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE; - } else { - mode = ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN; - } + List list = new ArrayList(); if (selection.equals("")) { //$NON-NLS-1$ ICDebugConfiguration dc = CDebugCorePlugin.getDefault().getDefaultDebugConfiguration(); if (dc == null) { - CDebugCorePlugin.getDefault().saveDefaultDebugConfiguration("org.eclipse.cdt.debug.mi.core.CDebuggerNew"); + CDebugCorePlugin.getDefault().saveDefaultDebugConfiguration("org.eclipse.cdt.debug.mi.core.CDebuggerNew");//$NON-NLS-1$ dc = CDebugCorePlugin.getDefault().getDefaultDebugConfiguration(); } if (dc != null) @@ -210,47 +207,48 @@ public class CDebuggerTab extends AbstractCDebuggerTab { } String defaultSelection = selection; for (int i = 0; i < debugConfigs.length; i++) { - if ((mode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE) - && debugConfigs[i].getName().equals("gdbserver Debugger")) || //$NON-NLS-1$ - (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/mi") && debugConfigs[i].supportsMode(mode))) { //$NON-NLS-1$ - String debuggerPlatform = debugConfigs[i].getPlatform(); - if (validatePlatform(config, debugConfigs[i])) { + if (((fRemoteMode || fAttachMode) && debugConfigs[i].getName().equals("gdbserver Debugger")) || //$NON-NLS-1$ + (!fRemoteMode && debugConfigs[i].getName().equals("gdb/mi"))) { //$NON-NLS-1$ +// String debuggerPlatform = debugConfigs[i].getPlatform(); +// if (validatePlatform(config, debugConfigs[i])) { list.add(debugConfigs[i]); // // select first exact matching debugger for platform or // // requested selection // if ( (defaultSelection.equals("") && debuggerPlatform.equalsIgnoreCase(configPlatform))) { //$NON-NLS-1$ // defaultSelection = debugConfigs[i].getID(); // } - } +// } } } - // if no selection meaning nothing in config the force initdefault on - // tab + // if no selection meaning nothing in config the force initdefault on tab setInitializeDefault(selection.equals("") ? true : false); //$NON-NLS-1$ - loadDebuggerCombo((ICDebugConfiguration[])list.toArray(new ICDebugConfiguration[list.size()]), defaultSelection); + loadDebuggerCombo(list.toArray(new ICDebugConfiguration[list.size()]), defaultSelection); } + @Override protected void updateComboFromSelection() { super.updateComboFromSelection(); initializeCommonControls(getLaunchConfiguration()); } + @Override public void setDefaults(ILaunchConfigurationWorkingCopy config) { super.setDefaults(config); - if (fSessionType == SessionType.ATTACH) { + if (fAttachMode && fRemoteMode) { + config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, + IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE_ATTACH); + } else if (fAttachMode) { config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH); - } else if (fSessionType == SessionType.REMOTE) { + } else if (fRemoteMode) { config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE); - config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, - ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_DEFAULT); } else { config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN); + } + + if (!fAttachMode) { config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_DEFAULT); } @@ -260,7 +258,7 @@ public class CDebuggerTab extends AbstractCDebuggerTab { // Set the default debugger based on the active toolchain on the project (if possible) String defaultDebugger = null; try { - String projectName = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, ""); + String projectName = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, "");//$NON-NLS-1$ if (projectName.length() > 0) { IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); ICProjectDescription projDesc = CoreModel.getDefault().getProjectDescription(project); @@ -293,6 +291,7 @@ public class CDebuggerTab extends AbstractCDebuggerTab { config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ID, defaultDebugger); } + @Override public void initializeFrom(ILaunchConfiguration config) { setInitializing(true); super.initializeFrom(config); @@ -305,43 +304,60 @@ public class CDebuggerTab extends AbstractCDebuggerTab { setInitializing(false); } + @Override public void performApply(ILaunchConfigurationWorkingCopy config) { super.performApply(config); - if (fSessionType == SessionType.ATTACH) { + + if (fAttachMode && fRemoteMode) { + config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, + IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE_ATTACH); + } else if (fAttachMode) { config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH); + } else if (fRemoteMode) { + config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, + IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE); } else { - config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, fStopInMain.getSelection()); - config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, fStopInMainSymbol.getText()); - if (fSessionType == SessionType.REMOTE) { - config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, - IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE); - } else { - config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, - ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN); - } + config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, + ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN); } + if (!fAttachMode) { + config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, + ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_DEFAULT); + config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, + fStopInMainSymbol.getText()); + + } + applyAdvancedAttributes(config); } + @Override public boolean isValid(ILaunchConfiguration config) { if (!validateDebuggerConfig(config)) { return false; } ICDebugConfiguration debugConfig = getDebugConfig(); - String mode = ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN; - if (fSessionType == SessionType.ATTACH) mode = ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH; - else if (fSessionType == SessionType.REMOTE) mode = IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE; - - if (!mode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE) && !debugConfig.supportsMode(mode)) { - setErrorMessage(MessageFormat.format(LaunchMessages.getString("CDebuggerTab.Mode_not_supported"), (Object[]) new String[]{mode})); //$NON-NLS-1$ +// if (fAttachMode && !debugConfig.supportsMode(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH)) { +// setErrorMessage(MessageFormat.format(LaunchMessages.getString("CDebuggerTab.Mode_not_supported"), //$NON-NLS-1$ +// (Object[]) new String[]{ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH})); +// return false; +// } +// if (fRemoteMode && !debugConfig.supportsMode(IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE)) { +// setErrorMessage(MessageFormat.format(LaunchMessages.getString("CDebuggerTab.Mode_not_supported"), //$NON-NLS-1$ +// (Object[]) new String[]{IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE})); +// return false; +// } + if (!fAttachMode && !fRemoteMode && !debugConfig.supportsMode(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN)) { + setErrorMessage(MessageFormat.format(LaunchMessages.getString("CDebuggerTab.Mode_not_supported"), //$NON-NLS-1$ + (Object[]) new String[]{ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN})); return false; } if ( fStopInMain != null && fStopInMainSymbol != null ) { // The "Stop on startup at" field must not be empty String mainSymbol = fStopInMainSymbol.getText().trim(); if (fStopInMain.getSelection() && mainSymbol.length() == 0) { - setErrorMessage( LaunchMessages.getString("CDebuggerTab.Stop_on_startup_at_can_not_be_empty")); //$NON-NLS-1$ + setErrorMessage(LaunchMessages.getString("CDebuggerTab.Stop_on_startup_at_can_not_be_empty")); //$NON-NLS-1$ return false; } } @@ -357,20 +373,6 @@ public class CDebuggerTab extends AbstractCDebuggerTab { return (debuggerPlatform.equals("*") || debuggerPlatform.equalsIgnoreCase(configPlatform)); //$NON-NLS-1$ } - protected boolean validateCPU(ILaunchConfiguration config, ICDebugConfiguration debugConfig) { - IBinaryObject binaryFile = null; - try { - binaryFile = getBinary(config); - } catch (CoreException e) { - setErrorMessage(e.getLocalizedMessage()); - } - String projectCPU = ICDebugConfiguration.CPU_NATIVE; - if (binaryFile != null) { - projectCPU = binaryFile.getCPU(); - } - return debugConfig.supportsCPU(projectCPU); - } - protected IBinaryObject getBinary(ILaunchConfiguration config) throws CoreException { String programName = null; String projectName = null; @@ -436,14 +438,15 @@ public class CDebuggerTab extends AbstractCDebuggerTab { protected void createOptionsComposite(Composite parent) { Composite optionsComp = new Composite(parent, SWT.NONE); - int numberOfColumns = (fSessionType == SessionType.ATTACH) ? 1 : 3; + int numberOfColumns = (fAttachMode) ? 1 : 3; GridLayout layout = new GridLayout( numberOfColumns, false ); optionsComp.setLayout( layout ); optionsComp.setLayoutData( new GridData( GridData.BEGINNING, GridData.CENTER, true, false, 1, 1 ) ); - if (fSessionType != SessionType.ATTACH) { + if (!fAttachMode) { fStopInMain = createCheckButton( optionsComp, LaunchMessages.getString( "CDebuggerTab.Stop_at_main_on_startup" ) ); //$NON-NLS-1$ fStopInMain.addSelectionListener(new SelectionAdapter() { + @Override public void widgetSelected(SelectionEvent e) { fStopInMainSymbol.setEnabled(fStopInMain.getSelection()); update(); @@ -460,6 +463,7 @@ public class CDebuggerTab extends AbstractCDebuggerTab { }); fStopInMainSymbol.getAccessible().addAccessibleListener( new AccessibleAdapter() { + @Override public void getName(AccessibleEvent e) { e.result = LaunchMessages.getString( "CDebuggerTab.Stop_at_main_on_startup"); //$NON-NLS-1$ } @@ -470,6 +474,7 @@ public class CDebuggerTab extends AbstractCDebuggerTab { ((GridData)fAdvancedButton.getLayoutData()).horizontalAlignment = GridData.END; fAdvancedButton.addSelectionListener(new SelectionAdapter() { + @Override public void widgetSelected(SelectionEvent e) { Dialog dialog = new AdvancedDebuggerOptionsDialog(getShell()); dialog.open(); @@ -477,32 +482,30 @@ public class CDebuggerTab extends AbstractCDebuggerTab { }); } - protected Map getAdvancedAttributes() { + protected Map getAdvancedAttributes() { return fAdvancedAttributes; } private void initializeAdvancedAttributes(ILaunchConfiguration config) { - Map attr = getAdvancedAttributes(); + Map attr = getAdvancedAttributes(); try { - Boolean varBookkeeping = (config.getAttribute( + boolean varBookkeeping = (config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_VARIABLE_BOOKKEEPING, false)) - ? Boolean.TRUE - : Boolean.FALSE; + ? true : false; attr.put(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_VARIABLE_BOOKKEEPING, varBookkeeping); } catch (CoreException e) { } try { Boolean regBookkeeping = (config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_REGISTER_BOOKKEEPING, false)) - ? Boolean.TRUE - : Boolean.FALSE; + ? true :false; attr.put(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_REGISTER_BOOKKEEPING, regBookkeeping); } catch (CoreException e) { } } private void applyAdvancedAttributes(ILaunchConfigurationWorkingCopy config) { - Map attr = getAdvancedAttributes(); + Map attr = getAdvancedAttributes(); Object varBookkeeping = attr.get(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_VARIABLE_BOOKKEEPING); if (varBookkeeping instanceof Boolean) config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_VARIABLE_BOOKKEEPING, @@ -513,6 +516,7 @@ public class CDebuggerTab extends AbstractCDebuggerTab { ((Boolean)regBookkeeping).booleanValue()); } + @Override protected Shell getShell() { return super.getShell(); } @@ -522,6 +526,7 @@ public class CDebuggerTab extends AbstractCDebuggerTab { * * @see org.eclipse.debug.ui.ILaunchConfigurationTab#dispose() */ + @Override public void dispose() { getAdvancedAttributes().clear(); ICDebuggerPage debuggerPage = getDynamicTab(); @@ -532,22 +537,29 @@ public class CDebuggerTab extends AbstractCDebuggerTab { protected void initializeCommonControls(ILaunchConfiguration config) { try { - if (fSessionType != SessionType.ATTACH) { + if (!fAttachMode) { fStopInMain.setSelection(config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_DEFAULT)); fStopInMainSymbol.setText(config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT)); fStopInMainSymbol.setEnabled(fStopInMain.getSelection()); + } else { + // In attach mode, figure out if we are doing a remote connect based on the currently + // chosen debugger + if (getDebugConfig().getName().equals("gdbserver Debugger")) fRemoteMode = true; //$NON-NLS-1$ + else fRemoteMode = false; } initializeAdvancedAttributes(config); } catch (CoreException e) { } } + @Override protected void setInitializeDefault(boolean init) { super.setInitializeDefault(init); } + @Override protected void contentsChanged() { fContainer.setMinSize(fContents.computeSize(SWT.DEFAULT, SWT.DEFAULT)); } 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 index 8e7e198a2de..5224c1b347d 100644 --- 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 @@ -10,7 +10,6 @@ *******************************************************************************/ package org.eclipse.dd.gdb.internal.ui.launching; -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; @@ -26,7 +25,8 @@ public class GdbAttachLaunchConfigurationTabGroup extends AbstractLaunchConfigur public void createTabs(ILaunchConfigurationDialog dialog, String mode) { ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] { new CMainTab(), - new CDebuggerTab(SessionType.ATTACH), + // We don't know yet if we are going to do a remote or local session + new CDebuggerTab(null, true), new SourceLookupTab(), new CommonTab() }; diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbLocalRunLaunchConfigurationTabGroup.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbLocalRunLaunchConfigurationTabGroup.java index 617b44dff51..5e1b0e3c71b 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbLocalRunLaunchConfigurationTabGroup.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbLocalRunLaunchConfigurationTabGroup.java @@ -26,7 +26,7 @@ public class GdbLocalRunLaunchConfigurationTabGroup extends AbstractLaunchConfig public void createTabs(ILaunchConfigurationDialog dialog, String mode) { ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] { new CMainTab(), - new CDebuggerTab(SessionType.RUN), + new CDebuggerTab(SessionType.LOCAL, false), new SourceLookupTab(), new CommonTab() }; diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbRemoteRunLaunchConfigurationTabGroup.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbRemoteRunLaunchConfigurationTabGroup.java index 808c7ef205d..09c1766be2d 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbRemoteRunLaunchConfigurationTabGroup.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/GdbRemoteRunLaunchConfigurationTabGroup.java @@ -26,7 +26,7 @@ public class GdbRemoteRunLaunchConfigurationTabGroup extends AbstractLaunchConfi public void createTabs(ILaunchConfigurationDialog dialog, String mode) { ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] { new CMainTab(), - new CDebuggerTab(SessionType.REMOTE), + new CDebuggerTab(SessionType.REMOTE, false), new SourceLookupTab(), new CommonTab() }; diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/ProcessPrompter.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/ProcessPrompter.java index 14c0eca231c..916ae6197fd 100644 --- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/ProcessPrompter.java +++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/launching/ProcessPrompter.java @@ -11,18 +11,18 @@ *******************************************************************************/ package org.eclipse.dd.gdb.internal.ui.launching; -import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.IProcessInfo; -import org.eclipse.cdt.core.IProcessList; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; +import org.eclipse.dd.gdb.internal.provisional.launching.FinalLaunchSequence; import org.eclipse.dd.gdb.internal.provisional.launching.LaunchMessages; import org.eclipse.dd.gdb.internal.ui.GdbUIPlugin; import org.eclipse.debug.core.IStatusHandler; +import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.LabelProvider; @@ -48,64 +48,83 @@ public class ProcessPrompter implements IStatusHandler { throw new CoreException(error); } - ILabelProvider provider = new LabelProvider() { - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object) - */ - public String getText(Object element) { - IProcessInfo info = (IProcessInfo)element; - IPath path = new Path(info.getName()); - return path.lastSegment() + " - " + info.getPid(); //$NON-NLS-1$ - } - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object) - */ - public Image getImage(Object element) { - return LaunchImages.get(LaunchImages.IMG_OBJS_EXEC); - } - }; - ILabelProvider qprovider = new LabelProvider() { - - public String getText(Object element) { - IProcessInfo info = (IProcessInfo)element; - return info.getName(); - } - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object) - */ - public Image getImage(Object element) { - return LaunchImages.get(LaunchImages.IMG_OBJS_EXEC); - } - }; - TwoPaneElementSelector dialog = new TwoPaneElementSelector(shell, provider, qprovider); - dialog.setTitle(LaunchMessages.getString("LocalAttachLaunchDelegate.Select_Process")); //$NON-NLS-1$ - dialog.setMessage(LaunchMessages.getString("LocalAttachLaunchDelegate.Select_Process_to_attach_debugger_to")); //$NON-NLS-1$ - IProcessList plist = null; - try { - plist = CCorePlugin.getDefault().getProcessList(); - } catch (CoreException e) { - GdbUIPlugin.errorDialog(LaunchMessages.getString("LocalAttachLaunchDelegate.CDT_Launch_Error"), e.getStatus()); //$NON-NLS-1$ - } + // Get the process list from the FinalLaunchSequence + IProcessInfo[] plist = ((FinalLaunchSequence)source).getProcessList(); if (plist == null) { MessageDialog.openError( - shell, - LaunchMessages.getString("LocalAttachLaunchDelegate.CDT_Launch_Error"), LaunchMessages.getString("LocalAttachLaunchDelegate.Platform_cannot_list_processes")); //$NON-NLS-1$ //$NON-NLS-2$ + shell, + LaunchMessages.getString("LocalAttachLaunchDelegate.CDT_Launch_Error"), LaunchMessages.getString("LocalAttachLaunchDelegate.Platform_cannot_list_processes")); //$NON-NLS-1$ //$NON-NLS-2$ return null; } - dialog.setElements(plist.getProcessList()); - if (dialog.open() == Window.OK) { - IProcessInfo info = (IProcessInfo)dialog.getFirstResult(); - if (info != null) { - return new Integer(info.getPid()); + + if (plist.length == 0) { + // No list available, just let the user put in a pid directly + InputDialog dialog = new InputDialog(shell, + LaunchMessages.getString("LocalAttachLaunchDelegate.Select_Process"), //$NON-NLS-1$ + LaunchMessages.getString("LocalAttachLaunchDelegate.Select_Process_to_attach_debugger_to"), //$NON-NLS-1$ + null, null); + + if (dialog.open() == Window.OK) { + String pidStr = dialog.getValue(); + try { + return Integer.parseInt(pidStr); + } catch (NumberFormatException e) { + } + } + } else { + ILabelProvider provider = new LabelProvider() { + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object) + */ + @Override + public String getText(Object element) { + IProcessInfo info = (IProcessInfo)element; + IPath path = new Path(info.getName()); + return path.lastSegment() + " - " + info.getPid(); //$NON-NLS-1$ + } + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object) + */ + @Override + public Image getImage(Object element) { + return LaunchImages.get(LaunchImages.IMG_OBJS_EXEC); + } + }; + ILabelProvider qprovider = new LabelProvider() { + @Override + public String getText(Object element) { + IProcessInfo info = (IProcessInfo)element; + return info.getName(); + } + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object) + */ + @Override + public Image getImage(Object element) { + return LaunchImages.get(LaunchImages.IMG_OBJS_EXEC); + } + }; + + // Display the list of processes and have the user choose + TwoPaneElementSelector dialog = new TwoPaneElementSelector(shell, provider, qprovider); + dialog.setTitle(LaunchMessages.getString("LocalAttachLaunchDelegate.Select_Process")); //$NON-NLS-1$ + dialog.setMessage(LaunchMessages.getString("LocalAttachLaunchDelegate.Select_Process_to_attach_debugger_to")); //$NON-NLS-1$ + + dialog.setElements(plist); + if (dialog.open() == Window.OK) { + IProcessInfo info = (IProcessInfo)dialog.getFirstResult(); + if (info != null) { + return new Integer(info.getPid()); + } } } + return null; } diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/IGDBLaunchConfigurationConstants.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/IGDBLaunchConfigurationConstants.java index b2d3f81384c..b530a354264 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/IGDBLaunchConfigurationConstants.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/IGDBLaunchConfigurationConstants.java @@ -13,5 +13,6 @@ package org.eclipse.dd.gdb.internal.provisional; public class IGDBLaunchConfigurationConstants { public static final String DEBUGGER_MODE_REMOTE = "remote"; //$NON-NLS-1$ + public static final String DEBUGGER_MODE_REMOTE_ATTACH = "remote_attach"; //$NON-NLS-1$ } 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 ac4e421aef6..7bc6e716809 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 @@ -13,13 +13,19 @@ package org.eclipse.dd.gdb.internal.provisional.launching; import java.util.ArrayList; import java.util.List; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.IProcessInfo; +import org.eclipse.cdt.core.IProcessList; +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; 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.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.DsfExecutor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; @@ -31,12 +37,17 @@ import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.Sessio import org.eclipse.dd.mi.service.CSourceLookup; import org.eclipse.dd.mi.service.MIBreakpointsManager; import org.eclipse.dd.mi.service.command.commands.CLIAttach; +import org.eclipse.dd.mi.service.command.commands.CLIMonitorListProcesses; import org.eclipse.dd.mi.service.command.commands.CLISource; 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.MITargetSelect; +import org.eclipse.dd.mi.service.command.output.CLIMonitorListProcessesInfo; import org.eclipse.dd.mi.service.command.output.MIInfo; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.IStatusHandler; public class FinalLaunchSequence extends Sequence { @@ -155,7 +166,6 @@ public class FinalLaunchSequence extends Sequence { }}, /* * If remote debugging, connect to target. - * If attach session, perform the attach. */ new Step() { private boolean fTcpConnection; @@ -233,15 +243,113 @@ 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(); } } }, + /* + * If attach session, perform the attach. + */ + new Step() { + private void promptForProcessID(final ILaunchConfiguration config, final DataRequestMonitor rm) { + IStatus promptStatus = new Status(IStatus.INFO, "org.eclipse.debug.ui", 200/*STATUS_HANDLER_PROMPT*/, "", null); //$NON-NLS-1$//$NON-NLS-2$ + final IStatus processPromptStatus = new Status(IStatus.INFO, "org.eclipse.dd.gdb.ui", 100, "", null); //$NON-NLS-1$//$NON-NLS-2$ + + final IStatusHandler prompter = DebugPlugin.getDefault().getStatusHandler(promptStatus); + + final Status noPidStatus = new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, + LaunchMessages.getString("LocalAttachLaunchDelegate.No_Process_ID_selected"), //$NON-NLS-1$ + null); + + if (prompter == null) { + rm.setStatus(noPidStatus); + rm.done(); + return; + } + + // Need a job because prompter.handleStatus will block + final Job promptForPid = new Job("Prompt for Process") { //$NON-NLS-1$ + @Override + protected IStatus run(IProgressMonitor monitor) { + try { + Object result = prompter.handleStatus(processPromptStatus, FinalLaunchSequence.this); + if (result instanceof Integer) { + rm.setData((Integer)result); + } else { + rm.setStatus(noPidStatus); + } + } catch (CoreException e) { + rm.setStatus(noPidStatus); + } + rm.done(); + + return Status.OK_STATUS; + } + }; + + if (fSessionType == SessionType.LOCAL) { + try { + IProcessList list = CCorePlugin.getDefault().getProcessList(); + if (list != null) fProcessList = list.getProcessList(); + } catch (CoreException e) { + } finally { + // If the list is null, the prompter will deal with it + promptForPid.schedule(); + } + } else { + fCommandControl.queueCommand( + new CLIMonitorListProcesses(fCommandControl.getControlDMContext()), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + if (isSuccess()) { + fProcessList = getData().getProcessList(); + } else { + // The monitor list command is not supported. + // Just set the list to empty and let the user + // put in the pid directly. + fProcessList = new IProcessInfo[0]; + } + + promptForPid.schedule(); + } + }); + } + } + + @Override + public void execute(final RequestMonitor requestMonitor) { + if (fAttach) { + // If we are attaching, get the process id. + int pid = -1; + try { + // have we already been given the pid (maybe from a JUnit test launch or something) + pid = fLaunch.getLaunchConfiguration().getAttribute(ICDTLaunchConfigurationConstants.ATTR_ATTACH_PROCESS_ID, -1); + } catch (CoreException e) { + // do nothing and fall to below + } + + if (pid != -1) { + fCommandControl.queueCommand( + new CLIAttach(fCommandControl.getControlDMContext(), pid), + new DataRequestMonitor(getExecutor(), requestMonitor)); + } else { + promptForProcessID(fLaunch.getLaunchConfiguration(), + new DataRequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleSuccess() { + fCommandControl.queueCommand( + new CLIAttach(fCommandControl.getControlDMContext(), getData()), + new DataRequestMonitor(getExecutor(), requestMonitor)); + } + }); + } + } else { + requestMonitor.done(); + } + } + }, /* * Start tracking the breakpoints once we know we are connected to the target (necessary for remote debugging) */ @@ -265,27 +373,25 @@ public class FinalLaunchSequence extends Sequence { GdbLaunch fLaunch; SessionType fSessionType; - int fPid; + boolean fAttach; GDBControl fCommandControl; - - public FinalLaunchSequence(DsfExecutor executor, GdbLaunch launch, SessionType type) { + // The list of processes used in the case of an ATTACH session + IProcessInfo[] fProcessList = null; + + public FinalLaunchSequence(DsfExecutor executor, GdbLaunch launch, SessionType sessionType, boolean attach) { super(executor); fLaunch = launch; - fSessionType = type; + fSessionType = sessionType; + fAttach = attach; } - // 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; - } - - @Override public Step[] getSteps() { return fSteps; } + public IProcessInfo[] getProcessList() { return fProcessList; } + } 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 a80d5da09ab..7e183809d96 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 @@ -46,7 +46,6 @@ import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchManager; -import org.eclipse.debug.core.IStatusHandler; import org.eclipse.debug.core.model.ILaunchConfigurationDelegate2; import org.eclipse.debug.core.model.IPersistableSourceLocator; import org.eclipse.debug.core.model.ISourceLocator; @@ -92,6 +91,8 @@ public class GdbLaunchDelegate extends LaunchConfigurationDelegate } SessionType sessionType = getSessionType(config); + boolean attach = getIsAttach(config); + final GdbLaunch launch = (GdbLaunch)l; if (sessionType == SessionType.REMOTE) { @@ -109,29 +110,9 @@ public class GdbLaunchDelegate extends LaunchConfigurationDelegate 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 (sessionType == 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$ - } - } - // Create and invoke the launch sequence to create the debug control and services final ServicesLaunchSequence servicesLaunchSequence = - new ServicesLaunchSequence(launch.getSession(), launch, exePath); + new ServicesLaunchSequence(launch.getSession(), launch, exePath, sessionType, attach); launch.getSession().getExecutor().execute(servicesLaunchSequence); try { servicesLaunchSequence.get(); @@ -151,12 +132,8 @@ public class GdbLaunchDelegate extends LaunchConfigurationDelegate launch.addInferiorProcess(exePath.lastSegment()); // Create and invoke the final launch sequence to setup GDB - final FinalLaunchSequence finalLaunchSequence; - if (sessionType == SessionType.ATTACH) { - finalLaunchSequence = new FinalLaunchSequence(launch.getSession().getExecutor(), launch, pid); - } else { - finalLaunchSequence = new FinalLaunchSequence(launch.getSession().getExecutor(), launch, sessionType); - } + final FinalLaunchSequence finalLaunchSequence = + new FinalLaunchSequence(launch.getSession().getExecutor(), launch, sessionType, attach); launch.getSession().getExecutor().execute(finalLaunchSequence); try { finalLaunchSequence.get(); @@ -167,36 +144,44 @@ public class GdbLaunchDelegate extends LaunchConfigurationDelegate } } - private SessionType getSessionType(ILaunchConfiguration config) { + private SessionType getSessionType(ILaunchConfiguration config) { try { String debugMode = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ); if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN)) { - return SessionType.RUN; + return SessionType.LOCAL; } else if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH)) { - return SessionType.ATTACH; + return SessionType.LOCAL; } else if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE)) { return SessionType.CORE; } else if (debugMode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE)) { return SessionType.REMOTE; - } + } else if (debugMode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE_ATTACH)) { + return SessionType.REMOTE; + } } catch (CoreException e) { } - return SessionType.RUN; + return SessionType.LOCAL; + } + + private boolean getIsAttach(ILaunchConfiguration config) { + try { + String debugMode = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ); + if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN)) { + return false; + } else if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH)) { + return true; + } else if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE)) { + return false; + } else if (debugMode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE)) { + return false; + } else if (debugMode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE_ATTACH)) { + return true; + } + } catch (CoreException e) { + } + return false; } - 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.dd.gdb.ui", 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; - } @Override public boolean preLaunchCheck(ILaunchConfiguration config, String mode, IProgressMonitor monitor) throws CoreException { diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/LaunchMessages.properties b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/LaunchMessages.properties index ad12c5f5d98..7ee2543bc37 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/LaunchMessages.properties +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/LaunchMessages.properties @@ -38,7 +38,7 @@ LocalAttachLaunchDelegate.Attaching_to_Local_C_Application=Attaching to Local C/ LocalAttachLaunchDelegate.No_Process_ID_selected=No Process ID selected LocalAttachLaunchDelegate.Select_Process=Select Process LocalAttachLaunchDelegate.Platform_cannot_list_processes=Current platform does not support listing processes -LocalAttachLaunchDelegate.Select_Process_to_attach_debugger_to=Select a Process to attach debugger to: +LocalAttachLaunchDelegate.Select_Process_to_attach_debugger_to=Select a Process to attach the debugger to: LocalAttachLaunchDelegate.CDT_Launch_Error=CDT Launch Error CoreFileLaunchDelegate.Launching_postmortem_debugger=Launching postmortem debugger diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ServicesLaunchSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ServicesLaunchSequence.java index 8dc218b1a26..ae4dd0175b9 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ServicesLaunchSequence.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ServicesLaunchSequence.java @@ -11,7 +11,6 @@ package org.eclipse.dd.gdb.internal.provisional.launching; import org.eclipse.cdt.debug.core.CDebugCorePlugin; -import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; import org.eclipse.cdt.debug.mi.core.IMILaunchConfigurationConstants; import org.eclipse.core.runtime.CoreException; @@ -21,7 +20,6 @@ import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.Sequence; import org.eclipse.dd.dsf.debug.service.StepQueueManager; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.gdb.internal.provisional.IGDBLaunchConfigurationConstants; import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl; import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl; import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType; @@ -42,29 +40,10 @@ public class ServicesLaunchSequence extends Sequence { new Step() { @Override public void execute(RequestMonitor requestMonitor) { - String debugMode = ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN; - try { - debugMode = fLaunch.getLaunchConfiguration().getAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, - ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ); - } catch (CoreException e) { - } - - if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN)) { - fSessionType = SessionType.RUN; - } else if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH)) { - fSessionType = SessionType.ATTACH; - } else if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE)) { - fSessionType = SessionType.CORE; - } else if (debugMode.equals(IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE)) { - fSessionType = SessionType.REMOTE; - } else { - fSessionType = SessionType.RUN; - } - // // Create the connection. // - fCommandControl = new GDBControl(fSession, getGDBPath(), fExecPath, fSessionType, 30); + fCommandControl = new GDBControl(fSession, getGDBPath(), fExecPath, fSessionType, fAttach, 30); fCommandControl.initialize(requestMonitor); } }, @@ -128,17 +107,21 @@ public class ServicesLaunchSequence extends Sequence { DsfSession fSession; GdbLaunch fLaunch; IPath fExecPath; + SessionType fSessionType; + boolean fAttach; GDBControl fCommandControl; CSourceLookup fSourceLookup; MIBreakpointsManager fBpmService; - public ServicesLaunchSequence(DsfSession session, GdbLaunch launch, IPath execPath) { + public ServicesLaunchSequence(DsfSession session, GdbLaunch launch, IPath execPath, SessionType sessionType, boolean attach) { super(session.getExecutor()); fSession = session; fLaunch = launch; fExecPath = execPath; + fSessionType = sessionType; + fAttach = attach; } @Override diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java index df28c728516..1037bb2ceb9 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBControl.java @@ -92,9 +92,11 @@ public class GDBControl extends AbstractMIControl { private static int fgInstanceCounter = 0; private final GDBControlDMContext fControlDmc; - public enum SessionType { RUN, ATTACH, CORE, REMOTE } + public enum SessionType { LOCAL, REMOTE, CORE } private SessionType fSessionType; + public boolean fAttach; + private boolean fConnected = false; private MonitorJob fMonitorJob; @@ -111,9 +113,10 @@ public class GDBControl extends AbstractMIControl { private PTY fPty; - public GDBControl(DsfSession session, IPath gdbPath, IPath execPath, SessionType type, int gdbLaunchTimeout) { + public GDBControl(DsfSession session, IPath gdbPath, IPath execPath, SessionType sessionType, boolean attach, int gdbLaunchTimeout) { super(session); - fSessionType = type; + fSessionType = sessionType; + fAttach = attach; fGdbPath = gdbPath; fExecPath = execPath; fGDBLaunchTimeout = gdbLaunchTimeout; @@ -184,6 +187,9 @@ public class GDBControl extends AbstractMIControl { return fSessionType; } + public boolean getIsAttachSession() { + return fAttach; + } public boolean canInterrupt() { return fProcess instanceof Spawner; } @@ -241,11 +247,11 @@ public class GDBControl extends AbstractMIControl { /* * This method does the necessary work to setup the input/output streams for the * inferior process, by either preparing the PTY to be used, to simply leaving - * the PTY null, which indicates that the input/output streams of the CLI shoud + * the PTY null, which indicates that the input/output streams of the CLI should * be used instead; this decision is based on the type of session. */ public void initInferiorInputOutput(final RequestMonitor requestMonitor) { - if (fSessionType == SessionType.ATTACH || fSessionType == SessionType.REMOTE) { + if (fSessionType == SessionType.REMOTE || fAttach) { // These types do not use a PTY fPty = null; requestMonitor.done(); @@ -275,7 +281,7 @@ public class GDBControl extends AbstractMIControl { public boolean canRestart() { - if (fSessionType == SessionType.ATTACH) return false; + if (fAttach) return false; // Before GDB6.8, the Linux gdbserver would restart a new // process when getting a -exec-run but the communication @@ -307,7 +313,7 @@ public class GDBControl extends AbstractMIControl { * Insert breakpoint at entry if set, and start or restart the program. */ protected void startOrRestart(final GdbLaunch launch, boolean restart, final RequestMonitor requestMonitor) { - if (fSessionType == SessionType.ATTACH) { + if (fAttach) { // 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(); diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBInferiorProcess.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBInferiorProcess.java index 907c134e1eb..a72c01b3e82 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBInferiorProcess.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/command/GDBInferiorProcess.java @@ -17,7 +17,6 @@ import java.util.concurrent.RejectedExecutionException; import org.eclipse.cdt.utils.pty.PTY; import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; -import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType; import org.eclipse.dd.mi.service.command.MIInferiorProcess; /** @@ -46,15 +45,12 @@ class GDBInferiorProcess extends MIInferiorProcess { // An inferior will be destroy():interrupt and kill if // - For attach session: - // the inferior was not disconnected yet (no need to try - // to kill a disconnected program). + // never (we don't kill an independent process.) // - For Program session: - // if the inferior was not terminated. + // if the inferior is still running. // - For PostMortem(Core): send event // else noop - if ((gdb.getSessionType() == SessionType.ATTACH && gdb.isConnected()) || - (gdb.getSessionType() == SessionType.RUN && getState() != State.TERMINATED)) - { + if (gdb.getIsAttachSession() == false) { // Try to interrupt the inferior, first. if (getState() == State.RUNNING) { gdb.interrupt(); diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIMonitorListProcesses.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIMonitorListProcesses.java new file mode 100644 index 00000000000..77b6b11f9e2 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/CLIMonitorListProcesses.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * 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.CLIMonitorListProcessesInfo; +import org.eclipse.dd.mi.service.command.output.MIInfo; +import org.eclipse.dd.mi.service.command.output.MIOutput; + +/** + * + * monitor list processes + * + * This command is not available in the current version of GDBServer. However it should + * be available in the future. + * + */ +public class CLIMonitorListProcesses extends CLICommand +{ + public CLIMonitorListProcesses(IDMContext ctx) { + super(ctx, "monitor list processes"); //$NON-NLS-1$ + } + + @Override + public CLIMonitorListProcessesInfo getResult(MIOutput output) { + return (CLIMonitorListProcessesInfo)getMIInfo(output); + } + + public MIInfo getMIInfo(MIOutput out) { + MIInfo info = null; + if (out != null) { + info = new CLIMonitorListProcessesInfo(out); + } + return info; + } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/CLIMonitorListProcessesInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/CLIMonitorListProcessesInfo.java new file mode 100644 index 00000000000..66cc8f4cd6e --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/CLIMonitorListProcessesInfo.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * 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.output; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.cdt.core.IProcessInfo; + + +/** + * + * @" 26 N 0 N 32794 Idle 2 Http daemon\n" + */ +public class CLIMonitorListProcessesInfo extends MIInfo { + + public class ProcessInfo implements IProcessInfo, Comparable { + int pid; + String name; + + public ProcessInfo(String pidString, String name) { + try { + pid = Integer.parseInt(pidString); + } catch (NumberFormatException e) { + } + this.name = name; + } + + public ProcessInfo(int pid, String name) { + this.pid = pid; + this.name = name; + } + + /** + * @see org.eclipse.cdt.core.IProcessInfo#getName() + */ + public String getName() { + return name; + } + + /** + * @see org.eclipse.cdt.core.IProcessInfo#getPid() + */ + public int getPid() { + return pid; + } + + public int compareTo(ProcessInfo other) { + int nameCompare = getName().compareTo(other.getName()); + if (nameCompare != 0) return nameCompare; + else return (getPid() < other.getPid()) ? -1 : 1; + } + } + + IProcessInfo[] fProcessList; + + public CLIMonitorListProcessesInfo(MIOutput out) { + super(out); + parse(); + } + + public IProcessInfo[] getProcessList() { + return fProcessList; + } + + private void parse() { + List aList = new ArrayList(); + if (isDone()) { + MIOutput out = getMIOutput(); + MIOOBRecord[] oobs = out.getMIOOBRecords(); + for (int i = 0; i < oobs.length; i++) { + if (oobs[i] instanceof MITargetStreamOutput) { + MIStreamRecord cons = (MIStreamRecord) oobs[i]; + String str = cons.getString().trim(); + if (str.length() > 0) { + // Parsing pattern of type @" 26 N 0 N 32794 Idle 2 Http daemon\n" + Pattern pattern = Pattern.compile("(\\d*)\\s(Y|N)\\s*\\d*\\s(Y|N)\\s*\\d*\\s*\\D*\\s*\\d\\s(.*)", Pattern.MULTILINE); //$NON-NLS-1$ + Matcher matcher = pattern.matcher(str); + if (matcher.find()) { + ProcessInfo proc = new ProcessInfo(matcher.group(1), matcher.group(4)); + aList.add(proc); + } + } + } + } + } + fProcessList = aList.toArray(new IProcessInfo[aList.size()]); + } +} diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java index f16ba60c8c4..5017601bf4b 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/launching/TestLaunchDelegate.java @@ -81,7 +81,7 @@ public class TestLaunchDelegate extends LaunchConfigurationDelegate monitor.worked( 1 ); final ServicesLaunchSequence servicesLaunchSequence = - new ServicesLaunchSequence(launch.getSession(), launch, exePath); + new ServicesLaunchSequence(launch.getSession(), launch, exePath, SessionType.LOCAL, false); launch.getSession().getExecutor().execute(servicesLaunchSequence); try { servicesLaunchSequence.get(); @@ -99,7 +99,7 @@ public class TestLaunchDelegate extends LaunchConfigurationDelegate // Create and invoke the final launch sequence to setup GDB final FinalLaunchSequence finalLaunchSequence = - new FinalLaunchSequence(launch.getSession().getExecutor(), launch, SessionType.RUN); + new FinalLaunchSequence(launch.getSession().getExecutor(), launch, SessionType.LOCAL, false); launch.getSession().getExecutor().execute(finalLaunchSequence); try { finalLaunchSequence.get();