1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-08 08:45:44 +02:00

Bug 450080 - Add option for remote launch to stand-alone debugger

Change-Id: Ifcbfd598d90305ac24bddf96893d4170201858c9
Signed-off-by: Marc Khouzam <marc.khouzam@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/36700
Tested-by: Hudson CI
Reviewed-by: Jeff Johnston <jjohnstn@redhat.com>
Tested-by: Jeff Johnston <jjohnstn@redhat.com>
This commit is contained in:
Marc Khouzam 2014-11-20 10:57:54 -05:00 committed by Jeff Johnston
parent 8bc2e3a81b
commit 73c1e5e224
15 changed files with 671 additions and 19 deletions

View file

@ -49,6 +49,21 @@ as desired. If the executable location you specify is invalid or no executable
a dialog will be brought up to allow you to enter the required information. The dialog will be appropriate to whether
you have selected to debug a core file (-c specified) or not.</p>
<h4>-r &lt;addr:port&gt;</h4>
<p>This option specified a hostname or IP address and and IP port to connect to to perform remote debugging.
The gdbserver must be running on the target and waiting for a connection on the specified port.
This option can be used at the same time as the -a option. In such a case
a Remote-Attach session will be started allowing the user to attach to
different processes on the remote target. The user will need to press
the 'connect' button or use the context-menu of the Debug view to choose one or more processes
to attach to. In this case the -e flag is optional, and when not specified,
a dialog will be used instead to prompt for the binary's location.
This option, when used without -a, will trigger a manual Remote debugging session towards
a single, pre-selected binary and therefore requires the use of the -e option
to specify the location of the binary on the local machine that matches the one on the
remote target.</p>
<h2>Automated Set-up</h3>
<p>As mentioned, the Stand-alone Debugger will initialize Eclipse objects on your behalf on

View file

@ -7,6 +7,7 @@
#
# Contributors:
# Red Hat Incorporated - initial API and implementation
# Marc Khouzam (Ericsson) - Update for remote debugging support (bug 450080)
#################################################################################
bundleName=C/C++ Stand-alone Debugger
provider=Eclipse CDT
@ -31,6 +32,9 @@ DebugNewExecutableMenu.label=&New Executable...
DebugAttachedExecutable.description=Debug an attached executable
DebugAttachedExecutable.name=Debug Attached Executable
DebugAttachedExecutableMenu.label=&Attach Executable...
DebugRemoteExecutable.description=Debug a Remote executable
DebugRemoteExecutable.name=Debug Remote Executable
DebugRemoteExecutableMenu.label=&Remote Executable...
DebugCore.description=Debug a corefile
DebugCore.name=Debug Core File
DebugCoreMenu.label=Debug &Core File...

View file

@ -225,6 +225,13 @@
id="org.eclipse.cdt.debug.application.command.debugAttachedExecutable"
name="%DebugAttachedExecutable.name">
</command>
<command
categoryId="org.eclipse.cdt.debug.ui.category.debugViewLayout"
defaultHandler="org.eclipse.cdt.internal.debug.application.DebugRemoteExecutableHandler"
description="%DebugRemoteExecutable.description"
id="org.eclipse.cdt.debug.application.command.debugRemoteExecutable"
name="%DebugRemoteExecutable.name">
</command>
<command
categoryId="org.eclipse.cdt.debug.ui.category.debugViewLayout"
defaultHandler="org.eclipse.cdt.internal.debug.application.DebugCoreFileHandler"

View file

@ -35,11 +35,24 @@ The script takes a few options which are mentioned below:
not precede any other arguments as they will be treated as arguments
to main.
-r $ADDR:$PORT : remote debugging towards hostname or IP address $ADDR and IP port $PORT.
The gdbserver must be running on the target and waiting for a connection.
This option can be used at the same time as the -a option. In such a case
a Remote-Attach session will be started allowing the user to attach to
different processes on the remote target. The user will need to press
the 'connect' button or use the context-menu of the Debug view to choose
one or more processes to attach to. In this case the -e flag is optional,
and when not specified, a dialog will be used instead to prompt for the
binary's location. This option, when used without -a, will trigger a
manual Remote debugging session to a single, pre-selected binary, and
therefore requires the use of the -e option to specify the location of
the binary on the local machine that matches the one on the remote target.
If no -a or -e option is specified, the last executable debugged via -e will be offered for
debugging. Otherwise, if this is the first time, a dialog will be presented to enter
an executable, build log, and program arguments.
e.g. ~/cdtdebugger/cdtdebug.sh -b ~/build.log ~/myproject/bin/a.out arg1 arg2
e.g. ~/cdtdebugger/cdtdebug.sh -b ~/build.log -e ~/myproject/bin/a.out arg1 arg2
The cdtdebug.sh script that is found in the plug-in can also be run directly, but cannot
be moved. The one installed in the cdtdebugger directory on the other hand, can be moved.

View file

@ -8,6 +8,7 @@
#
# Contributors:
# Red Hat Inc. - initial API and implementation
# Marc Khouzam (Ericsson) - Update for remote debugging support (bug 450080)
###############################################################################
SCRIPT_DIR=`dirname $0`
@ -29,6 +30,8 @@ Target options:
-a attach to an existing process (list will be shown)
-c COREFILE debug core-file (should also specify executable)
-e EXECUTABLE [ARGS...] debug given executable (passing ARGS to main)
-r ADDRESS:PORT debug toward the specified remote server. Can be
combined with the -a option.
The -e option must be used last as subsequent options are passed to main.
@ -61,7 +64,7 @@ while test $# -gt 0 ; do
options="$options \"$1\""
shift;
done ;;
-c )
-c | -r )
test $# = 1 && eval "$exit_missing_arg"
options="$options $1 $2"
shift; shift ;;

View file

@ -7,6 +7,7 @@
*
* Contributors:
* Red Hat Inc. - initial API and implementation
* Marc Khouzam (Ericsson) - Update for remote debugging support (bug 450080)
*******************************************************************************/
package org.eclipse.cdt.debug.application;
@ -39,11 +40,13 @@ public class ApplicationActionBarAdvisor extends ActionBarAdvisor {
public static String COREFILE_COMMAND_ID = "org.eclipse.cdt.debug.application.command.debugCore"; //$NON-NLS-1$
public static String NEW_EXECUTABLE_COMMAND_ID = "org.eclipse.cdt.debug.application.command.debugNewExecutable"; //$NON-NLS-1$
public static String ATTACH_EXECUTABLE_COMMAND_ID = "org.eclipse.cdt.debug.application.command.debugAttachedExecutable"; //$NON-NLS-1$
public static String REMOTE_EXECUTABLE_COMMAND_ID = "org.eclipse.cdt.debug.application.command.debugRemoteExecutable"; //$NON-NLS-1$
private final IWorkbenchWindow window;
private IWorkbenchAction corefileAction;
private IWorkbenchAction newExecutableAction;
private IWorkbenchAction remoteExecutableAction;
private IWorkbenchAction attachExecutableAction;
private IWorkbenchAction quitAction;
@ -81,6 +84,9 @@ public class ApplicationActionBarAdvisor extends ActionBarAdvisor {
attachExecutableAction = ATTACH_EXECUTABLE.create(window);
register(attachExecutableAction);
remoteExecutableAction = REMOTE_EXECUTABLE.create(window);
register(remoteExecutableAction);
corefileAction = COREFILE.create(window);
register(corefileAction);
@ -132,6 +138,9 @@ public class ApplicationActionBarAdvisor extends ActionBarAdvisor {
ActionContributionItem newExecutableItem = new ActionContributionItem(newExecutableAction);
menu.add(newExecutableItem);
ActionContributionItem remoteExecutableItem = new ActionContributionItem(remoteExecutableAction);
menu.add(remoteExecutableItem);
ActionContributionItem attachExecutableItem = new ActionContributionItem(attachExecutableAction);
menu.add(attachExecutableItem);
@ -415,6 +424,30 @@ public class ApplicationActionBarAdvisor extends ActionBarAdvisor {
}
};
/**
* Workbench action (id: "remoteexecutable", commandId: "org.eclipse.cdt.debug.application.command.debugRemoteExecutable"):
* Debug a remote executable. This action maintains its enablement state.
*/
private static final ActionFactory REMOTE_EXECUTABLE = new ActionFactory("remoteexecutable", //$NON-NLS-1$
REMOTE_EXECUTABLE_COMMAND_ID) {
/* (non-Javadoc)
* @see org.eclipse.ui.actions.ActionFactory#create(org.eclipse.ui.IWorkbenchWindow)
*/
@Override
public IWorkbenchAction create(IWorkbenchWindow window) {
if (window == null) {
throw new IllegalArgumentException();
}
WorkbenchCommandAction action = new WorkbenchCommandAction(
getCommandId(), window);
action.setId(getId());
action.setText(Messages.RemoteExecutableMenuName);
action.setToolTipText(Messages.RemoteExecutable_toolTip);
return action;
}
};
/**
* Workbench action (id: "attachexecutable", commandId: "org.eclipse.cdt.debug.application.command.debugAttachedExecutable"):
* Attach and debug an existing executable. This action maintains its enablement state.

View file

@ -7,6 +7,7 @@
*
* Contributors:
* Red Hat Inc. - initial API and implementation
* Marc Khouzam (Ericsson) - Update for remote debugging support (bug 450080)
*******************************************************************************/
package org.eclipse.cdt.debug.application;
@ -22,6 +23,7 @@ import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.internal.debug.application.DebugAttachedExecutable;
import org.eclipse.cdt.internal.debug.application.DebugCoreFile;
import org.eclipse.cdt.internal.debug.application.DebugExecutable;
import org.eclipse.cdt.internal.debug.application.DebugRemoteExecutable;
import org.eclipse.cdt.internal.debug.application.JobContainer;
import org.eclipse.cdt.utils.spawner.ProcessFactory;
import org.eclipse.core.resources.ResourcesPlugin;
@ -139,6 +141,8 @@ public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {
String corefile = null;
String buildLog = null;
String arguments = null;
String remoteAddress = null;
String remotePort = null;
String[] args = Platform.getCommandLineArgs();
try {
@ -154,6 +158,9 @@ public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {
}
else if ("-a".equals(args[i])) { //$NON-NLS-1$
attachExecutable = true;
// Make sure 'executable' is still null in case we are dealing with a remote
// session that is also an attach, as the -r flag could have been set first
executable = null;
}
else if ("-c".equals(args[i])) { //$NON-NLS-1$
++i;
@ -162,6 +169,18 @@ public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {
if (i < args.length)
corefile = args[i];
}
else if ("-r".equals(args[i])) { //$NON-NLS-1$
++i;
remoteAddress = ""; //$NON-NLS-1$
if (!attachExecutable) executable = ""; //$NON-NLS-1$
if (i < args.length) {
String[] params = args[i].split(":"); //$NON-NLS-1$
if (params.length == 2) {
remoteAddress = params[0];
remotePort = params[1];
}
}
}
else if ("-e".equals(args[i])) { //$NON-NLS-1$
++i;
if (i < args.length)
@ -187,7 +206,7 @@ public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {
}
File coreFile = new File(corefile);
corefile = coreFile.getCanonicalPath();
if (executable == null || !executableFile.exists() || !coreFile.exists()) {
if (executableFile == null || !executableFile.exists() || !coreFile.exists()) {
final CoreFileInfo info = new CoreFileInfo("", "", ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ $NON-NLS-2$ $NON-NLS-3$
final IStatus errorStatus = new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0,
Messages.GdbDebugNewExecutableCommand_Binary_file_does_not_exist, null);
@ -222,6 +241,62 @@ public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {
executable = info.getHostPath();
corefile = info.getCoreFilePath();
}
} else if (remoteAddress != null) {
// Verify what we can about the port, address and executable.
File executableFile = null;
if (executable != null) {
executableFile = new File(executable);
executable = executableFile.getCanonicalPath();
}
Integer port = null;
try {
port = Integer.parseInt(remotePort);
} catch (NumberFormatException e) {
port = null;
}
if ((!attachExecutable && (executableFile == null || !executableFile.exists())) ||
remoteAddress.length() == 0 || port == null) {
final RemoteExecutableInfo[] info = new RemoteExecutableInfo[1];
final IStatus errorStatus = new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0,
Messages.GdbDebugNewExecutableCommand_Binary_file_does_not_exist, null);
final String executablePath = executable;
final String addressStr = remoteAddress;
final String portStr = remotePort;
final String buildLogPath = buildLog;
final boolean attach = attachExecutable;
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
RemoteExecutableDialog dialog = new RemoteExecutableDialog(getWindowConfigurer().getWindow().getShell(),
executablePath, buildLogPath, addressStr, portStr, attach);
dialog.setBlockOnOpen(true);
if (dialog.open() == IDialogConstants.OK_ID) {
info[0] = dialog.getExecutableInfo();
} else {
info[0] = null;
ErrorDialog.openError(null,
Messages.DebuggerInitializingProblem, null, errorStatus,
IStatus.ERROR | IStatus.WARNING);
}
}
});
// Check and see if we failed above and if so, quit
if (info[0] == null) {
monitor.done();
// throw internal exception which will be caught below
throw new StartupException(errorStatus.getMessage());
}
executable = info[0].getHostPath();
buildLog = info[0].getBuildLog();
remoteAddress = info[0].getAddress();
remotePort = info[0].getPort();
attachExecutable = info[0].isAttach();
}
} else if (executable != null) {
File executableFile = new File(executable);
executable = executableFile.getCanonicalPath();
@ -230,7 +305,7 @@ public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {
buildLogFile = new File(buildLog);
buildLog = buildLogFile.getCanonicalPath();
}
if (!executableFile.exists() || (buildLog != null && !buildLogFile.exists())) {
if (!executableFile.exists() || (buildLogFile != null && !buildLogFile.exists())) {
final NewExecutableInfo info = new NewExecutableInfo("", "", "", ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ $NON-NLS-2$ $NON-NLS-3$
final IStatus errorStatus = new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0,
Messages.GdbDebugNewExecutableCommand_Binary_file_does_not_exist, null);
@ -268,7 +343,10 @@ public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {
}
}
monitor.worked(1);
if (attachExecutable) {
if (remoteAddress != null && remoteAddress.length() > 0 &&
remotePort != null && remotePort.length() > 0) {
config = DebugRemoteExecutable.createLaunchConfig(monitor, buildLog, executable, remoteAddress, remotePort, attachExecutable);
} else if (attachExecutable) {
config = DebugAttachedExecutable.createLaunchConfig(monitor, buildLog);
} else if (corefile != null && corefile.length() > 0) {
config = DebugCoreFile.createLaunchConfig(monitor, buildLog, executable, corefile);

View file

@ -87,7 +87,7 @@ public class CoreFileDialog extends TitleAreaDialog {
comp.setLayout( layout );
comp.setLayoutData( gd );
new Label( comp, SWT.None ).setText( remote ? Messages.GdbDebugNewExecutableCommand_Binary_on_host : Messages.GdbDebugNewExecutableCommand_Binary );
new Label( comp, SWT.None ).setText( remote ? Messages.GdbDebugNewExecutableCommand_Binary_on_host : Messages.GdbDebugExecutableCommand_Binary );
fHostBinaryText = new Text( comp, SWT.BORDER );
if (fHostBinary != null)
fHostBinaryText.setText(fHostBinary);
@ -100,7 +100,7 @@ public class CoreFileDialog extends TitleAreaDialog {
}
} );
Button browseButton = new Button( comp, SWT.PUSH );
browseButton.setText( Messages.GdbDebugNewExecutableCommand_Browse );
browseButton.setText( Messages.GdbDebugExecutableCommand_Browse );
browseButton.setFont( JFaceResources.getDialogFont() );
setButtonLayoutData( browseButton );
browseButton.addSelectionListener( new SelectionAdapter() {
@ -144,7 +144,7 @@ public class CoreFileDialog extends TitleAreaDialog {
} );
Button browseButton2 = new Button( comp, SWT.PUSH );
browseButton2.setText( Messages.GdbDebugNewExecutableCommand_Browse );
browseButton2.setText( Messages.GdbDebugExecutableCommand_Browse );
browseButton2.setFont( JFaceResources.getDialogFont() );
setButtonLayoutData( browseButton2 );
browseButton2.addSelectionListener( new SelectionAdapter() {

View file

@ -7,6 +7,7 @@
*
* Contributors:
* Red Hat Inc. - initial API and implementation
* Marc Khouzam (Ericsson) - Update for remote debugging support (bug 450080)
*******************************************************************************/
package org.eclipse.cdt.debug.application;
@ -35,14 +36,15 @@ public class Messages extends NLS {
public static String DebuggerInitializingProblem;
public static String GdbDebugNewExecutableCommand_Arguments;
public static String GdbDebugNewExecutableCommand_Binary;
public static String GdbDebugExecutableCommand_Binary;
public static String GdbDebugExecutableCommand_Binary_Optional;
public static String GdbDebugNewExecutableCommand_Binary_file_does_not_exist;
public static String GdbDebugNewExecutableCommand_Binary_must_be_specified;
public static String GdbDebugNewExecutableCommand_Binary_on_host;
public static String GdbDebugNewExecutableCommand_Binary_on_target;
public static String GdbDebugNewExecutableCommand_Binary_on_target_must_be_specified;
public static String GdbDebugNewExecutableCommand_Browse;
public static String GdbDebugNewExecutableCommand_BuildLog;
public static String GdbDebugExecutableCommand_Browse;
public static String GdbDebugExecutableCommand_BuildLog;
public static String GdbDebugNewExecutableCommand_BuildLog_file_does_not_exist;
public static String GdbDebugNewExecutableCommand_Debug_New_Executable;
public static String GdbDebugNewExecutableCommand_Host_binary_file_does_not_exist;
@ -53,6 +55,14 @@ public class Messages extends NLS {
public static String GdbDebugNewExecutableCommand_Select_binaries_on_host_and_target;
public static String GdbDebugNewExecutableCommand_Select_Binary;
public static String GdbDebugNewExecutableCommand_Select_binary_and_specify_arguments;
public static String GdbDebugRemoteExecutableCommand_Debug_Remote_Executable;
public static String GdbDebugRemoteExecutableCommand_Select_Remote_Options;
public static String GdbDebugRemoteExecutableCommand_Host_name_or_ip_address;
public static String GdbDebugRemoteExecutableCommand_Port_number;
public static String GdbDebugRemoteExecutableCommand_Attach;
public static String GdbDebugRemoteExecutableCommand_address_must_be_specified;
public static String GdbDebugRemoteExecutableCommand_port_must_be_specified;
public static String GdbDebugRemoteExecutableCommand_port_must_be_a_number;
public static String GdbDebugCoreFileCommand_CoreFile;
public static String GdbDebugCoreFileCommand_Debug_Core_File;
public static String GdbDebugCoreFileCommand_Select_binary_and_specify_corefile;
@ -90,6 +100,8 @@ public class Messages extends NLS {
public static String CoreFile_toolTip;
public static String NewExecutable_toolTip;
public static String NewExecutableMenuName;
public static String RemoteExecutable_toolTip;
public static String RemoteExecutableMenuName;
public static String AttachedExecutable_toolTip;
public static String AttachedExecutableMenuName;

View file

@ -90,7 +90,7 @@ public class NewExecutableDialog extends TitleAreaDialog {
comp.setLayout( layout );
comp.setLayoutData( gd );
new Label( comp, SWT.None ).setText( remote ? Messages.GdbDebugNewExecutableCommand_Binary_on_host : Messages.GdbDebugNewExecutableCommand_Binary );
new Label( comp, SWT.None ).setText( remote ? Messages.GdbDebugNewExecutableCommand_Binary_on_host : Messages.GdbDebugExecutableCommand_Binary );
fHostBinaryText = new Text( comp, SWT.BORDER );
if (fHostBinary != null)
fHostBinaryText.setText(fHostBinary);
@ -103,7 +103,7 @@ public class NewExecutableDialog extends TitleAreaDialog {
}
} );
Button browseButton = new Button( comp, SWT.PUSH );
browseButton.setText( Messages.GdbDebugNewExecutableCommand_Browse );
browseButton.setText( Messages.GdbDebugExecutableCommand_Browse );
browseButton.setFont( JFaceResources.getDialogFont() );
setButtonLayoutData( browseButton );
browseButton.addSelectionListener( new SelectionAdapter() {
@ -140,7 +140,7 @@ public class NewExecutableDialog extends TitleAreaDialog {
fArgumentsText.setText(fArgs);
new Label( comp, SWT.None ).setText( Messages.GdbDebugNewExecutableCommand_BuildLog );
new Label( comp, SWT.None ).setText( Messages.GdbDebugExecutableCommand_BuildLog );
fBuildLogText = new Text( comp, SWT.BORDER );
if (fBuildLog != null)
fBuildLogText.setText(fBuildLog);

View file

@ -0,0 +1,251 @@
/*******************************************************************************
* Copyright (c) 2013, 2014 Mentor Graphics 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:
* Mentor Graphics - Initial API and implementation
* Red Hat Inc. - modified for use in Standalone Debugger
* Marc Khouzam (Ericsson) - Modified for remote launch (bug 450080)
*******************************************************************************/
package org.eclipse.cdt.debug.application;
import java.io.File;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public class RemoteExecutableDialog extends TitleAreaDialog {
private RemoteExecutableInfo fInfo = null;
private Text fHostBinaryText;
private Label fBinaryLabel;
private Text fBuildLogText;
private Text fAddressText;
private Text fPortText;
private Button fAttachButton;
private final String fHostBinary;
private final String fBuildLog;
private final String fAddress;
private final String fPort;
private final boolean fAttach;
public RemoteExecutableDialog (Shell parentShell) {
this(parentShell, null, null, null, null, false);
}
public RemoteExecutableDialog( Shell parentShell, String hostBinary, String buildLog, String address, String port, boolean attach) {
super( parentShell );
setShellStyle( getShellStyle() | SWT.RESIZE );
fHostBinary = hostBinary;
fBuildLog = buildLog;
fAddress = address;
fPort = port;
fAttach = attach;
}
@Override
protected Control createContents( Composite parent ) {
Control control = super.createContents( parent );
validate();
return control;
}
@Override
protected Control createDialogArea( Composite parent ) {
getShell().setText( Messages.GdbDebugRemoteExecutableCommand_Debug_Remote_Executable );
setTitle( Messages.GdbDebugRemoteExecutableCommand_Select_Remote_Options );
String message = Messages.GdbDebugRemoteExecutableCommand_Select_Remote_Options;
setMessage( message );
Composite control = (Composite)super.createDialogArea( parent );
Composite comp = new Composite( control, SWT.NONE );
GridData gd = new GridData( SWT.FILL, SWT.FILL, true, true );
GridLayout layout = new GridLayout( 3, false );
comp.setLayout( layout );
comp.setLayoutData( gd );
fBinaryLabel = new Label( comp, SWT.None );
fBinaryLabel.setText(fAttach ? Messages.GdbDebugExecutableCommand_Binary_Optional :
Messages.GdbDebugExecutableCommand_Binary );
fHostBinaryText = new Text( comp, SWT.BORDER );
if (fHostBinary != null)
fHostBinaryText.setText(fHostBinary);
fHostBinaryText.setLayoutData( new GridData( SWT.FILL, SWT.CENTER, true, false ) );
fHostBinaryText.addModifyListener( new ModifyListener() {
@Override
public void modifyText( ModifyEvent e ) {
validate();
}
} );
Button browseButton = new Button( comp, SWT.PUSH );
browseButton.setText( Messages.GdbDebugExecutableCommand_Browse );
browseButton.setFont( JFaceResources.getDialogFont() );
setButtonLayoutData( browseButton );
browseButton.addSelectionListener( new SelectionAdapter() {
@Override
public void widgetSelected( SelectionEvent e ) {
FileDialog dialog = new FileDialog( getShell() );
dialog.setFileName( fHostBinaryText.getText() );
String result = dialog.open();
if ( result != null ) {
fHostBinaryText.setText( result );
}
}
} );
new Label( comp, SWT.None ).setText( Messages.GdbDebugExecutableCommand_BuildLog );
fBuildLogText = new Text( comp, SWT.BORDER );
if (fBuildLog != null)
fBuildLogText.setText(fBuildLog);
fBuildLogText.setLayoutData( new GridData( SWT.FILL, SWT.CENTER, true, false, 2, 1 ) );
fBuildLogText.addModifyListener( new ModifyListener() {
@Override
public void modifyText( ModifyEvent e ) {
validate();
}
} );
new Label( comp, SWT.None ).setText( Messages.GdbDebugRemoteExecutableCommand_Host_name_or_ip_address );
fAddressText = new Text( comp, SWT.BORDER );
if (fAddress != null)
fAddressText.setText(fAddress);
fAddressText.setLayoutData( new GridData( SWT.FILL, SWT.CENTER, true, false, 2, 1 ) );
fAddressText.addModifyListener( new ModifyListener() {
@Override
public void modifyText( ModifyEvent e ) {
validate();
}
} );
new Label( comp, SWT.None ).setText( Messages.GdbDebugRemoteExecutableCommand_Port_number );
fPortText = new Text( comp, SWT.BORDER );
if (fPort != null)
fPortText.setText(fPort);
fPortText.setLayoutData( new GridData( SWT.FILL, SWT.CENTER, true, false, 2, 1 ) );
fPortText.addModifyListener( new ModifyListener() {
@Override
public void modifyText( ModifyEvent e ) {
validate();
}
} );
fAttachButton = new Button( comp, SWT.CHECK);
fAttachButton.setText( Messages.GdbDebugRemoteExecutableCommand_Attach);
fAttachButton.setSelection(fAttach);
fAttachButton.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
fBinaryLabel.setText(fAttachButton.getSelection() ?
Messages.GdbDebugExecutableCommand_Binary_Optional :
Messages.GdbDebugExecutableCommand_Binary );
validate();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
fBinaryLabel.setText(fAttachButton.getSelection() ?
Messages.GdbDebugExecutableCommand_Binary_Optional :
Messages.GdbDebugExecutableCommand_Binary );
validate();
}
});
return control;
}
@Override
protected void okPressed() {
fInfo = new RemoteExecutableInfo( fHostBinaryText.getText().trim(),
fBuildLogText.getText().trim(),
fAddressText.getText().trim(),
fPortText.getText().trim(),
fAttachButton.getSelection() );
super.okPressed();
}
public RemoteExecutableInfo getExecutableInfo() {
return fInfo;
}
private void validate() {
String error = null;
String hostBinary = fHostBinaryText.getText().trim();
if (hostBinary.isEmpty()) {
boolean attach = fAttachButton.getSelection();
if (!attach) error = Messages.GdbDebugNewExecutableCommand_Binary_must_be_specified;
}
else {
File file = new File(hostBinary);
if (!file.exists() ) {
error = Messages.GdbDebugNewExecutableCommand_Binary_file_does_not_exist;
}
else if (file.isDirectory()) {
error = Messages.GdbDebugNewExecutableCommand_Invalid_binary;
}
}
String buildLog = fBuildLogText.getText();
if (error == null && !buildLog.isEmpty()) {
File file = new File(buildLog);
if (!file.exists()) {
error = Messages.GdbDebugNewExecutableCommand_BuildLog_file_does_not_exist;
}
else if (file.isDirectory()) {
error = Messages.GdbDebugNewExecutableCommand_Invalid_buildLog;
}
}
String address = fAddressText.getText().trim();
if (error == null && address.isEmpty()) {
error = Messages.GdbDebugRemoteExecutableCommand_address_must_be_specified;
}
String port = fPortText.getText().trim();
if (error == null) {
if (port.isEmpty()) {
error = Messages.GdbDebugRemoteExecutableCommand_port_must_be_specified;
} else {
try {
Integer.parseInt(port);
} catch (NumberFormatException e) {
error = Messages.GdbDebugRemoteExecutableCommand_port_must_be_a_number;
}
}
}
setErrorMessage((error != null ) ? error : null);
getButton(IDialogConstants.OK_ID).setEnabled(getErrorMessage() == null);
}
}

View file

@ -0,0 +1,70 @@
/*******************************************************************************
* Copyright (c) 2013, 2014 Mentor Graphics 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:
* Mentor Graphics - Initial API and implementation
* Red Hat Inc. - modified for use in Standalone Debugger
* Marc Khouzam (Ericsson) - Modified for Remote launch (bug 450080)
*******************************************************************************/
package org.eclipse.cdt.debug.application;
/**
* This class provides information required to start debugging a remote executable.
*/
public class RemoteExecutableInfo {
private final String fHostPath;
private final String fBuildLog;
private final String fAddress;
private final String fPort;
private final boolean fAttach;
public RemoteExecutableInfo(String hostPath, String buildLog, String address, String port, boolean attach) {
super();
fHostPath = hostPath;
fBuildLog = buildLog;
fAddress = address;
fPort = port;
fAttach = attach;
}
public RemoteExecutableInfo(RemoteExecutableInfo info) {
fHostPath = info.getHostPath();
fBuildLog = info.getBuildLog();
fAddress = info.getAddress();
fPort = info.getPort();
fAttach = info.isAttach();
}
/**
* Returns the path of the executable on the host
*/
public String getHostPath() {
return fHostPath;
}
public String getAddress() {
return fAddress;
}
public String getPort() {
return fPort;
}
public boolean isAttach() {
return fAttach;
}
/**
* Get the build log path.
*
* @return the build log path or null
*/
public String getBuildLog() {
return fBuildLog;
}
}

View file

@ -8,6 +8,7 @@
# Contributors:
# Red Hat Inc. - initial API and implementation
# Mentor Graphics - GDB Debug New Executable messages
# Marc Khouzam (Ericsson) - Update for remote debugging support (bug 450080)
###############################################################################
ExecutablesView_ImportExecutables=Importing Executables
Debugger_Title=Eclipse C/C++ Stand-alone Debugger
@ -27,14 +28,15 @@ LaunchMissingError=Previous launch configuration cannot be found
DebuggerInitializingProblem=Problem occurred in start-up
GdbDebugNewExecutableCommand_Arguments=Arguments:
GdbDebugNewExecutableCommand_Binary=Binary:
GdbDebugNewExecutableCommand_Binary_file_does_not_exist=Debugger will start up with no input
GdbDebugExecutableCommand_Binary=Binary:
GdbDebugExecutableCommand_Binary_Optional=Binary (optional):
GdbDebugNewExecutableCommand_Binary_file_does_not_exist=Binary does not exist
GdbDebugNewExecutableCommand_Binary_must_be_specified=Binary must be specified
GdbDebugNewExecutableCommand_Binary_on_host=Binary on host:
GdbDebugNewExecutableCommand_Binary_on_target=Binary on target:
GdbDebugNewExecutableCommand_BuildLog=Build Log path:
GdbDebugExecutableCommand_BuildLog=Build Log path (optional):
GdbDebugNewExecutableCommand_Binary_on_target_must_be_specified=Binary on target must be specified
GdbDebugNewExecutableCommand_Browse=Browse...
GdbDebugExecutableCommand_Browse=Browse...
GdbDebugNewExecutableCommand_Debug_New_Executable=Debug New Executable
GdbDebugNewExecutableCommand_Host_binary_file_does_not_exist=Host binary file does not exist
GdbDebugNewExecutableCommand_Host_binary_must_be_specified=Host binary must be specified
@ -46,6 +48,15 @@ GdbDebugNewExecutableCommand_Select_binaries_on_host_and_target=Select binaries
GdbDebugNewExecutableCommand_Select_Binary=Select Binary
GdbDebugNewExecutableCommand_Select_binary_and_specify_arguments=Select a binary and specify the arguments
GdbDebugRemoteExecutableCommand_Debug_Remote_Executable=Debug Remote Executable
GdbDebugRemoteExecutableCommand_Select_Remote_Options=Select Remote Options
GdbDebugRemoteExecutableCommand_Host_name_or_ip_address=Host name or IP address
GdbDebugRemoteExecutableCommand_Port_number=Port number
GdbDebugRemoteExecutableCommand_Attach=Attach
GdbDebugRemoteExecutableCommand_address_must_be_specified=Host name or IP address must be specified
GdbDebugRemoteExecutableCommand_port_must_be_specified=IP Port must be specified
GdbDebugRemoteExecutableCommand_port_must_be_a_number=Port must be a valid number
GdbDebugCoreFileCommand_CoreFile=Core File Path:
GdbDebugCoreFileCommand_Debug_Core_File=Debug Core File
GdbDebugCoreFileCommand_Select_binary_and_specify_corefile=Select a binary and specify the core file
@ -84,5 +95,7 @@ CoreFileMenuName=Debug &Core File...
CoreFile_toolTip=Debug an executable that has generated a core file
NewExecutable_toolTip=Load a new executable and debug it
NewExecutableMenuName=&Debug New Executable...
RemoteExecutable_toolTip=Connect to a remote target and debug it
RemoteExecutableMenuName=Debug &Remote Executable...
AttachedExecutable_toolTip=Attach to an existing executable on the system and debug
AttachedExecutableMenuName=Debug &Attached Executable...

View file

@ -0,0 +1,86 @@
/*******************************************************************************
* Copyright (c) 2014 Red Hat, Inc.
* 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:
* Marc Khouzam (Ericsson) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.debug.application;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
public class DebugRemoteExecutable {
public DebugRemoteExecutable() {
}
public static ILaunchManager getLaunchManager() {
return DebugPlugin.getDefault().getLaunchManager();
}
public static ILaunchConfiguration createLaunchConfig(IProgressMonitor monitor,
String buildLog, String executable, String address, String port, boolean attach)
throws CoreException, InterruptedException {
ILaunchConfiguration config = null;
config = createConfiguration(executable, address, port, attach, true);
monitor.worked(1);
return config;
}
protected static ILaunchConfigurationType getLaunchConfigType(boolean attach) {
return getLaunchManager().getLaunchConfigurationType(
attach ? ICDTLaunchConfigurationConstants.ID_LAUNCH_C_ATTACH :
ICDTLaunchConfigurationConstants.ID_LAUNCH_C_REMOTE_APP);
}
protected static ILaunchConfiguration createConfiguration(String exePath, String address, String port, boolean attach, boolean save) {
ILaunchConfiguration config = null;
try {
ILaunchConfigurationType configType = getLaunchConfigType(attach);
ILaunchConfigurationWorkingCopy wc = configType.newInstance(
null,
getLaunchManager().generateLaunchConfigurationName(
attach ? "CDT_REMOTE_ATTACH" : "CDT_REMOTE")); //$NON-NLS-1$ //$NON-NLS-2$
wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE,
attach ? IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE_ATTACH :
IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE);
if (exePath != null && exePath.length() > 0) {
wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, exePath);
} else {
assert attach;
}
wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME,
"Executables"); //$NON-NLS-1$
wc.setAttribute(
ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY,
(String) null);
wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_REMOTE_TCP, true);
wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_HOST, address);
wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_PORT, port);
if (save) {
config = wc.doSave();
} else {
config = wc;
}
} catch (CoreException e) {
e.printStackTrace();
}
return config;
}
}

View file

@ -0,0 +1,67 @@
/*******************************************************************************
* Copyright (c) 2014 Mentor Graphics 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:
* Marc Khouzam (Ericsson) - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.debug.application;
import org.eclipse.cdt.debug.application.RemoteExecutableDialog;
import org.eclipse.cdt.debug.application.RemoteExecutableInfo;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class DebugRemoteExecutableHandler extends AbstractHandler {
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
RemoteExecutableDialog dialog = new RemoteExecutableDialog(new Shell());
if (dialog.open() == IDialogConstants.OK_ID) {
RemoteExecutableInfo info = dialog.getExecutableInfo();
String executable = info.getHostPath();
String buildLog = info.getBuildLog();
String address = info.getAddress();
String port = info.getPort();
boolean attach = info.isAttach();
try {
final ILaunchConfiguration config = DebugRemoteExecutable.createLaunchConfig(new NullProgressMonitor(), buildLog, executable, address, port, attach);
if (config != null) {
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
DebugUITools.launch(config, ILaunchManager.DEBUG_MODE);
}
});
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (CoreException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
return null;
}
}