1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 17:05:26 +02:00

Bug 374374: Cancelling the launch before the finalLaunchSequence is started is not done properly

This commit is contained in:
Marc Khouzam 2012-03-15 11:28:06 -04:00
parent 2167b279f5
commit dfaa8a0339

View file

@ -13,6 +13,7 @@
* Ericsson - Added support for post-mortem trace files
* Abeer Bagul (Tensilica) - Allow to better override GdbLaunch (bug 339550)
* Anton Gorenkov - Need to use a process factory (Bug 210366)
* Marc Khouzam (Ericsson) - Cleanup the launch if it is cancelled (Bug 374374)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.launching;
@ -68,6 +69,8 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate2
private final static String TRACING_FIRST_VERSION = "7.1.50"; //$NON-NLS-1$
private GdbLaunch fGdbLaunch;
public GdbLaunchDelegate() {
// We now fully support project-less debugging
// See bug 343861
@ -95,6 +98,7 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate2
private void launchDebugger( ILaunchConfiguration config, ILaunch launch, IProgressMonitor monitor ) throws CoreException {
monitor.beginTask(LaunchMessages.getString("GdbLaunchDelegate.0"), 10); //$NON-NLS-1$
if ( monitor.isCanceled() ) {
cleanupLaunch();
return;
}
@ -108,6 +112,7 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate2
private void launchDebugSession( final ILaunchConfiguration config, ILaunch l, IProgressMonitor monitor ) throws CoreException {
if ( monitor.isCanceled() ) {
cleanupLaunch();
return;
}
@ -146,10 +151,12 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate2
// First make sure non-stop is supported, if the user want to use this mode
if (LaunchUtils.getIsNonStopMode(config) && !isNonStopSupportedInGdbVersion(gdbVersion)) {
cleanupLaunch();
throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Non-stop mode is only supported starting with GDB " + NON_STOP_FIRST_VERSION, null)); //$NON-NLS-1$
}
if (LaunchUtils.getIsPostMortemTracing(config) && !isPostMortemTracingSupportedInGdbVersion(gdbVersion)) {
cleanupLaunch();
throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Post-mortem tracing is only supported starting with GDB " + TRACING_FIRST_VERSION, null)); //$NON-NLS-1$
}
@ -161,8 +168,10 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate2
new ServicesLaunchSequence(launch.getSession(), launch, subMon1);
launch.getSession().getExecutor().execute(servicesLaunchSequence);
boolean succeed = false;
try {
servicesLaunchSequence.get();
succeed = true;
} catch (InterruptedException e1) {
throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$
} catch (ExecutionException e1) {
@ -170,10 +179,16 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate2
} catch (CancellationException e1) {
// Launch aborted, so exit cleanly
return;
} finally {
if (!succeed) {
cleanupLaunch();
}
}
if (monitor.isCanceled())
return;
if (monitor.isCanceled()) {
cleanupLaunch();
return;
}
// The initializeControl method should be called after the ICommandControlService
// is initialized in the ServicesLaunchSequence above. This is because it is that
@ -210,7 +225,7 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate2
};
launch.getSession().getExecutor().execute(completeLaunchQuery);
boolean succeed = false;
succeed = false;
try {
completeLaunchQuery.get();
succeed = true;
@ -225,30 +240,39 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate2
if (!succeed) {
// finalLaunchSequence failed. Shutdown the session so that all started
// services including any GDB process are shutdown. (bug 251486)
//
Query<Object> launchShutdownQuery = new Query<Object>() {
@Override
protected void execute(DataRequestMonitor<Object> rm) {
launch.shutdownSession(rm);
}
};
launch.getSession().getExecutor().execute(launchShutdownQuery);
// wait for the shutdown to finish.
// The Query.get() method is a synchronous call which blocks until the
// query completes.
try {
launchShutdownQuery.get();
} catch (InterruptedException e) {
throw new DebugException( new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "InterruptedException while shutting down debugger launch " + launch, e)); //$NON-NLS-1$
} catch (ExecutionException e) {
throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in shutting down debugger launch " + launch, e)); //$NON-NLS-1$
}
cleanupLaunch();
}
}
}
/**
* This method takes care of cleaning up any resources allocated by the launch, as early as
* the call to getLaunch(), whenever the launch is cancelled or does not complete properly.
* @since 4.1 */
protected void cleanupLaunch() throws DebugException {
if (fGdbLaunch != null) {
Query<Object> launchShutdownQuery = new Query<Object>() {
@Override
protected void execute(DataRequestMonitor<Object> rm) {
fGdbLaunch.shutdownSession(rm);
}
};
fGdbLaunch.getSession().getExecutor().execute(launchShutdownQuery);
// wait for the shutdown to finish.
// The Query.get() method is a synchronous call which blocks until the
// query completes.
try {
launchShutdownQuery.get();
} catch (InterruptedException e) {
throw new DebugException( new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "InterruptedException while shutting down debugger launch " + fGdbLaunch, e)); //$NON-NLS-1$
} catch (ExecutionException e) {
throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in shutting down debugger launch " + fGdbLaunch, e)); //$NON-NLS-1$
}
}
}
/**
* Method used to check that the project, program and binary are correct.
* Can be overridden to avoid checking certain things.
@ -296,9 +320,25 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate2
return true;
}
return super.preLaunchCheck(config, mode, monitor);
boolean result = super.preLaunchCheck(config, mode, monitor);
if (!result) {
// The launch will not proceed! We must cleanup.
cleanupLaunch();
}
return result;
}
@Override
public boolean finalLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException {
boolean result = super.finalLaunchCheck(configuration, mode, monitor);
if (!result) {
// The launch will not proceed! We must cleanup.
cleanupLaunch();
}
return result;
}
/**
* Modify the ILaunchConfiguration to set the DebugPlugin.ATTR_PROCESS_FACTORY_ID attribute,
@ -318,6 +358,9 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate2
}
}
// This is the first method to be called in the launch sequence, even before preLaunchCheck()
// If we cancel the launch, we need to cleanup what is allocated in this method. The cleanup
// can be performed by GdbLaunch.shutdownSession()
@Override
public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException {
// Need to configure the source locator before creating the launch
@ -325,10 +368,10 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate2
// the adapters will be created for the whole session, including
// the source lookup adapter.
GdbLaunch launch = createGdbLaunch(configuration, mode, null);
launch.initialize();
launch.setSourceLocator(getSourceLocator(configuration, launch.getSession()));
return launch;
fGdbLaunch = createGdbLaunch(configuration, mode, null);
fGdbLaunch.initialize();
fGdbLaunch.setSourceLocator(getSourceLocator(configuration, fGdbLaunch.getSession()));
return fGdbLaunch;
}
/**