diff mbox series

[v2,5/8] devtool: ide-sdk: wait for debugger server shutdown

Message ID 20260809093629.3457107-6-adrian.freihofer@siemens.com
State New
Headers show
Series oe-selftest: devtool ide-sdk: fix lldb connect race in _lldb_server_debugging_once | expand

Commit Message

AdrianF Aug. 9, 2026, 9:35 a.m. UTC
From: Adrian Freihofer <adrian.freihofer@siemens.com>

Have the ide=none GDB and LLDB stop scripts wait for their recorded
server PID to exit before removing their state. This makes a successful
stop command a reliable target-side lifecycle boundary and reports a
timeout when the server cannot be stopped.

Signed-off-by: Adrian Freihofer <adrian.freihofer@siemens.com>
---
 scripts/lib/devtool/ide_plugins/__init__.py |  7 +++++++
 scripts/lib/devtool/ide_plugins/ide_none.py | 17 ++++++++++++-----
 2 files changed, 19 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/scripts/lib/devtool/ide_plugins/__init__.py b/scripts/lib/devtool/ide_plugins/__init__.py
index 6c88e0e34e..1c4288a8b5 100644
--- a/scripts/lib/devtool/ide_plugins/__init__.py
+++ b/scripts/lib/devtool/ide_plugins/__init__.py
@@ -117,6 +117,13 @@  class DebuggerCrossConfig:
             % (self._target_tcp_port_check_cmd(), cleanup, self.DEBUG_SERVER_NAME,
                self.debug_server_port))
 
+    def _target_wait_for_process_exit_cmd(self, pid_var):
+        return (
+            "_w=0; while kill -0 \\$_%s 2>/dev/null; do _w=\\$((_w+1)); "
+            "[ \\$_w -lt 100 ] || { echo %s did not stop >&2; exit 1; }; "
+            "sleep 0.1; done;"
+            % (pid_var, self.DEBUG_SERVER_NAME))
+
     def initialize(self):
         """Called after construction to generate any required config files."""
         pass
diff --git a/scripts/lib/devtool/ide_plugins/ide_none.py b/scripts/lib/devtool/ide_plugins/ide_none.py
index a8ddc3f39f..8e01c2fc41 100644
--- a/scripts/lib/devtool/ide_plugins/ide_none.py
+++ b/scripts/lib/devtool/ide_plugins/ide_none.py
@@ -24,9 +24,13 @@  class GdbCrossConfigNone(GdbCrossConfig):
         """Kill a gdbserver process"""
         # This is the usual behavior: gdbserver is stopped on demand
         if server_mode == DebuggerServerModes.MULTI:
-            gdbserver_cmd_stop = "test -f %s && kill \\$(cat %s);" % (
-                self._gdbserver_pid_file(server_mode), self._gdbserver_pid_file(server_mode))
-            gdbserver_cmd_stop += " rm -rf %s" % self._gdbserver_tmp_dir(server_mode)
+            pid_file = self._gdbserver_pid_file(server_mode)
+            gdbserver_cmd_stop = "if test -f %s; then _gdbserver_pid=\\$(cat %s); " % (
+                pid_file, pid_file)
+            gdbserver_cmd_stop += "kill \\$_gdbserver_pid 2>/dev/null; "
+            gdbserver_cmd_stop += self._target_wait_for_process_exit_cmd(
+                "gdbserver_pid")
+            gdbserver_cmd_stop += " fi; rm -rf %s" % self._gdbserver_tmp_dir(server_mode)
         # This is unexpected since gdbserver should terminate after each debug session
         # Just kill all gdbserver instances to keep it simple
         else:
@@ -169,8 +173,11 @@  class LldbServerConfigNone(LldbServerConfig):
         if server_mode == DebuggerServerModes.MULTI:
             pid_file = self._lldb_server_pid_file(server_mode)
             tmp_dir = self._lldb_server_tmp_dir(server_mode)
-            cmd = ("test -f %(pf)s && kill \\$(cat %(pf)s) 2>/dev/null; rm -rf %(td)s"
-                   % {'pf': pid_file, 'td': tmp_dir})
+            cmd = "if test -f %s; then _lldb_server_pid=\\$(cat %s); " % (
+                pid_file, pid_file)
+            cmd += "kill \\$_lldb_server_pid 2>/dev/null; "
+            cmd += self._target_wait_for_process_exit_cmd("lldb_server_pid")
+            cmd += " fi; rm -rf %s" % tmp_dir
         else:
             cmd = "killall lldb-server 2>/dev/null || true"
         return "\"/bin/sh -c '" + cmd + "'\""