diff options
author | Uwe Stieber | 2015-05-21 10:39:40 +0000 |
---|---|---|
committer | Uwe Stieber | 2015-05-21 10:39:40 +0000 |
commit | 77d2fc8a4c8e3474421f7bd4efef515454ba7367 (patch) | |
tree | 8a1c2c0471f0784356494d9687351d5636f3e043 | |
parent | a1b45a3b01e9d6265f2ae365ebbf8492fe6c77f7 (diff) | |
download | org.eclipse.tcf-77d2fc8a4c8e3474421f7bd4efef515454ba7367.tar.gz org.eclipse.tcf-77d2fc8a4c8e3474421f7bd4efef515454ba7367.tar.xz org.eclipse.tcf-77d2fc8a4c8e3474421f7bd4efef515454ba7367.zip |
Target Explorer: Unify gdbserver launch code and enable it for attach launches
10 files changed, 327 insertions, 293 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/interfaces/IRemoteTEConfigurationConstants.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/interfaces/IRemoteTEConfigurationConstants.java index 9e78f5bb5..d976b1ef8 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/interfaces/IRemoteTEConfigurationConstants.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/interfaces/IRemoteTEConfigurationConstants.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2014 PalmSource, Inc. and others. + * Copyright (c) 2006, 2015 PalmSource, Inc. 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 @@ -26,12 +26,18 @@ public interface IRemoteTEConfigurationConstants { public static final String ATTR_GDBSERVER_COMMAND_DEFAULT = "gdbserver"; //$NON-NLS-1$ /* - * Generic Remote Path and Download options ATTR_REMOTE_PATH: Path of the binary on the remote. - * ATTR_SKIP_DOWNLOAD_TO_TARGET: true if download to remote is not desired. + * Generic Remote Path and Download options: + * ATTR_REMOTE_PATH: Path of the binary on the remote. + * ATTR_SKIP_DOWNLOAD_TO_TARGET: true if download to remote is not desired. */ public static final String ATTR_REMOTE_PATH = DebugPlugin.getUniqueIdentifier() + ".ATTR_TARGET_PATH"; //$NON-NLS-1$ public static final String ATTR_SKIP_DOWNLOAD_TO_TARGET = DebugPlugin.getUniqueIdentifier() + ".ATTR_SKIP_DOWNLOAD_TO_TARGET"; //$NON-NLS-1$ + /* + * The remote PID to attach to. + */ + public static final String ATTR_REMOTE_PID = DebugPlugin.getUniqueIdentifier() + ".ATTR_REMOTE_PID"; //$NON-NLS-1$ + public static final String ATTR_PRERUN_COMMANDS = DebugPlugin.getUniqueIdentifier() + ".ATTR_PRERUN_CMDS"; //$NON-NLS-1$ public static final String ATTR_REMOTE_PATH_DEFAULT = ""; //$NON-NLS-1$ diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/launching/TEGdbAbstractLaunchDelegate.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/launching/TEGdbAbstractLaunchDelegate.java new file mode 100644 index 000000000..f82be10d5 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/launching/TEGdbAbstractLaunchDelegate.java @@ -0,0 +1,274 @@ +/******************************************************************************* + * Copyright (c) 2015 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.tcf.launch.cdt.launching; + +import java.io.IOException; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.cdt.dsf.concurrent.DsfRunnable; +import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor; +import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants; +import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch; +import org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate; +import org.eclipse.core.runtime.Assert; +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.SubProgressMonitor; +import org.eclipse.core.variables.VariablesPlugin; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.osgi.util.NLS; +import org.eclipse.tcf.protocol.IPeer; +import org.eclipse.tcf.te.runtime.callback.Callback; +import org.eclipse.tcf.te.tcf.core.streams.StreamsDataReceiver; +import org.eclipse.tcf.te.tcf.launch.cdt.activator.Activator; +import org.eclipse.tcf.te.tcf.launch.cdt.interfaces.IRemoteTEConfigurationConstants; +import org.eclipse.tcf.te.tcf.launch.cdt.nls.Messages; +import org.eclipse.tcf.te.tcf.launch.cdt.utils.TEHelper; +import org.eclipse.tcf.te.tcf.processes.core.launcher.ProcessLauncher; + +/** + * Abstract launch delegate implementation handling launching the gdbserver via TCF/TE. + */ +public abstract class TEGdbAbstractLaunchDelegate extends GdbLaunchDelegate { + + /** + * Constructor + */ + public TEGdbAbstractLaunchDelegate() { + super(); + } + + /** + * Constructor + * + * @param requireCProject <code>True</code> if a C project is required for launching, + * <code>false</code> otherwise. + */ + public TEGdbAbstractLaunchDelegate(boolean requireCProject) { + super(requireCProject); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public void launch(ILaunchConfiguration config, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { + // If not of the expected type --> return immediately + if (!(launch instanceof GdbLaunch)) return; + + // Initialize TE + Activator.getDefault().initializeTE(); + // Get the peer from the launch configuration + IPeer peer = TEHelper.getCurrentConnection(config).getPeer(); + + // Get the executable path (run/debug application) or the PID (attach to application) + IPath exePath = checkBinaryDetails(config); + String remoteExePath = null; + String remotePID = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_REMOTE_PID, (String)null); + + // If neither executable not PID is given --> abort + if (exePath == null && remotePID == null) { + abort(Messages.TEGdbAbstractLaunchDelegate_no_program_or_pid, null, ICDTLaunchConfigurationConstants.ERR_PROGRAM_NOT_EXIST); + } + + // If an executable path is specified, download the binary if needed + if (exePath != null) { + remoteExePath = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_REMOTE_PATH, ""); //$NON-NLS-1$ + monitor.setTaskName(Messages.TEGdbAbstractLaunchDelegate_downloading); + boolean skipDownload = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_SKIP_DOWNLOAD_TO_TARGET, false); + + if (!skipDownload) { + try { + TEHelper.remoteFileTransfer(peer, exePath.toString(), remoteExePath, new SubProgressMonitor(monitor, 80)); + } + catch (IOException e) { + abort(NLS.bind(Messages.TEGdbAbstractLaunchDelegate_filetransferFailed, e.getLocalizedMessage()), e, ICDTLaunchConfigurationConstants.ERR_PROGRAM_NOT_EXIST); + } + } + } + + // 2.Launch gdbserver on target + String gdbserverPortNumber = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_GDBSERVER_PORT, IRemoteTEConfigurationConstants.ATTR_GDBSERVER_PORT_DEFAULT); + String gdbserverPortNumberMappedTo = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_GDBSERVER_PORT_MAPPED_TO, (String) null); + String gdbserverCommand = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_GDBSERVER_COMMAND, IRemoteTEConfigurationConstants.ATTR_GDBSERVER_COMMAND_DEFAULT); + String commandArguments = ""; //$NON-NLS-1$ + if (remotePID != null && !"".equals(remotePID)) { //$NON-NLS-1$ + commandArguments = "--attach :" + gdbserverPortNumber + " " + remotePID; //$NON-NLS-1$ //$NON-NLS-2$ + monitor.setTaskName(Messages.TEGdbAbstractLaunchDelegate_attaching_program); + } else if (remoteExePath != null && !"".equals(remoteExePath)) { //$NON-NLS-1$ + commandArguments = ":" + gdbserverPortNumber + " " + TEHelper.spaceEscapify(remoteExePath); //$NON-NLS-1$ //$NON-NLS-2$ + + String arguments = getProgramArguments(config); + String prelaunchCmd = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_PRERUN_COMMANDS, ""); //$NON-NLS-1$ + + TEHelper.launchCmd(peer, prelaunchCmd, null, new SubProgressMonitor(monitor, 2), new Callback()); + + if (arguments != null && !arguments.equals("")) { //$NON-NLS-1$ + commandArguments += " " + arguments; //$NON-NLS-1$ + } + monitor.setTaskName(Messages.TEGdbAbstractLaunchDelegate_starting_program); + } + + final AtomicBoolean gdbServerStarted = new AtomicBoolean(false); + final AtomicBoolean gdbServerReady = new AtomicBoolean(false); + final AtomicBoolean gdbServerExited = new AtomicBoolean(false); + final StringBuffer gdbServerOutput = new StringBuffer(); + final Object lock = new Object(); + + final GdbLaunch l = (GdbLaunch) launch; + final Callback callback = new Callback() { + @Override + protected void internalDone(Object caller, IStatus status) { + if (!status.isOK()) { + gdbServerOutput.append(status.getMessage()); + gdbServerExited.set(true); + synchronized (lock) { + lock.notifyAll(); + } + } + else { + gdbServerStarted.set(true); + } + super.internalDone(caller, status); + } + }; + + StreamsDataReceiver.Listener listener = new StreamsDataReceiver.Listener() { + + @Override + public void dataReceived(String data) { + gdbServerOutput.append(data); + if (data.contains("Listening on port")) { //$NON-NLS-1$ + gdbServerReady.set(true); + synchronized (lock) { + lock.notifyAll(); + } + } + else if (data.contains("GDBserver exiting") || data.contains("Exiting")) { //$NON-NLS-1$ //$NON-NLS-2$ + gdbServerExited.set(true); + synchronized (lock) { + lock.notifyAll(); + } + } + + } + }; + + ProcessLauncher launcher = TEHelper.launchCmd(peer, gdbserverCommand, commandArguments, listener, new SubProgressMonitor(monitor, 3), callback); + + // Now wait until gdbserver is up and running on the remote host + while (!gdbServerReady.get() && !gdbServerExited.get()) { + if (monitor.isCanceled()) { + // gdbserver launch failed + // Need to shutdown the DSF launch session because it is + // partially started already. + shutdownSession(l, Messages.TEGdbAbstractLaunchDelegate_canceledMsg); + } + if (gdbServerStarted.get() && launcher.getChannel() == null) { + // gdbserver died + shutdownSession(l, gdbServerOutput.toString()); + } + synchronized (lock) { + try { + lock.wait(300); + } + catch (InterruptedException e) { + } + } + } + + // If the gdbserver exited, also shutdown the DSF launch session + if (gdbServerExited.get()) { + shutdownSession(l, gdbServerOutput.toString()); + } + + // 3. Let debugger know how gdbserver was started on the remote + ILaunchConfigurationWorkingCopy wc = config.getWorkingCopy(); + wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_REMOTE_TCP, true); + wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_HOST, TEHelper.getCurrentConnection(config).getPeer().getAttributes().get(IPeer.ATTR_IP_HOST)); + wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_PORT, gdbserverPortNumberMappedTo == null || "".equals(gdbserverPortNumberMappedTo) ? gdbserverPortNumber : gdbserverPortNumberMappedTo); //$NON-NLS-1$ + wc.doSave(); + try { + super.launch(config, mode, launch, monitor); + } + catch (CoreException ex) { + // Launch failed, need to kill gdbserver + launcher.terminate(); + // report failure further + throw ex; + } + finally { + monitor.done(); + } + } + + /** + * Shutdown the GDB debug session. + * + * @param launch The GDB launch. Must not be <code>null</code>. + * @throws CoreException If the GDB debug session shutdown failed. + */ + protected void shutdownSession(final GdbLaunch launch) throws CoreException { + shutdownSession(launch, null); + } + + /** + * Shutdown the GDB debug session. + * + * @param launch The GDB launch. Must not be <code>null</code>. + * @param details Error message, may be <code>null</code> + * @throws CoreException If the GDB debug session shutdown failed. + */ + protected void shutdownSession(final GdbLaunch launch, String details) throws CoreException { + Assert.isNotNull(launch); + try { + launch.getSession().getExecutor().submit(new DsfRunnable() { + @Override + public void run() { + // Avoid an NPE while running the shutdown + if (launch.getDsfExecutor() != null) { + launch.shutdownSession(new ImmediateRequestMonitor()); + } + } + }).get(1000, TimeUnit.MILLISECONDS); + } + catch (RejectedExecutionException e) { + // Session disposed. + } + catch (Exception e) { + // Ignore exceptions during shutdown. + } + + String msg = Messages.TEGdbAbstractLaunchDelegate_gdbserverFailedToStartErrorMessage; + if (details != null && details.length() > 0) msg = NLS.bind(Messages.TEGdbAbstractLaunchDelegate_gdbserverFailedToStartErrorWithDetails, details); + abort(msg, null, ICDTLaunchConfigurationConstants.ERR_DEBUGGER_NOT_INSTALLED); + } + + protected String getProgramArguments(ILaunchConfiguration config) throws CoreException { + String args = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, (String) null); + if (args != null) { + args = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(args); + } + return args; + } + + @Override + protected String getPluginID() { + return Activator.PLUGIN_ID; + } + +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/launching/TEGdbAttachLaunchDelegate.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/launching/TEGdbAttachLaunchDelegate.java index 3eb444a26..cfa2284fb 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/launching/TEGdbAttachLaunchDelegate.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/launching/TEGdbAttachLaunchDelegate.java @@ -9,11 +9,10 @@ *******************************************************************************/ package org.eclipse.tcf.te.tcf.launch.cdt.launching; -import org.eclipse.cdt.dsf.gdb.launching.GdbAttachLaunchDelegate; /** * Attach to a remotely running process and launch the necessary gdbserver via TCF/TE. */ -public class TEGdbAttachLaunchDelegate extends GdbAttachLaunchDelegate { +public class TEGdbAttachLaunchDelegate extends TEGdbAbstractLaunchDelegate { } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/launching/TEGdbLaunchDelegate.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/launching/TEGdbLaunchDelegate.java index d6aced122..5f6c97ec8 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/launching/TEGdbLaunchDelegate.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/launching/TEGdbLaunchDelegate.java @@ -15,224 +15,10 @@ package org.eclipse.tcf.te.tcf.launch.cdt.launching; -import java.io.IOException; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; +/** + * Launch and debug a remote application. The necessary gdbserver is launched via TCF/TE. + */ +public class TEGdbLaunchDelegate extends TEGdbAbstractLaunchDelegate { -import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; -import org.eclipse.cdt.dsf.concurrent.DsfRunnable; -import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor; -import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants; -import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch; -import org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate; -import org.eclipse.core.runtime.Assert; -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.SubProgressMonitor; -import org.eclipse.core.variables.VariablesPlugin; -import org.eclipse.debug.core.ILaunch; -import org.eclipse.debug.core.ILaunchConfiguration; -import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; -import org.eclipse.osgi.util.NLS; -import org.eclipse.tcf.protocol.IPeer; -import org.eclipse.tcf.te.runtime.callback.Callback; -import org.eclipse.tcf.te.tcf.core.streams.StreamsDataReceiver; -import org.eclipse.tcf.te.tcf.launch.cdt.activator.Activator; -import org.eclipse.tcf.te.tcf.launch.cdt.interfaces.IRemoteTEConfigurationConstants; -import org.eclipse.tcf.te.tcf.launch.cdt.nls.Messages; -import org.eclipse.tcf.te.tcf.launch.cdt.utils.TEHelper; -import org.eclipse.tcf.te.tcf.processes.core.launcher.ProcessLauncher; - -public class TEGdbLaunchDelegate extends GdbLaunchDelegate { - - @Override - public void launch(ILaunchConfiguration config, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { - IPath exePath = checkBinaryDetails(config); - if (exePath != null && launch instanceof GdbLaunch) { - // -1. Initialize TE - Activator.getDefault().initializeTE(); - // 0. Get the peer from the launch configuration - IPeer peer = TEHelper.getCurrentConnection(config).getPeer(); - // 1.Download binary if needed - String remoteExePath = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_REMOTE_PATH, ""); //$NON-NLS-1$ - monitor.setTaskName(Messages.RemoteRunLaunchDelegate_2); - boolean skipDownload = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_SKIP_DOWNLOAD_TO_TARGET, false); - - if (!skipDownload) { - try { - TEHelper.remoteFileTransfer(peer, exePath.toString(), remoteExePath, new SubProgressMonitor(monitor, 80)); - } catch (IOException e) { - abort(NLS.bind(Messages.RemoteGdbLaunchDelegate_filetransferFailed, e.getLocalizedMessage()), e, ICDTLaunchConfigurationConstants.ERR_PROGRAM_NOT_EXIST); - } - } - - // 2.Launch gdbserver on target - String gdbserverPortNumber = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_GDBSERVER_PORT, IRemoteTEConfigurationConstants.ATTR_GDBSERVER_PORT_DEFAULT); - String gdbserverPortNumberMappedTo = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_GDBSERVER_PORT_MAPPED_TO, (String) null); - String gdbserverCommand = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_GDBSERVER_COMMAND, IRemoteTEConfigurationConstants.ATTR_GDBSERVER_COMMAND_DEFAULT); - String commandArguments = ":" + gdbserverPortNumber + " " + TEHelper.spaceEscapify(remoteExePath); //$NON-NLS-1$ //$NON-NLS-2$ - String arguments = getProgramArguments(config); - String prelaunchCmd = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_PRERUN_COMMANDS, ""); //$NON-NLS-1$ - - TEHelper.launchCmd(peer, prelaunchCmd, null, new SubProgressMonitor(monitor, 2), new Callback()); - - if (arguments != null && !arguments.equals("")) //$NON-NLS-1$ - commandArguments += " " + arguments; //$NON-NLS-1$ - monitor.setTaskName(Messages.RemoteRunLaunchDelegate_9); - - final AtomicBoolean gdbServerStarted = new AtomicBoolean(false); - final AtomicBoolean gdbServerReady = new AtomicBoolean(false); - final AtomicBoolean gdbServerExited = new AtomicBoolean(false); - final StringBuffer gdbServerOutput = new StringBuffer(); - final Object lock = new Object(); - - final GdbLaunch l = (GdbLaunch) launch; - final Callback callback = new Callback() { - @Override - protected void internalDone(Object caller, IStatus status) { - if (!status.isOK()) { - gdbServerOutput.append(status.getMessage()); - gdbServerExited.set(true); - synchronized (lock) { - lock.notifyAll(); - } - } else { - gdbServerStarted.set(true); - } - super.internalDone(caller, status); - } - }; - - StreamsDataReceiver.Listener listener = new StreamsDataReceiver.Listener() { - - @Override - public void dataReceived(String data) { - gdbServerOutput.append(data); - if (data.contains("Listening on port")) { //$NON-NLS-1$ - gdbServerReady.set(true); - synchronized (lock) { - lock.notifyAll(); - } - } - else if (data.contains("GDBserver exiting") || data.contains("Exiting")) { //$NON-NLS-1$ //$NON-NLS-2$ - gdbServerExited.set(true); - synchronized (lock) { - lock.notifyAll(); - } - } - - } - }; - - ProcessLauncher launcher = TEHelper.launchCmd(peer, gdbserverCommand, commandArguments, listener, new SubProgressMonitor(monitor, 3), callback); - - // Now wait until gdbserver is up and running on the remote host - while (!gdbServerReady.get() && !gdbServerExited.get()) { - if (monitor.isCanceled()) { - // gdbserver launch failed - // Need to shutdown the DSF launch session because it is - // partially started already. - shutdownSession(l, Messages.TEGdbLaunchDelegate_canceledMsg); - } - if (gdbServerStarted.get() && launcher.getChannel() == null) { - // gdbserver died - shutdownSession(l, gdbServerOutput.toString()); - } - synchronized (lock) { - try { - lock.wait(300); - } - catch (InterruptedException e) { - } - } - } - - // If the gdbserver exited, also shutdown the DSF launch session - if (gdbServerExited.get()) { - shutdownSession(l, gdbServerOutput.toString()); - } - - // 3. Let debugger know how gdbserver was started on the remote - ILaunchConfigurationWorkingCopy wc = config.getWorkingCopy(); - wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_REMOTE_TCP, true); - wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_HOST, - TEHelper.getCurrentConnection(config).getPeer().getAttributes().get(IPeer.ATTR_IP_HOST)); - wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_PORT, gdbserverPortNumberMappedTo == null || "".equals(gdbserverPortNumberMappedTo) ? gdbserverPortNumber : gdbserverPortNumberMappedTo); //$NON-NLS-1$ - wc.doSave(); - try { - super.launch(config, mode, launch, monitor); - } - catch (CoreException ex) { - // Launch failed, need to kill gdbserver - launcher.terminate(); - // report failure further - throw ex; - } - finally { - monitor.done(); - } - } - } - - /** - * Shutdown the GDB debug session. - * - * @param launch The GDB launch. Must not be <code>null</code>. - * @throws CoreException If the GDB debug session shutdown failed. - */ - protected void shutdownSession(final GdbLaunch launch) throws CoreException { - shutdownSession(launch, null); - } - - /** - * Shutdown the GDB debug session. - * - * @param launch The GDB launch. Must not be <code>null</code>. - * @param details Error message, may be <code>null</code> - * @throws CoreException If the GDB debug session shutdown failed. - */ - protected void shutdownSession(final GdbLaunch launch, String details) throws CoreException { - Assert.isNotNull(launch); - try { - launch.getSession().getExecutor().submit(new DsfRunnable() { - @Override - public void run() { - // Avoid an NPE while running the shutdown - if (launch.getDsfExecutor() != null) { - launch.shutdownSession(new ImmediateRequestMonitor()); - } - } - }).get(1000, TimeUnit.MILLISECONDS); - } - catch (RejectedExecutionException e) { - // Session disposed. - } - catch (Exception e) { - // Ignore exceptions during shutdown. - } - - String msg = Messages.RemoteGdbLaunchDelegate_gdbserverFailedToStartErrorMessage; - if (details != null && details.length() > 0) - msg = NLS.bind(Messages.RemoteGdbLaunchDelegate_gdbserverFailedToStartErrorWithDetails, details); - abort(msg, null, ICDTLaunchConfigurationConstants.ERR_DEBUGGER_NOT_INSTALLED); - } - - protected String getProgramArguments(ILaunchConfiguration config) throws CoreException { - String args = config - .getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, (String) null); - if (args != null) { - args = VariablesPlugin.getDefault().getStringVariableManager() - .performStringSubstitution(args); - } - return args; - } - - @Override - protected String getPluginID() { - return Activator.PLUGIN_ID; - } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/launching/TERunLaunchDelegate.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/launching/TERunLaunchDelegate.java index 40747147b..34174a699 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/launching/TERunLaunchDelegate.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/launching/TERunLaunchDelegate.java @@ -44,19 +44,19 @@ public class TERunLaunchDelegate extends AbstractCLaunchDelegate { IPeer peer = TEHelper.getCurrentConnection(config).getPeer(); // 1.Download binary if needed String remoteExePath = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_REMOTE_PATH, ""); //$NON-NLS-1$ - monitor.setTaskName(Messages.RemoteRunLaunchDelegate_2); + monitor.setTaskName(Messages.TEGdbAbstractLaunchDelegate_downloading); boolean skipDownload = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_SKIP_DOWNLOAD_TO_TARGET, false); if (!skipDownload) { try { TEHelper.remoteFileTransfer(peer, exePath.toString(), remoteExePath, new SubProgressMonitor(monitor, 80)); } catch (IOException e) { - abort(NLS.bind(Messages.RemoteGdbLaunchDelegate_filetransferFailed, e.getLocalizedMessage()), e, ICDTLaunchConfigurationConstants.ERR_PROGRAM_NOT_EXIST); + abort(NLS.bind(Messages.TEGdbAbstractLaunchDelegate_filetransferFailed, e.getLocalizedMessage()), e, ICDTLaunchConfigurationConstants.ERR_PROGRAM_NOT_EXIST); } } // 2. Run the binary - monitor.setTaskName(Messages.RemoteRunLaunchDelegate_12); + monitor.setTaskName(Messages.TEGdbAbstractLaunchDelegate_starting_debugger); String arguments = getProgramArguments(config); String prelaunchCmd = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_PRERUN_COMMANDS, ""); //$NON-NLS-1$ diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/nls/Messages.java index 33e482575..168f00ee9 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/nls/Messages.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/nls/Messages.java @@ -23,7 +23,6 @@ public class Messages extends NLS { private static final String BUNDLE_NAME = "org.eclipse.tcf.te.tcf.launch.cdt.nls.Messages"; //$NON-NLS-1$ public static String Gdbserver_name_textfield_label; - public static String Gdbserver_Settings_Tab_Name; public static String Port_number_textfield_label; @@ -32,50 +31,28 @@ public class Messages extends NLS { public static String Remote_GDB_Debugger_Options; public static String RemoteCMainTab_Prerun; - public static String RemoteCMainTab_Program; - public static String RemoteCMainTab_Remote_Path_Browse_Button; - - public static String RemoteCMainTab_Remote_Path_Browse_Button_Title; public static String RemoteCMainTab_SkipDownload; public static String RemoteCMainTab_ErrorNoProgram; public static String RemoteCMainTab_ErrorNoConnection; - public static String RemoteCMainTab_Connection; - public static String RemoteCMainTab_New; - public static String RemoteCMainTab_Properties; - public static String RemoteCMainTab_Properties_title; - public static String RemoteCMainTab_Properties_Location; - public static String RemoteCMainTab_Properties_Skip_default; - - public static String RemoteGdbLaunchDelegate_filetransferFailed; - public static String RemoteGdbLaunchDelegate_gdbserverFailedToStartErrorMessage; - public static String RemoteGdbLaunchDelegate_gdbserverFailedToStartErrorWithDetails; - - public static String RemoteRunLaunchDelegate_0; public static String RemoteRunLaunchDelegate_RemoteShell; - public static String RemoteRunLaunchDelegate_1; - - public static String RemoteRunLaunchDelegate_10; - - public static String RemoteRunLaunchDelegate_12; - - public static String RemoteRunLaunchDelegate_13; - - public static String RemoteRunLaunchDelegate_2; - public static String RemoteRunLaunchDelegate_3; - public static String RemoteRunLaunchDelegate_4; - public static String RemoteRunLaunchDelegate_5; - public static String RemoteRunLaunchDelegate_6; - public static String RemoteRunLaunchDelegate_7; - public static String RemoteRunLaunchDelegate_8; - public static String RemoteRunLaunchDelegate_9; + public static String TEHelper_executing; + public static String TEHelper_connection_not_found; public static String TCFPeerSelector_0; - public static String TEGdbLaunchDelegate_canceledMsg; + public static String TEGdbAbstractLaunchDelegate_no_program_or_pid; + public static String TEGdbAbstractLaunchDelegate_downloading; + public static String TEGdbAbstractLaunchDelegate_attaching_program; + public static String TEGdbAbstractLaunchDelegate_starting_program; + public static String TEGdbAbstractLaunchDelegate_starting_debugger; + public static String TEGdbAbstractLaunchDelegate_canceledMsg; + public static String TEGdbAbstractLaunchDelegate_filetransferFailed; + public static String TEGdbAbstractLaunchDelegate_gdbserverFailedToStartErrorMessage; + public static String TEGdbAbstractLaunchDelegate_gdbserverFailedToStartErrorWithDetails; static { // initialize resource bundle diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/nls/Messages.properties index fd99857b6..7d5cd7b16 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/nls/Messages.properties +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/nls/Messages.properties @@ -19,41 +19,33 @@ # NLS_MESSAGEFORMAT_VAR # NLS_ENCODING=UTF-8 -RemoteRunLaunchDelegate_0=Launching -RemoteRunLaunchDelegate_RemoteShell=Remote Shell -RemoteRunLaunchDelegate_1=Unidentified mode {0} passed to RemoteRunLaunchDelegate -RemoteRunLaunchDelegate_10=Initializing RSE -RemoteRunLaunchDelegate_12=Starting Debugger -RemoteRunLaunchDelegate_13=Could not find the remote connection. -RemoteRunLaunchDelegate_2=Downloading -RemoteRunLaunchDelegate_3=Wrong service requested. -RemoteRunLaunchDelegate_4=No subsystem found.\n -RemoteRunLaunchDelegate_5=Could not connect to the remote system. -RemoteRunLaunchDelegate_6=Error during file upload. -RemoteRunLaunchDelegate_7=Could not create the hostShellProcess.\n -RemoteRunLaunchDelegate_8=Executing {0} {1} -RemoteRunLaunchDelegate_9=Starting Program +Remote_GDB_Debugger_Options=Remote GDB Debugger Options RemoteCMainTab_Prerun=Commands to execute before application RemoteCMainTab_Program=Remote Absolute File Path for C/C++ Application: RemoteCMainTab_SkipDownload=Skip download to target path. -Remote_GDB_Debugger_Options=Remote GDB Debugger Options RemoteCMainTab_ErrorNoProgram=Remote executable path is not specified. RemoteCMainTab_ErrorNoConnection=Remote Connection must be selected. RemoteCMainTab_Remote_Path_Browse_Button=Browse... -RemoteCMainTab_Connection=Connection: -RemoteCMainTab_New=New... + Gdbserver_Settings_Tab_Name=Gdbserver Settings Gdbserver_name_textfield_label=Gdbserver name: + Port_number_textfield_label=Port number: Port_number_mapped_to_textfield_label=Mapped to: -RemoteCMainTab_Remote_Path_Browse_Button_Title=Select Remote C/C++ Application File -RemoteCMainTab_Properties=Properties... -RemoteCMainTab_Properties_title=Properties -RemoteCMainTab_Properties_Location=Remote workspace location: -RemoteCMainTab_Properties_Skip_default=Skip download to target path by default -RemoteGdbLaunchDelegate_filetransferFailed=Failed to download application image to target. Possibly caused by: {0} -RemoteGdbLaunchDelegate_gdbserverFailedToStartErrorMessage=Could not start gdbserver on the remote host. See console output for more details. -RemoteGdbLaunchDelegate_gdbserverFailedToStartErrorWithDetails=Could not start gdbserver on the remote host. Possibly caused by:\n{0} + +TEHelper_executing=Executing {0} {1} +TEHelper_connection_not_found=Could not find the remote connection. + +TEGdbAbstractLaunchDelegate_no_program_or_pid=Either the application path or the PID to attach to must be specified. +TEGdbAbstractLaunchDelegate_downloading=Downloading +TEGdbAbstractLaunchDelegate_attaching_program=Attaching to Application +TEGdbAbstractLaunchDelegate_starting_program=Starting Application +TEGdbAbstractLaunchDelegate_starting_debugger=Starting Debugger +TEGdbAbstractLaunchDelegate_filetransferFailed=Failed to download application image to target. Possibly caused by: {0} +TEGdbAbstractLaunchDelegate_gdbserverFailedToStartErrorMessage=Could not start gdbserver on the remote host. See console output for more details. +TEGdbAbstractLaunchDelegate_gdbserverFailedToStartErrorWithDetails=Could not start gdbserver on the remote host. Possibly caused by:\n{0} + TCFPeerSelector_0=Connection: -TEGdbLaunchDelegate_canceledMsg=Canceled by user + +TEGdbAbstractLaunchDelegate_canceledMsg=Canceled by user diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/tabs/TEAbstractDebuggerTab.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/tabs/TEAbstractDebuggerTab.java index 80cd548b2..b7cc496c1 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/tabs/TEAbstractDebuggerTab.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/tabs/TEAbstractDebuggerTab.java @@ -22,7 +22,7 @@ import org.eclipse.swt.widgets.Control; * Abstract custom debugger tab implementation. */ @SuppressWarnings("restriction") -public class TEAbstractDebuggerTab extends CDebuggerTab { +public abstract class TEAbstractDebuggerTab extends CDebuggerTab { // Do not change the ID. We want to maintain compatibility private final static String DEFAULTS_SET = "org.eclipse.cdt.launch.remote.te.TEDSFDebuggerTab.DEFAULTS_SET"; //$NON-NLS-1$ diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/tabs/TEAbstractMainTab.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/tabs/TEAbstractMainTab.java index ddf8ba9f1..014208a7b 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/tabs/TEAbstractMainTab.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/tabs/TEAbstractMainTab.java @@ -46,7 +46,7 @@ import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode; * Abstract custom main tab implementation. */ @SuppressWarnings("restriction") -public class TEAbstractMainTab extends CMainTab { +public abstract class TEAbstractMainTab extends CMainTab { /* Labels and Error Messages */ private static final String REMOTE_PROG_LABEL_TEXT = Messages.RemoteCMainTab_Program; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/utils/TEHelper.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/utils/TEHelper.java index ea3152f0c..ae2c0f42a 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/utils/TEHelper.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.cdt/src/org/eclipse/tcf/te/tcf/launch/cdt/utils/TEHelper.java @@ -85,7 +85,7 @@ public class TEHelper { // Copy the host file to a temporary location if needed if (copyViaTemp) { - monitor.beginTask(Messages.RemoteRunLaunchDelegate_2 + " " + localFilePath + " to " + remoteFilePath, 200); //$NON-NLS-1$ //$NON-NLS-2$ + monitor.beginTask(Messages.TEGdbAbstractLaunchDelegate_downloading + " " + localFilePath + " to " + remoteFilePath, 200); //$NON-NLS-1$ //$NON-NLS-2$ try { IPath hostPath = item.getHostPath(); @@ -131,7 +131,7 @@ public class TEHelper { item = new FileTransferItem(new Path(tempFile.getAbsolutePath()), remoteFilePath); item.setProperty(IFileTransferItem.PROPERTY_DIRECTION, "" + IFileTransferItem.HOST_TO_TARGET); //$NON-NLS-1$ } else { - monitor.beginTask(Messages.RemoteRunLaunchDelegate_2 + " " + localFilePath + " to " + remoteFilePath, 100); //$NON-NLS-1$ //$NON-NLS-2$ + monitor.beginTask(Messages.TEGdbAbstractLaunchDelegate_downloading + " " + localFilePath + " to " + remoteFilePath, 100); //$NON-NLS-1$ //$NON-NLS-2$ } // Transfer the file to the target @@ -164,7 +164,7 @@ public class TEHelper { String peerId = config.getAttribute(IRemoteTEConfigurationConstants.ATTR_REMOTE_CONNECTION, ""); //$NON-NLS-1$ IPeerNode connection = getPeerNode(peerId); if (connection == null) { - abort(Messages.RemoteRunLaunchDelegate_13, null, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR); + abort(Messages.TEHelper_connection_not_found, null, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR); } return connection; } @@ -191,7 +191,7 @@ public class TEHelper { public static ProcessLauncher launchCmd(final IPeer peer, String remoteCommandPath, String[] args, Listener listener, SubProgressMonitor monitor, ICallback callback) throws CoreException { if (remoteCommandPath != null && !remoteCommandPath.trim().equals("")) { //$NON-NLS-1$ - monitor.beginTask(NLS.bind(Messages.RemoteRunLaunchDelegate_8, remoteCommandPath, args), 10); + monitor.beginTask(NLS.bind(Messages.TEHelper_executing, remoteCommandPath, args), 10); // Construct the launcher object ProcessLauncher launcher = new ProcessLauncher(); @@ -260,7 +260,7 @@ public class TEHelper { public static String launchCmdReadOutput(final IPeer peer, String remoteCommandPath, String[] args, final SubProgressMonitor monitor, ICallback callback) throws CoreException { String output = null; if (remoteCommandPath != null && !remoteCommandPath.trim().equals("")) { //$NON-NLS-1$ - monitor.beginTask(NLS.bind(Messages.RemoteRunLaunchDelegate_8, remoteCommandPath, args), 10); + monitor.beginTask(NLS.bind(Messages.TEHelper_executing, remoteCommandPath, args), 10); // Construct the launcher object final ProcessStreamsProxy proxy = new ProcessStreamsProxy(); |