1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-01 21:35:40 +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.Hashtable;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ICProject;
@ -514,7 +515,11 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
try { try {
fProcess = launchGDBProcess(commandLine); 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 // Don't send the backendStarted event yet. We wait until we have registered this service
// so that other services can have access to it. // so that other services can have access to it.
} catch(CoreException e) { } catch(CoreException e) {
@ -563,6 +568,13 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
@Override @Override
protected void shutdown(final RequestMonitor requestMonitor) { 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$ new Job("Terminating GDB process.") { //$NON-NLS-1$
{ {
setSystem(true); setSystem(true);
@ -570,17 +582,29 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
@Override @Override
protected IStatus run(IProgressMonitor monitor) { protected IStatus run(IProgressMonitor monitor) {
if (GDBBackend.this.getState() == State.STARTED) { try {
// If we get here, our monitoring thread has been cleaned up already, // Need to do this on the executor for thread-safety
// but GDB is running. We have to terminate GDB and send // And we should wait for it to complete since we then
// the proper event. // check if the killing of GDB worked.
assert fMonitorJob.fMonitorExited == true; getExecutor().submit(
destroy(); new DsfRunnable() {
fBackendState = State.TERMINATED; public void run() {
getSession().dispatchEvent( destroy();
new BackendStateChangedEvent(getSession().getId(), getId(), State.TERMINATED),
getProperties()); 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; int attempts = 0;
while (attempts < 10) { while (attempts < 10) {
@ -599,7 +623,7 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
attempts++; attempts++;
} }
requestMonitor.setStatus(new Status( 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(); requestMonitor.done();
return Status.OK_STATUS; return Status.OK_STATUS;
} }
@ -683,10 +707,16 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
fMonProcess.waitFor(); fMonProcess.waitFor();
fGDBExitValue = fMonProcess.exitValue(); fGDBExitValue = fMonProcess.exitValue();
fBackendState = State.TERMINATED; // Need to do this on the executor for thread-safety
getSession().dispatchEvent( getExecutor().submit(
new BackendStateChangedEvent(getSession().getId(), getId(), State.TERMINATED), new DsfRunnable() {
getProperties()); public void run() {
fBackendState = State.TERMINATED;
getSession().dispatchEvent(
new BackendStateChangedEvent(getSession().getId(), getId(), State.TERMINATED),
getProperties());
}
});
} catch (InterruptedException ie) { } catch (InterruptedException ie) {
// clear interrupted state // clear interrupted state
Thread.interrupted(); Thread.interrupted();