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