mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-01 06:05:24 +02:00
Bug 424996 - Improved error reporting when determining GDB version
Change-Id: I8aca4b262e6545a9196ccb63dd180eb635eb9181 Signed-off-by: Marc Khouzam <marc.khouzam@ericsson.com> Reviewed-on: https://git.eclipse.org/r/20326 Tested-by: Hudson CI Reviewed-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com> IP-Clean: Marc-Andre Laperle <marc-andre.laperle@ericsson.com> Tested-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
This commit is contained in:
parent
1de1915f89
commit
a2e42758f2
1 changed files with 71 additions and 42 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2010, 2013 Ericsson and others.
|
* Copyright (c) 2010, 2014 Ericsson and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -10,6 +10,7 @@
|
||||||
* Ericsson - Added support for Mac OS
|
* Ericsson - Added support for Mac OS
|
||||||
* Sergey Prigogin (Google)
|
* Sergey Prigogin (Google)
|
||||||
* Marc Khouzam (Ericsson) - Add timer when fetching GDB version (Bug 376203)
|
* Marc Khouzam (Ericsson) - Add timer when fetching GDB version (Bug 376203)
|
||||||
|
* Marc Khouzam (Ericsson) - Better error reporting when obtaining GDB version (Bug 424996)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.dsf.gdb.launching;
|
package org.eclipse.cdt.dsf.gdb.launching;
|
||||||
|
|
||||||
|
@ -289,39 +290,82 @@ public class LaunchUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method actually launches 'gdb --vesion' to determine the version
|
* This method actually launches 'gdb --version' to determine the version
|
||||||
* of the GDB that is being used. This method should ideally be called
|
* of the GDB that is being used. This method should ideally be called
|
||||||
* only once and the resulting version string stored for future uses.
|
* only once per session and the resulting version string stored for future uses.
|
||||||
|
*
|
||||||
|
* A timeout is scheduled which will kill the process if it takes too long.
|
||||||
*/
|
*/
|
||||||
public static String getGDBVersion(final ILaunchConfiguration configuration) throws CoreException {
|
public static String getGDBVersion(final ILaunchConfiguration configuration) throws CoreException {
|
||||||
final Process process;
|
|
||||||
String cmd = getGDBPath(configuration).toOSString() + " --version"; //$NON-NLS-1$
|
String cmd = getGDBPath(configuration).toOSString() + " --version"; //$NON-NLS-1$
|
||||||
|
Process process = null;
|
||||||
|
Job timeoutJob = null;
|
||||||
try {
|
try {
|
||||||
process = ProcessFactory.getFactory().exec(cmd, getLaunchEnvironment(configuration));
|
process = ProcessFactory.getFactory().exec(cmd, getLaunchEnvironment(configuration));
|
||||||
} catch(IOException e) {
|
|
||||||
throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED,
|
|
||||||
"Error while launching command: " + cmd, e.getCause()));//$NON-NLS-1$
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start a timeout job to make sure we don't get stuck waiting for
|
// Start a timeout job to make sure we don't get stuck waiting for
|
||||||
// an answer from a gdb that is hanging
|
// an answer from a gdb that is hanging
|
||||||
// Bug 376203
|
// Bug 376203
|
||||||
Job timeoutJob = new Job("GDB version timeout job") { //$NON-NLS-1$
|
final Process finalProc = process;
|
||||||
{ setSystem(true); }
|
timeoutJob = new Job("GDB version timeout job") { //$NON-NLS-1$
|
||||||
@Override
|
{ setSystem(true); }
|
||||||
protected IStatus run(IProgressMonitor arg) {
|
@Override
|
||||||
// Took too long. Kill the gdb process and
|
protected IStatus run(IProgressMonitor arg) {
|
||||||
// let things clean up.
|
// Took too long. Kill the gdb process and
|
||||||
process.destroy();
|
// let things clean up.
|
||||||
return Status.OK_STATUS;
|
finalProc.destroy();
|
||||||
}
|
return Status.OK_STATUS;
|
||||||
};
|
}
|
||||||
timeoutJob.schedule(10000);
|
};
|
||||||
|
timeoutJob.schedule(10000);
|
||||||
InputStream stream = null;
|
|
||||||
|
String streamOutput = readStream(process.getInputStream());
|
||||||
|
|
||||||
|
String gdbVersion = 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: " + cmd, //$NON-NLS-1$
|
||||||
|
detailedException));
|
||||||
|
}
|
||||||
|
return gdbVersion;
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED,
|
||||||
|
"Error with command: " + cmd, e));//$NON-NLS-1$
|
||||||
|
} 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read from the specified stream and return what was read.
|
||||||
|
*
|
||||||
|
* @param stream The input stream to be used to read the data. This method will close the stream.
|
||||||
|
* @return The data read from the stream
|
||||||
|
* @throws IOException If an IOException happens when reading the stream
|
||||||
|
*/
|
||||||
|
private static String readStream(InputStream stream) throws IOException {
|
||||||
StringBuilder cmdOutput = new StringBuilder(200);
|
StringBuilder cmdOutput = new StringBuilder(200);
|
||||||
try {
|
try {
|
||||||
stream = process.getInputStream();
|
|
||||||
Reader r = new InputStreamReader(stream);
|
Reader r = new InputStreamReader(stream);
|
||||||
BufferedReader reader = new BufferedReader(r);
|
BufferedReader reader = new BufferedReader(r);
|
||||||
|
|
||||||
|
@ -330,33 +374,18 @@ public class LaunchUtils {
|
||||||
cmdOutput.append(line);
|
cmdOutput.append(line);
|
||||||
cmdOutput.append('\n');
|
cmdOutput.append('\n');
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
return cmdOutput.toString();
|
||||||
throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED,
|
|
||||||
"Error reading GDB STDOUT after sending: " + cmd, e.getCause()));//$NON-NLS-1$
|
|
||||||
} finally {
|
} finally {
|
||||||
// If we get here we are obviously not stuck so we can cancel the timeout job.
|
|
||||||
// Note that it may already have executed, but that is not a problem.
|
|
||||||
timeoutJob.cancel();
|
|
||||||
|
|
||||||
// Cleanup to avoid leaking pipes
|
// Cleanup to avoid leaking pipes
|
||||||
// Close the stream we used, and then destroy the process
|
|
||||||
// Bug 345164
|
// Bug 345164
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
try {
|
try {
|
||||||
stream.close();
|
stream.close();
|
||||||
} catch (IOException e) {}
|
} catch (IOException e) {}
|
||||||
}
|
}
|
||||||
process.destroy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String gdbVersion = getGDBVersionFromText(cmdOutput.toString());
|
|
||||||
if (gdbVersion == null || gdbVersion.isEmpty()) {
|
|
||||||
throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED,
|
|
||||||
"Could not determine GDB version after sending: " + cmd, null));//$NON-NLS-1$
|
|
||||||
}
|
|
||||||
return gdbVersion;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean getIsAttach(ILaunchConfiguration config) {
|
public static boolean getIsAttach(ILaunchConfiguration config) {
|
||||||
try {
|
try {
|
||||||
String debugMode = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN );
|
String debugMode = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN );
|
||||||
|
|
Loading…
Add table
Reference in a new issue