mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-04 14:55:41 +02:00
Bug 374374: Cancelling the launch before the finalLaunchSequence is started is not done properly
This commit is contained in:
parent
2167b279f5
commit
dfaa8a0339
1 changed files with 71 additions and 28 deletions
|
@ -13,6 +13,7 @@
|
||||||
* Ericsson - Added support for post-mortem trace files
|
* Ericsson - Added support for post-mortem trace files
|
||||||
* Abeer Bagul (Tensilica) - Allow to better override GdbLaunch (bug 339550)
|
* Abeer Bagul (Tensilica) - Allow to better override GdbLaunch (bug 339550)
|
||||||
* Anton Gorenkov - Need to use a process factory (Bug 210366)
|
* 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;
|
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 final static String TRACING_FIRST_VERSION = "7.1.50"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
private GdbLaunch fGdbLaunch;
|
||||||
|
|
||||||
public GdbLaunchDelegate() {
|
public GdbLaunchDelegate() {
|
||||||
// We now fully support project-less debugging
|
// We now fully support project-less debugging
|
||||||
// See bug 343861
|
// See bug 343861
|
||||||
|
@ -95,6 +98,7 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate2
|
||||||
private void launchDebugger( ILaunchConfiguration config, ILaunch launch, IProgressMonitor monitor ) throws CoreException {
|
private void launchDebugger( ILaunchConfiguration config, ILaunch launch, IProgressMonitor monitor ) throws CoreException {
|
||||||
monitor.beginTask(LaunchMessages.getString("GdbLaunchDelegate.0"), 10); //$NON-NLS-1$
|
monitor.beginTask(LaunchMessages.getString("GdbLaunchDelegate.0"), 10); //$NON-NLS-1$
|
||||||
if ( monitor.isCanceled() ) {
|
if ( monitor.isCanceled() ) {
|
||||||
|
cleanupLaunch();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,6 +112,7 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate2
|
||||||
|
|
||||||
private void launchDebugSession( final ILaunchConfiguration config, ILaunch l, IProgressMonitor monitor ) throws CoreException {
|
private void launchDebugSession( final ILaunchConfiguration config, ILaunch l, IProgressMonitor monitor ) throws CoreException {
|
||||||
if ( monitor.isCanceled() ) {
|
if ( monitor.isCanceled() ) {
|
||||||
|
cleanupLaunch();
|
||||||
return;
|
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
|
// First make sure non-stop is supported, if the user want to use this mode
|
||||||
if (LaunchUtils.getIsNonStopMode(config) && !isNonStopSupportedInGdbVersion(gdbVersion)) {
|
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$
|
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)) {
|
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$
|
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);
|
new ServicesLaunchSequence(launch.getSession(), launch, subMon1);
|
||||||
|
|
||||||
launch.getSession().getExecutor().execute(servicesLaunchSequence);
|
launch.getSession().getExecutor().execute(servicesLaunchSequence);
|
||||||
|
boolean succeed = false;
|
||||||
try {
|
try {
|
||||||
servicesLaunchSequence.get();
|
servicesLaunchSequence.get();
|
||||||
|
succeed = true;
|
||||||
} catch (InterruptedException e1) {
|
} 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$
|
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) {
|
} catch (ExecutionException e1) {
|
||||||
|
@ -170,10 +179,16 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate2
|
||||||
} catch (CancellationException e1) {
|
} catch (CancellationException e1) {
|
||||||
// Launch aborted, so exit cleanly
|
// Launch aborted, so exit cleanly
|
||||||
return;
|
return;
|
||||||
|
} finally {
|
||||||
|
if (!succeed) {
|
||||||
|
cleanupLaunch();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (monitor.isCanceled())
|
if (monitor.isCanceled()) {
|
||||||
return;
|
cleanupLaunch();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// The initializeControl method should be called after the ICommandControlService
|
// The initializeControl method should be called after the ICommandControlService
|
||||||
// is initialized in the ServicesLaunchSequence above. This is because it is that
|
// 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);
|
launch.getSession().getExecutor().execute(completeLaunchQuery);
|
||||||
boolean succeed = false;
|
succeed = false;
|
||||||
try {
|
try {
|
||||||
completeLaunchQuery.get();
|
completeLaunchQuery.get();
|
||||||
succeed = true;
|
succeed = true;
|
||||||
|
@ -225,30 +240,39 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate2
|
||||||
if (!succeed) {
|
if (!succeed) {
|
||||||
// finalLaunchSequence failed. Shutdown the session so that all started
|
// finalLaunchSequence failed. Shutdown the session so that all started
|
||||||
// services including any GDB process are shutdown. (bug 251486)
|
// services including any GDB process are shutdown. (bug 251486)
|
||||||
//
|
cleanupLaunch();
|
||||||
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$
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
* Method used to check that the project, program and binary are correct.
|
||||||
* Can be overridden to avoid checking certain things.
|
* Can be overridden to avoid checking certain things.
|
||||||
|
@ -296,9 +320,25 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate2
|
||||||
return true;
|
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,
|
* 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
|
@Override
|
||||||
public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException {
|
public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException {
|
||||||
// Need to configure the source locator before creating the launch
|
// 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 adapters will be created for the whole session, including
|
||||||
// the source lookup adapter.
|
// the source lookup adapter.
|
||||||
|
|
||||||
GdbLaunch launch = createGdbLaunch(configuration, mode, null);
|
fGdbLaunch = createGdbLaunch(configuration, mode, null);
|
||||||
launch.initialize();
|
fGdbLaunch.initialize();
|
||||||
launch.setSourceLocator(getSourceLocator(configuration, launch.getSession()));
|
fGdbLaunch.setSourceLocator(getSourceLocator(configuration, fGdbLaunch.getSession()));
|
||||||
return launch;
|
return fGdbLaunch;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue