1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-21 21:52:10 +02:00

Bug 541520: Make GDB version detection standalone

Provides GDB version detection as a public API that can be used without
having a saved launch config, or having a launch config at all.

Change-Id: Ifaee337899c01fe7066b27f7d66484bfc728f5ed
Signed-off-by: Max Bureck <max.bureck@fokus.fraunhofer.de>
This commit is contained in:
Max Bureck 2018-11-26 00:20:16 +01:00 committed by Jonah Graham
parent f94490939f
commit 0da8033c2c
2 changed files with 32 additions and 74 deletions

View file

@ -41,7 +41,6 @@ import org.eclipse.cdt.core.cdtvariables.ICdtVariableManager;
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.parser.util.StringUtil;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
@ -72,8 +71,6 @@ import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.utils.CommandLineUtil;
import org.eclipse.cdt.utils.spawner.ProcessFactory;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
@ -81,13 +78,11 @@ import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
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.MultiStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
@ -514,75 +509,13 @@ public class GdbLaunch extends DsfLaunch implements ITerminate, IDisconnect, ITr
return fGdbVersion;
}
String cmd = getGDBPath().toOSString() + " --version"; //$NON-NLS-1$
String gdbPath = getGDBPath().toOSString();
String[] launchEnvironment = getLaunchEnvironment();
// Parse cmd to properly handle spaces and such things (bug 458499)
String[] args = CommandLineUtil.argumentsToArray(cmd);
Process process = null;
Job timeoutJob = null;
try {
process = ProcessFactory.getFactory().exec(args, getLaunchEnvironment());
// Start a timeout job to make sure we don't get stuck waiting for
// an answer from a gdb that is hanging
// Bug 376203
final Process finalProc = process;
timeoutJob = new Job("GDB version timeout job") { //$NON-NLS-1$
{
setSystem(true);
}
@Override
protected IStatus run(IProgressMonitor arg) {
// Took too long. Kill the gdb process and
// let things clean up.
finalProc.destroy();
return Status.OK_STATUS;
}
};
timeoutJob.schedule(10000);
String streamOutput = readStream(process.getInputStream());
String gdbVersion = LaunchUtils.getGDBVersionFromText(streamOutput);
if (gdbVersion == null || gdbVersion.isEmpty()) {
Exception detailedException = null;
if (!streamOutput.isEmpty()) {
// We got some output but couldn't parse it. Make that
// output visible to the user in the error dialog.
detailedException = new Exception("Unexpected output format: \n\n" + streamOutput); //$NON-NLS-1$
} else {
// We got no output. Check if we got something on the error
// stream.
streamOutput = readStream(process.getErrorStream());
if (!streamOutput.isEmpty()) {
detailedException = new Exception(streamOutput);
}
}
throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED,
"Could not determine GDB version using command: " + StringUtil.join(args, " "), //$NON-NLS-1$ //$NON-NLS-2$
detailedException));
}
String gdbVersion = LaunchUtils.getGDBVersion(gdbPath, launchEnvironment);
fGdbVersion = gdbVersion;
return fGdbVersion;
} catch (IOException e) {
throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED,
"Error with command: " + StringUtil.join(args, " "), e));//$NON-NLS-1$ //$NON-NLS-2$
} finally {
// If we get here we are obviously not stuck reading the stream so
// we can cancel the timeout job.
// Note that it may already have executed, but that is not a
// problem.
if (timeoutJob != null) {
timeoutJob.cancel();
}
if (process != null) {
process.destroy();
}
}
}
/**

View file

@ -28,6 +28,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -284,7 +285,31 @@ public class LaunchUtils {
*/
@Deprecated
public static String getGDBVersion(final ILaunchConfiguration configuration) throws CoreException {
String cmd = getGDBPath(configuration).toOSString() + " --version"; //$NON-NLS-1$
String gdbPath = getGDBPath(configuration).toOSString();
String[] launchEnvironment = getLaunchEnvironment(configuration);
return getGDBVersion(gdbPath, launchEnvironment);
}
/**
* This method actually launches 'gdb --version' to determine the version of
* the GDB that is being used.
*
* A timeout is scheduled which will kill the process if it takes too long.
*
* @param gdbPath the path to the GDB executable to be called
* @param launchEnvironment the environment variables set for the
* GDB process. Every element of the array must be of format "key=value".
* @return the detected version of GDB at {@code gdbPath}
* @throws CoreException is e.g. thrown if the execution of GDB fails
* @throws NullPointerException if {@code gdbPath} or {@code launchEnvironment} is {@code null}
* @since 5.6
*/
public static String getGDBVersion(String gdbPath, String[] launchEnvironment) throws CoreException {
Objects.requireNonNull(gdbPath, "gdbPath"); //$NON-NLS-1$
Objects.requireNonNull(launchEnvironment, "launchEnvironment"); //$NON-NLS-1$
String cmd = gdbPath + " --version"; //$NON-NLS-1$
// Parse cmd to properly handle spaces and such things (bug 458499)
String[] args = CommandLineUtil.argumentsToArray(cmd);
@ -292,7 +317,7 @@ public class LaunchUtils {
Process process = null;
Job timeoutJob = null;
try {
process = ProcessFactory.getFactory().exec(args, getLaunchEnvironment(configuration));
process = ProcessFactory.getFactory().exec(args, launchEnvironment);
// Start a timeout job to make sure we don't get stuck waiting for
// an answer from a gdb that is hanging