From 46a8a239c37a02e1468bdb5cf190f1c46bcaf99f Mon Sep 17 00:00:00 2001 From: Mickael Istria Date: Tue, 3 Oct 2023 16:12:14 +0200 Subject: [PATCH] Support termination of virtual DSPProcess The DSPProcess not always maps to an actual process, but when it does, we use it to control termination actions and state, and if it doesn't we failback to an internal state. This makes that the "Terminate" button on the Console works. --- .../eclipse/lsp4e/debug/console/DSPProcess.java | 10 ++++++++-- .../lsp4e/debug/debugmodel/DSPDebugTarget.java | 15 ++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/org.eclipse.lsp4e.debug/src/org/eclipse/lsp4e/debug/console/DSPProcess.java b/org.eclipse.lsp4e.debug/src/org/eclipse/lsp4e/debug/console/DSPProcess.java index ed59e6b71..49741ef6c 100644 --- a/org.eclipse.lsp4e.debug/src/org/eclipse/lsp4e/debug/console/DSPProcess.java +++ b/org.eclipse.lsp4e.debug/src/org/eclipse/lsp4e/debug/console/DSPProcess.java @@ -11,7 +11,9 @@ import java.util.Optional; import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.model.IProcess; import org.eclipse.lsp4e.debug.debugmodel.DSPDebugTarget; @@ -27,6 +29,7 @@ public class DSPProcess implements IProcess { private final DSPStreamsProxy proxy; private final ProcessEventArguments processArgs; private final Optional handle; + private boolean terminated; public DSPProcess(DSPDebugTarget target) { this(target, null); @@ -50,16 +53,19 @@ public T getAdapter(Class adapter) { @Override public boolean canTerminate() { - return target.canTerminate(); + return !isTerminated(); } @Override public boolean isTerminated() { - return target.isTerminated(); + return handle.map(h -> !h.isAlive()).orElse(terminated); } @Override public void terminate() throws DebugException { + terminated = true; + handle.ifPresent(ProcessHandle::destroyForcibly); + DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { new DebugEvent(this, DebugEvent.TERMINATE) }); target.terminate(); } diff --git a/org.eclipse.lsp4e.debug/src/org/eclipse/lsp4e/debug/debugmodel/DSPDebugTarget.java b/org.eclipse.lsp4e.debug/src/org/eclipse/lsp4e/debug/debugmodel/DSPDebugTarget.java index 42dd3d330..4e2a8863c 100644 --- a/org.eclipse.lsp4e.debug/src/org/eclipse/lsp4e/debug/debugmodel/DSPDebugTarget.java +++ b/org.eclipse.lsp4e.debug/src/org/eclipse/lsp4e/debug/debugmodel/DSPDebugTarget.java @@ -310,16 +310,17 @@ private void terminated() { try { t.terminate(); } catch (DebugException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + DSPPlugin.logError(e); } }); - fireTerminateEvent(); - if (process != null) { - // Disable the terminate button of the console associated with the DSPProcess. - DebugPlugin.getDefault() - .fireDebugEventSet(new DebugEvent[] { new DebugEvent(process, DebugEvent.TERMINATE) }); + if (process != null && process.canTerminate()) { + try { + process.terminate(); + } catch (DebugException e) { + DSPPlugin.logError(e); + } } + fireTerminateEvent(); if (breakpointManager != null) { breakpointManager.shutdown(); }