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:
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 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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue