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:
parent
6facbd8e21
commit
3b373bb5a5
1 changed files with 37 additions and 26 deletions
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue