1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-22 22:22:11 +02:00

Bug 340021: GDB process not killed when canceling a launch

This commit is contained in:
Marc Khouzam 2011-03-15 20:17:36 +00:00
parent 6facbd8e21
commit 3b373bb5a5

View file

@ -88,6 +88,7 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
private Properties fEnvVariables;
private SessionType fSessionType;
private Boolean fAttach;
private State fBackendState = State.NOT_INITIALIZED;
/**
* Unique ID of this service instance.
@ -446,13 +447,7 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
}
public State getState() {
if (fMonitorJob == null) {
return State.NOT_INITIALIZED;
} else if (fMonitorJob.fExited) {
return State.TERMINATED;
} else {
return State.STARTED;
}
return fBackendState;
}
public int getExitCode() {
@ -519,6 +514,9 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
try {
fProcess = launchGDBProcess(commandLine);
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) {
gdbLaunchRequestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, e.getMessage(), e));
gdbLaunchRequestMonitor.done();
@ -572,7 +570,17 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
@Override
protected IStatus run(IProgressMonitor monitor) {
destroy();
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());
}
int attempts = 0;
while (attempts < 10) {
@ -616,8 +624,8 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
@Override
protected void shutdown(RequestMonitor requestMonitor) {
if (!fMonitorJob.fExited) {
fMonitorJob.kill();
if (fMonitorJob != null) {
fMonitorJob.kill();
}
requestMonitor.done();
}
@ -639,9 +647,12 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
* the GDBControlInitializedDMEvent that's used to indicate that GDB
* back end is ready for MI commands. But we still fire the event as
* it does no harm and may be needed sometime.... 09/29/2008
*
* We send the event in the register step because that is when
* other services have access to it.
*/
getSession().dispatchEvent(
new BackendStateChangedEvent(getSession().getId(), getId(), IMIBackend.State.STARTED),
new BackendStateChangedEvent(getSession().getId(), getId(), State.STARTED),
getProperties());
requestMonitor.done();
@ -660,7 +671,7 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
* then notifies the associated runtime process.
*/
private class MonitorJob extends Job {
boolean fExited = false;
boolean fMonitorExited = false;
DsfRunnable fMonitorStarted;
Process fMonProcess;
@ -668,20 +679,20 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
protected IStatus run(IProgressMonitor monitor) {
synchronized(fMonProcess) {
getExecutor().submit(fMonitorStarted);
while (!fExited) {
try {
fMonProcess.waitFor();
fGDBExitValue = fMonProcess.exitValue();
} catch (InterruptedException ie) {
// clear interrupted state
Thread.interrupted();
} finally {
fExited = true;
getSession().dispatchEvent(
new BackendStateChangedEvent(getSession().getId(), getId(), IMIBackend.State.TERMINATED),
getProperties());
}
try {
fMonProcess.waitFor();
fGDBExitValue = fMonProcess.exitValue();
fBackendState = State.TERMINATED;
getSession().dispatchEvent(
new BackendStateChangedEvent(getSession().getId(), getId(), State.TERMINATED),
getProperties());
} catch (InterruptedException ie) {
// clear interrupted state
Thread.interrupted();
}
fMonitorExited = true;
}
return Status.OK_STATUS;
}
@ -695,7 +706,7 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
void kill() {
synchronized(fMonProcess) {
if (!fExited) {
if (!fMonitorExited) {
getThread().interrupt();
}
}