());
+
+ getSession().addServiceEventListener(GdbBackend.this, null);
+
+ /*
+ * This event is not consumed by any one at present, instead it's
+ * 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(), State.STARTED),
+ getProperties());
+
+ requestMonitor.done();
+ }
+
+ @Override
+ protected void shutdown(RequestMonitor requestMonitor) {
+ unregister();
+ getSession().removeServiceEventListener(GdbBackend.this);
+ requestMonitor.done();
+ }
+ }
+
+ /**
+ * Monitors a system process, waiting for it to terminate, and then notifies
+ * the associated runtime process.
+ */
+ private class MonitorJob extends Job {
+ boolean fMonitorExited = false;
+ DsfRunnable fMonitorStarted;
+ Process fMonProcess;
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ synchronized (fMonProcess) {
+ getExecutor().submit(fMonitorStarted);
+ try {
+ fMonProcess.waitFor();
+ fGDBExitValue = fMonProcess.exitValue();
+
+ if (Activator.getInstance().isDebugging()) {
+ System.out.println("MonitorJob.run() exitValue() " + fGDBExitValue);
+ }
+
+ if(fProcess.isAlive() && Activator.getInstance().isDebugging())
+ {
+ // Need to do this on the executor for thread-safety
+ getExecutor().submit(new DsfRunnable() {
+ @Override
+ public void run() {
+
+ if (Activator.getInstance().isDebugging()) {
+ System.out.println("MonitorJob.run() run() ");
+ }
+
+ destroy();
+ fBackendState = State.TERMINATED;
+
+ if (Activator.getInstance().isDebugging()) {
+ System.out.println(
+ "MonitorJob.run() run() dispatchEvent(BackendStateChangedEvent, 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;
}
+ MonitorJob(Process process, DsfRunnable monitorStarted) {
+ super("GDB process monitor job."); //$NON-NLS-1$
+ fMonProcess = process;
+ fMonitorStarted = monitorStarted;
+ setSystem(true);
+ }
+
+ void kill() {
+ synchronized (fMonProcess) {
+ if (!fMonitorExited) {
+ getThread().interrupt();
+ }
+ }
+ }
+ }
+
+ /**
+ * Stores the request monitor that must be dealt with for the result of the
+ * interrupt operation. If the interrupt successfully suspends the backend,
+ * the request monitor can be retrieved and completed successfully, and then
+ * this job should be canceled. If this job is not canceled before the time
+ * is up, it will imply the interrupt did not successfully suspend the
+ * backend, and the current job will indicate this in the request monitor.
+ *
+ * The specified timeout is used to indicate how many milliseconds this job
+ * should wait for. INTERRUPT_TIMEOUT_DEFAULT indicates to use the default
+ * of 5 seconds. The default is also use if the timeout value is 0 or
+ * negative.
+ *
+ * @since 3.0
+ */
+ protected class MonitorInterruptJob extends Job {
+ // Bug 310274. Until we have a preference to configure timeouts,
+ // we need a large enough default timeout to accommodate slow
+ // remote sessions.
+ private final static int TIMEOUT_DEFAULT_VALUE = 5000;
+ private final RequestMonitor fRequestMonitor;
+
+ public MonitorInterruptJob(int timeout, RequestMonitor rm) {
+ super("Interrupt monitor job."); //$NON-NLS-1$
+ setSystem(true);
+ fRequestMonitor = rm;
+
+ if (timeout == INTERRUPT_TIMEOUT_DEFAULT || timeout <= 0) {
+ timeout = TIMEOUT_DEFAULT_VALUE; // default of 5 seconds
+ }
+
+ schedule(timeout);
+ }
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ getExecutor().submit(new DsfRunnable() {
+ @Override
+ public void run() {
+ fInterruptFailedJob = null;
+ fRequestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID,
+ IDsfStatusConstants.REQUEST_FAILED, "Interrupt failed.", null)); //$NON-NLS-1$
+ fRequestMonitor.done();
+ }
+ });
+ return Status.OK_STATUS;
+ }
+
+ public RequestMonitor getRequestMonitor() {
+ return fRequestMonitor;
+ }
+ }
+
+ /**
+ * We use this handler to determine if the SIGINT we sent to GDB has been
+ * effective. We must listen for an MI event and not a higher-level
+ * ISuspendedEvent. The reason is that some ISuspendedEvent are not sent
+ * when the target stops, in cases where we don't want to views to update.
+ * For example, if we want to interrupt the target to set a breakpoint, this
+ * interruption is done silently; we will receive the MI event though.
+ *
+ *
+ * Though we send a SIGINT, we may not specifically get an MISignalEvent.
+ * Typically we will, but not always, so wait for an MIStoppedEvent. See
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=305178#c21
+ *
+ * @since 3.0
+ *
+ */
+ @DsfServiceEventHandler
+ public void eventDispatched(final MIStoppedEvent e) {
+ if (fInterruptFailedJob != null) {
+ if (fInterruptFailedJob.cancel()) {
+ fInterruptFailedJob.getRequestMonitor().done();
+ }
+ fInterruptFailedJob = null;
+ }
+ }
+
+ /**
+ * Safety net, in case the GDB client does not exit on command.
+ *
+ * The event is created and triggered by Process.terminate().
+ *
+ * @param e
+ */
+ @DsfServiceEventHandler
+ public void eventDispatched(final ProcessStateChangedEvent e) {
+
if (Activator.getInstance().isDebugging()) {
- System.out.println("openocd.GdbBackend.getGDBWorkingDirectory() " + path);
+ System.out.println("GnuMcuGdbBackend.eventDispatched() " + e);
+ }
+
+ // When the process is terminated, also terminate the backend.
+ if (e.getState() == State.TERMINATED && e.getSessionId().equals(getSession().getId())
+ && getState() == State.STARTED) {
+
+ destroy();
}
- return path;
}
// ------------------------------------------------------------------------
diff --git a/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/Launch.java b/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/Launch.java
index 738c444e7..0e10d97c4 100644
--- a/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/Launch.java
+++ b/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/Launch.java
@@ -32,15 +32,16 @@
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.ISourceLocator;
-import org.eclipse.debug.internal.core.LaunchConfigurationWorkingCopy;
import org.eclipse.embedcdt.debug.gdbjtag.core.dsf.GnuMcuLaunch;
+import org.eclipse.swt.widgets.Display;
-import com.espressif.idf.core.util.PortChecker;
import com.espressif.idf.debug.gdbjtag.openocd.Activator;
import com.espressif.idf.debug.gdbjtag.openocd.Configuration;
import com.espressif.idf.debug.gdbjtag.openocd.ConfigurationAttributes;
@@ -57,6 +58,8 @@ public class Launch extends GnuMcuLaunch
private DsfSession fSession;
private DsfServicesTracker fTracker;
private DefaultDsfExecutor fExecutor;
+ private IProcess openOcdServerProcess;
+ private IProcess gdbIProcess;
// ------------------------------------------------------------------------
@@ -165,14 +168,13 @@ public void initializeServerConsole(IProgressMonitor monitor) throws CoreExcepti
System.out.println("openocd.Launch.initializeServerConsole()");
}
- IProcess newProcess;
boolean doAddServerConsole = Configuration.getDoAddServerConsole(fConfig);
if (doAddServerConsole)
{
// Add the GDB server process to the launch tree
- newProcess = addServerProcess(Configuration.getGdbServerCommandName(fConfig));
+ openOcdServerProcess = addServerProcess(Configuration.getGdbServerCommandName(fConfig));
monitor.worked(1);
}
}
@@ -185,11 +187,10 @@ public void initializeConsoles(IProgressMonitor monitor) throws CoreException
System.out.println("openocd.Launch.initializeConsoles()");
}
- IProcess newProcess;
{
// Add the GDB client process to the launch tree.
- newProcess = addClientProcess(Configuration.getGdbClientCommandName(fConfig));
- newProcess.setAttribute(IProcess.ATTR_CMDLINE, Configuration.getGdbClientCommandLine(fConfig));
+ gdbIProcess = addClientProcess(Configuration.getGdbClientCommandName(fConfig));
+ gdbIProcess.setAttribute(IProcess.ATTR_CMDLINE, Configuration.getGdbClientCommandLine(fConfig));
monitor.worked(1);
}
@@ -244,4 +245,31 @@ public Process call() throws CoreException
}
// ------------------------------------------------------------------------
+
+ @Override
+ public void terminate() throws DebugException
+ {
+ super.terminate();
+ for(IProcess process : getProcesses())
+ {
+ if (process != null)
+ {
+ try
+ {
+ process.terminate();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+
+ }
+ }
+ }
+
+ @Override
+ public IProcess[] getProcesses()
+ {
+ return new IProcess[] { openOcdServerProcess, gdbIProcess };
+ }
}
diff --git a/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/LaunchConfigurationDelegate.java b/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/LaunchConfigurationDelegate.java
index b7712aa21..5f59eea21 100644
--- a/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/LaunchConfigurationDelegate.java
+++ b/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/LaunchConfigurationDelegate.java
@@ -699,19 +699,6 @@ protected void handleCompleted()
// --------------------------------------------------------------------
}
- @Override
- /**
- * This method takes care of cleaning up any resources allocated by the launch, as early as
- * the call to getLaunch(), whenever the launch is cancelled or does not complete properly.
- * @since 5.0 */
- protected void cleanupLaunch(ILaunch launch) throws DebugException
- {
- if (launch instanceof GdbLaunch)
- {
- launch.terminate();
- }
- }
-
/**
* Perform some local validations before starting the debug session.
*/
diff --git a/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/process/IdfRuntimeProcess.java b/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/process/IdfRuntimeProcess.java
index b43da1ea8..8c67d92bb 100644
--- a/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/process/IdfRuntimeProcess.java
+++ b/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/process/IdfRuntimeProcess.java
@@ -16,6 +16,7 @@
import org.eclipse.debug.core.model.RuntimeProcess;
import org.eclipse.debug.internal.core.NullStreamsProxy;
+import com.espressif.idf.core.util.StringUtil;
import com.espressif.idf.debug.gdbjtag.openocd.dsf.process.monitors.StreamsProxy;
/**
@@ -38,6 +39,10 @@ public IdfRuntimeProcess(ILaunch launch, Process process, String name, Map
Date: Mon, 18 Nov 2024 16:54:45 +0100
Subject: [PATCH 13/16] fix(disclamers): updated required docs for the classes
---
.../debug/gdbjtag/openocd/dsf/GdbBackend.java | 38 ++++++++++++++++---
1 file changed, 32 insertions(+), 6 deletions(-)
diff --git a/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/GdbBackend.java b/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/GdbBackend.java
index b16ba5072..c45374269 100644
--- a/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/GdbBackend.java
+++ b/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/GdbBackend.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 Liviu Ionescu.
+ * Copyright (c) 2006, 2012 Wind River Systems, Nokia and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -7,11 +7,29 @@
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
- *
+ *
* Contributors:
- * Liviu Ionescu - initial version
+ * Nokia - initial API and implementation with some code moved from GDBControl.
+ * Wind River System
+ * Ericsson
+ * Marc Khouzam (Ericsson) - Use the new IMIBackend2 interface (Bug 350837)
+ * Mark Bozeman (Mentor Graphics) - Report GDB start failures (Bug 376203)
+ * Iulia Vasii (Freescale Semiconductor) - Separate GDB command from its arguments (Bug 445360)
*******************************************************************************/
+/* ----------------------------------------------------------------------------
+ *
+ * Copied here because we need the new version, but still remain compatible
+ * with Kepler. When dependency to Kepler will be removed, this file will
+ * no longer be necessary.
+ *
+ * It is identical to the newer GDBBackend, with the following changes:
+ * - package org.eclipse.embedcdt.debug.gdbjtag.jlink.dsf;
+ * - some imports
+ * - @SuppressWarnings("restriction")
+ *
+ * ------------------------------------------------------------------------- */
+
package com.espressif.idf.debug.gdbjtag.openocd.dsf;
import java.io.BufferedReader;
@@ -72,17 +90,25 @@
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.embedcdt.debug.gdbjtag.core.DebugUtils;
+import org.eclipse.embedcdt.debug.gdbjtag.core.dsf.GnuMcuGdbBackend;
import org.eclipse.embedcdt.debug.gdbjtag.core.dsf.GnuMcuProcesses_7_2_1.ProcessStateChangedEvent;
import org.osgi.framework.BundleContext;
import com.espressif.idf.debug.gdbjtag.openocd.Activator;
import com.espressif.idf.debug.gdbjtag.openocd.Configuration;
+
/**
- * The Kepler CDT GDBBackend does not allow such a simple customisation, we had
- * to copy a newer version locally and use it.
+ * Implementation of {@link IGDBBackend} for the common case where GDB is
+ * launched in local file system on host PC where Eclipse runs. This also
+ * manages some GDB parameters from a given launch configuration.
+ *
+ * You can subclass for you special needs.
+ *
+ * @since 1.1
+ *
+ * This class is taken from {@link GnuMcuGdbBackend}
*/
-
public class GdbBackend extends AbstractDsfService implements IGDBBackend, IMIBackend2 {
private final ILaunchConfiguration fLaunchConfiguration;
From f1d737c7843c42184696f0a2ec7af5b424a69b44 Mon Sep 17 00:00:00 2001
From: Ali Azam Rana <85216275+alirana01@users.noreply.github.com>
Date: Tue, 19 Nov 2024 14:16:27 +0100
Subject: [PATCH 14/16] fix(npe): updated code to handle npe for the
getProcesses function
---
.../idf/debug/gdbjtag/openocd/dsf/Launch.java | 11 ++++++++++-
.../openocd/dsf/process/IdfRuntimeProcess.java | 4 ----
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/Launch.java b/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/Launch.java
index 0e10d97c4..afd947137 100644
--- a/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/Launch.java
+++ b/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/Launch.java
@@ -14,7 +14,9 @@
package com.espressif.idf.debug.gdbjtag.openocd.dsf;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
@@ -270,6 +272,13 @@ public void terminate() throws DebugException
@Override
public IProcess[] getProcesses()
{
- return new IProcess[] { openOcdServerProcess, gdbIProcess };
+ List processes = new ArrayList<>();
+ if (openOcdServerProcess != null) {
+ processes.add(openOcdServerProcess);
+ }
+ if (gdbIProcess != null) {
+ processes.add(gdbIProcess);
+ }
+ return processes.toArray(new IProcess[0]);
}
}
diff --git a/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/process/IdfRuntimeProcess.java b/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/process/IdfRuntimeProcess.java
index 8c67d92bb..b25a451a5 100644
--- a/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/process/IdfRuntimeProcess.java
+++ b/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/process/IdfRuntimeProcess.java
@@ -39,10 +39,6 @@ public IdfRuntimeProcess(ILaunch launch, Process process, String name, Map
Date: Wed, 20 Nov 2024 17:16:13 +0100
Subject: [PATCH 15/16] fix(proc_dictionary): Add helper class to hold
processes by launches
Refactored the dictionary handling in the process manager to organize
processes based on their respective launches. This improves code
readability and reduces bugs when managing multiple launches.
---
.../idf/debug/gdbjtag/openocd/dsf/Launch.java | 33 ++++++++++--
.../openocd/dsf/LaunchProcessDictionary.java | 52 +++++++++++++++++++
2 files changed, 82 insertions(+), 3 deletions(-)
create mode 100644 bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/LaunchProcessDictionary.java
diff --git a/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/Launch.java b/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/Launch.java
index afd947137..a774af32d 100644
--- a/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/Launch.java
+++ b/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/Launch.java
@@ -34,7 +34,6 @@
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
@@ -42,7 +41,6 @@
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.embedcdt.debug.gdbjtag.core.dsf.GnuMcuLaunch;
-import org.eclipse.swt.widgets.Display;
import com.espressif.idf.debug.gdbjtag.openocd.Activator;
import com.espressif.idf.debug.gdbjtag.openocd.Configuration;
@@ -62,6 +60,9 @@ public class Launch extends GnuMcuLaunch
private DefaultDsfExecutor fExecutor;
private IProcess openOcdServerProcess;
private IProcess gdbIProcess;
+
+ private static final String SERVER_PROC_KEY = "SERVER_PROC";
+ private static final String GDB_PROC_KEY = "GDB_PROC";
// ------------------------------------------------------------------------
@@ -105,6 +106,15 @@ public void run()
// fireChanged();
}
};
+
+ try
+ {
+ cleanUpOldLaunchProcesses();
+ }
+ catch (CoreException e)
+ {
+ e.printStackTrace();
+ }
// Invoke the execution code and block waiting for the result.
try
@@ -121,6 +131,7 @@ public void run()
new Status(IStatus.ERROR, Activator.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR,
"Error initializing launch", e); //$NON-NLS-1$
}
+
}
@Override
@@ -177,6 +188,7 @@ public void initializeServerConsole(IProgressMonitor monitor) throws CoreExcepti
// Add the GDB server process to the launch tree
openOcdServerProcess = addServerProcess(Configuration.getGdbServerCommandName(fConfig));
+ LaunchProcessDictionary.getInstance().addProcessToDictionary(getLaunchConfiguration().getName(), SERVER_PROC_KEY, openOcdServerProcess);
monitor.worked(1);
}
}
@@ -193,7 +205,7 @@ public void initializeConsoles(IProgressMonitor monitor) throws CoreException
// Add the GDB client process to the launch tree.
gdbIProcess = addClientProcess(Configuration.getGdbClientCommandName(fConfig));
gdbIProcess.setAttribute(IProcess.ATTR_CMDLINE, Configuration.getGdbClientCommandLine(fConfig));
-
+ LaunchProcessDictionary.getInstance().addProcessToDictionary(getLaunchConfiguration().getName(), GDB_PROC_KEY, gdbIProcess);
monitor.worked(1);
}
}
@@ -281,4 +293,19 @@ public IProcess[] getProcesses()
}
return processes.toArray(new IProcess[0]);
}
+
+ private void cleanUpOldLaunchProcesses() throws CoreException
+ {
+ IProcess serverIProcess = LaunchProcessDictionary.getInstance().getProcessFromDictionary(getLaunchConfiguration().getName(), SERVER_PROC_KEY);
+ if (serverIProcess != null && !serverIProcess.isTerminated())
+ {
+ serverIProcess.terminate();
+ }
+
+ IProcess gdbIProcess = LaunchProcessDictionary.getInstance().getProcessFromDictionary(getLaunchConfiguration().getName(), GDB_PROC_KEY);
+ if(gdbIProcess != null && !gdbIProcess.isTerminated())
+ {
+ gdbIProcess.terminate();
+ }
+ }
}
diff --git a/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/LaunchProcessDictionary.java b/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/LaunchProcessDictionary.java
new file mode 100644
index 000000000..52c7eb3cb
--- /dev/null
+++ b/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/LaunchProcessDictionary.java
@@ -0,0 +1,52 @@
+package com.espressif.idf.debug.gdbjtag.openocd.dsf;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.debug.core.model.IProcess;
+
+public class LaunchProcessDictionary
+{
+ private static LaunchProcessDictionary instance;
+
+ private Map> processDictionary;
+
+ private LaunchProcessDictionary()
+ {
+ processDictionary = new HashMap<>();
+ }
+
+ public static LaunchProcessDictionary getInstance()
+ {
+ if(instance == null)
+ instance = new LaunchProcessDictionary();
+
+ return instance;
+ }
+
+ public void addProcessToDictionary(String launchName, String procName, IProcess process)
+ {
+ if (!processDictionary.containsKey(launchName))
+ {
+ Map processMap = new HashMap<>();
+ processMap.put(procName, process);
+ processDictionary.put(launchName, processMap);
+ return;
+ }
+
+ Map processMap = processDictionary.get(launchName);
+ processMap.put(procName, process);
+ processDictionary.put(launchName, processMap);
+ }
+
+ public IProcess getProcessFromDictionary(String launchName, String procName)
+ {
+ if (!processDictionary.containsKey(launchName))
+ {
+ return null;
+ }
+
+ return processDictionary.get(launchName).get(procName);
+ }
+
+}
From 9fde5658f32adc0b6c835ea3675d4e66b41fc693 Mon Sep 17 00:00:00 2001
From: Ali Azam Rana <85216275+alirana01@users.noreply.github.com>
Date: Wed, 20 Nov 2024 17:30:45 +0100
Subject: [PATCH 16/16] fix(process): Debug Launch to return true for
disconnect and terminate
---
.../idf/debug/gdbjtag/openocd/dsf/Launch.java | 30 +++++++++----------
.../openocd/dsf/LaunchProcessDictionary.java | 21 +++++++++++++
2 files changed, 36 insertions(+), 15 deletions(-)
diff --git a/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/Launch.java b/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/Launch.java
index a774af32d..4b2583375 100644
--- a/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/Launch.java
+++ b/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/Launch.java
@@ -264,23 +264,23 @@ public Process call() throws CoreException
public void terminate() throws DebugException
{
super.terminate();
- for(IProcess process : getProcesses())
- {
- if (process != null)
- {
- try
- {
- process.terminate();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
-
- }
- }
+
+ LaunchProcessDictionary.getInstance().killAllProcessesInLaunch(getLaunchConfiguration().getName());
}
+ @Override
+ public boolean canDisconnect()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean canTerminate()
+ {
+ return true;
+ }
+
+
@Override
public IProcess[] getProcesses()
{
diff --git a/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/LaunchProcessDictionary.java b/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/LaunchProcessDictionary.java
index 52c7eb3cb..3199d8989 100644
--- a/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/LaunchProcessDictionary.java
+++ b/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/dsf/LaunchProcessDictionary.java
@@ -3,6 +3,7 @@
import java.util.HashMap;
import java.util.Map;
+import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IProcess;
public class LaunchProcessDictionary
@@ -48,5 +49,25 @@ public IProcess getProcessFromDictionary(String launchName, String procName)
return processDictionary.get(launchName).get(procName);
}
+
+ public void killAllProcessesInLaunch(String launchName)
+ {
+ if(!processDictionary.containsKey(launchName))
+ {
+ return;
+ }
+
+ for (IProcess process : processDictionary.get(launchName).values())
+ {
+ try
+ {
+ process.terminate();
+ }
+ catch (DebugException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
}