1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-31 21:05:37 +02:00

Bug 340021: GDB process not killed when canceling a launch

This commit is contained in:
Marc Khouzam 2011-03-18 18:25:37 +00:00
parent 11b9fcea4f
commit 4975d5a2c7

View file

@ -23,6 +23,7 @@ import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import org.eclipse.cdt.core.model.ICProject;
@ -514,7 +515,11 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
try {
fProcess = launchGDBProcess(commandLine);
fBackendState = State.STARTED;
// Need to do this on the executor for thread-safety
getExecutor().submit(
new DsfRunnable() {
public void run() { fBackendState = State.STARTED; }
});
// Don't send the backendStarted event yet. We wait until we have registered this service
// so that other services can have access to it.
} catch(CoreException e) {
@ -563,6 +568,13 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
@Override
protected void shutdown(final RequestMonitor requestMonitor) {
if (getState() != State.STARTED) {
// gdb not started yet or already killed, don't bother starting
// a job to kill it
requestMonitor.done();
return;
}
new Job("Terminating GDB process.") { //$NON-NLS-1$
{
setSystem(true);
@ -570,17 +582,29 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
@Override
protected IStatus run(IProgressMonitor monitor) {
if (GDBBackend.this.getState() == State.STARTED) {
// If we get here, our monitoring thread has been cleaned up already,
// but GDB is running. We have to terminate GDB and send
// the proper event.
assert fMonitorJob.fMonitorExited == true;
destroy();
fBackendState = State.TERMINATED;
getSession().dispatchEvent(
new BackendStateChangedEvent(getSession().getId(), getId(), State.TERMINATED),
getProperties());
}
try {
// Need to do this on the executor for thread-safety
// And we should wait for it to complete since we then
// check if the killing of GDB worked.
getExecutor().submit(
new DsfRunnable() {
public void run() {
destroy();
if (fMonitorJob.fMonitorExited) {
// Now that we have destroyed the process,
// and that the monitoring thread was killed,
// we need to set our state and send the event
fBackendState = State.TERMINATED;
getSession().dispatchEvent(
new BackendStateChangedEvent(getSession().getId(), getId(), State.TERMINATED),
getProperties());
}
}
}).get();
} catch (InterruptedException e1) {
} catch (ExecutionException e1) {
}
int attempts = 0;
while (attempts < 10) {
@ -599,7 +623,7 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
attempts++;
}
requestMonitor.setStatus(new Status(
IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "Process terminate failed", null)); //$NON-NLS-1$
IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "GDB terminate failed", null)); //$NON-NLS-1$
requestMonitor.done();
return Status.OK_STATUS;
}
@ -683,10 +707,16 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
fMonProcess.waitFor();
fGDBExitValue = fMonProcess.exitValue();
fBackendState = State.TERMINATED;
getSession().dispatchEvent(
new BackendStateChangedEvent(getSession().getId(), getId(), State.TERMINATED),
getProperties());
// Need to do this on the executor for thread-safety
getExecutor().submit(
new DsfRunnable() {
public void run() {
fBackendState = State.TERMINATED;
getSession().dispatchEvent(
new BackendStateChangedEvent(getSession().getId(), getId(), State.TERMINATED),
getProperties());
}
});
} catch (InterruptedException ie) {
// clear interrupted state
Thread.interrupted();