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:
parent
11b9fcea4f
commit
4975d5a2c7
1 changed files with 47 additions and 17 deletions
|
@ -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();
|
||||||
|
|
Loading…
Add table
Reference in a new issue