https://github.com/charles-zablit updated 
https://github.com/llvm/llvm-project/pull/172879

>From 85f80882a497ad071b33c4efbc638226edd9a6b3 Mon Sep 17 00:00:00 2001
From: Charles Zablit <[email protected]>
Date: Thu, 18 Dec 2025 16:59:34 +0000
Subject: [PATCH 1/3] [lldb-dap] refactor monitor thread in tests

---
 .../tools/lldb-dap/attach/TestDAP_attach.py   | 25 +++++++++++++------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py 
b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py
index d6287397a93b0..7d1b3750a04a2 100644
--- a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py
+++ b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py
@@ -16,7 +16,7 @@
 @skipIf(oslist=["linux"], archs=["arm$"])
 class TestDAP_attach(lldbdap_testcase.DAPTestCaseBase):
     def spawn(self, args):
-        self.process = subprocess.Popen(
+        self.target_process = subprocess.Popen(
             args,
             stdin=subprocess.PIPE,
             stdout=subprocess.PIPE,
@@ -27,12 +27,17 @@ def spawn(self, args):
     def spawn_and_wait(self, program, delay):
         time.sleep(delay)
         self.spawn([program])
-        self.process.wait()
+        proc = self.target_process
+        # Wait for either the process to exit or the event to be set
+        while proc.poll() is None and not self.spawn_event.is_set():
+            time.sleep(0.1)
+        proc.kill()
+        proc.wait()
 
     def continue_and_verify_pid(self):
         self.do_continue()
-        out, _ = self.process.communicate("foo")
-        self.assertIn(f"pid = {self.process.pid}", out)
+        out, _ = self.target_process.communicate("foo")
+        self.assertIn(f"pid = {self.target_process.pid}", out)
 
     def test_by_pid(self):
         """
@@ -40,7 +45,7 @@ def test_by_pid(self):
         """
         program = self.build_and_create_debug_adapter_for_attach()
         self.spawn([program])
-        self.attach(pid=self.process.pid)
+        self.attach(pid=self.target_process.pid)
         self.continue_and_verify_pid()
 
     def test_by_name(self):
@@ -65,6 +70,7 @@ def test_by_name_waitFor(self):
         doesn't exist yet.
         """
         program = self.build_and_create_debug_adapter_for_attach()
+        self.spawn_event = threading.Event()
         self.spawn_thread = threading.Thread(
             target=self.spawn_and_wait,
             args=(
@@ -73,8 +79,13 @@ def test_by_name_waitFor(self):
             ),
         )
         self.spawn_thread.start()
-        self.attach(program=program, waitFor=True)
-        self.continue_and_verify_pid()
+        try:
+            self.attach(program=program, waitFor=True)
+            self.continue_and_verify_pid()
+        finally:
+            self.spawn_event.set()
+            if self.spawn_thread.is_alive():
+                self.spawn_thread.join(timeout=10)
 
     def test_attach_with_missing_debuggerId_or_targetId(self):
         """

>From 912ec85e8d8002cbf2dcbc7f0fe79c276a2db5a3 Mon Sep 17 00:00:00 2001
From: Charles Zablit <[email protected]>
Date: Fri, 19 Dec 2025 11:35:31 +0000
Subject: [PATCH 2/3] address comments

---
 .../Python/lldbsuite/test/lldbtest.py         | 28 +++++++++++++++----
 .../tools/lldb-dap/attach/TestDAP_attach.py   | 24 ++++++++--------
 2 files changed, 36 insertions(+), 16 deletions(-)

diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py 
b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index 8c1eea97620e2..321320910db02 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -42,6 +42,7 @@
 import sys
 import time
 import traceback
+from typing import Optional, Union
 
 # Third-party modules
 import unittest
@@ -410,17 +411,22 @@ def __init__(self, trace_on):
     def pid(self):
         return self._proc.pid
 
-    def launch(self, executable, args, extra_env):
+    def launch(self, executable, args, extra_env, **kwargs):
         env = None
         if extra_env:
             env = dict(os.environ)
             env.update([kv.split("=", 1) for kv in extra_env])
 
+        stdout = kwargs.pop("stdout", DEVNULL if not self._trace_on else None)
+        stderr = kwargs.pop("stderr", None)
+
         self._proc = Popen(
             [executable] + args,
-            stdout=DEVNULL if not self._trace_on else None,
+            stdout=stdout,
+            stderr=stderr,
             stdin=PIPE,
             env=env,
+            **kwargs,
         )
 
     def terminate(self):
@@ -444,6 +450,11 @@ def terminate(self):
             self._proc.kill()
             time.sleep(self._delayafterterminate)
 
+    def communicate(
+        self, input: Optional[str] = None, timeout: Optional[float] = None
+    ) -> tuple[bytes, bytes]:
+        return self._proc.communicate(input, timeout)
+
     def poll(self):
         return self._proc.poll()
 
@@ -460,7 +471,7 @@ def __init__(self, install_remote):
     def pid(self):
         return self._pid
 
-    def launch(self, executable, args, extra_env):
+    def launch(self, executable, args, extra_env, **kwargs):
         if self._install_remote:
             src_path = executable
             dst_path = lldbutil.join_remote_paths(
@@ -943,16 +954,23 @@ def cleanupSubprocesses(self):
             del p
         del self.subprocesses[:]
 
-    def spawnSubprocess(self, executable, args=[], extra_env=None, 
install_remote=True):
+    @property
+    def lastSubprocess(self) -> Optional[Union[_RemoteProcess, _LocalProcess]]:
+        return self.subprocesses[-1] if len(self.subprocesses) > 0 else None
+
+    def spawnSubprocess(
+        self, executable, args=None, extra_env=None, install_remote=True, 
**kwargs
+    ):
         """Creates a subprocess.Popen object with the specified executable and 
arguments,
         saves it in self.subprocesses, and returns the object.
         """
+        args = [] if args is None else args
         proc = (
             _RemoteProcess(install_remote)
             if lldb.remote_platform
             else _LocalProcess(self.TraceOn())
         )
-        proc.launch(executable, args, extra_env=extra_env)
+        proc.launch(executable, args, extra_env=extra_env, **kwargs)
         self.subprocesses.append(proc)
         return proc
 
diff --git a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py 
b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py
index 7d1b3750a04a2..27718d91a89d5 100644
--- a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py
+++ b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py
@@ -15,10 +15,10 @@
 # process scheduling can cause a massive (minutes) delay during this test.
 @skipIf(oslist=["linux"], archs=["arm$"])
 class TestDAP_attach(lldbdap_testcase.DAPTestCaseBase):
-    def spawn(self, args):
-        self.target_process = subprocess.Popen(
-            args,
-            stdin=subprocess.PIPE,
+    def spawn(self, program, args=None):
+        return self.spawnSubprocess(
+            executable=program,
+            args=args,
             stdout=subprocess.PIPE,
             stderr=subprocess.PIPE,
             universal_newlines=True,
@@ -26,8 +26,7 @@ def spawn(self, args):
 
     def spawn_and_wait(self, program, delay):
         time.sleep(delay)
-        self.spawn([program])
-        proc = self.target_process
+        proc = self.spawn(program=program)
         # Wait for either the process to exit or the event to be set
         while proc.poll() is None and not self.spawn_event.is_set():
             time.sleep(0.1)
@@ -36,16 +35,19 @@ def spawn_and_wait(self, program, delay):
 
     def continue_and_verify_pid(self):
         self.do_continue()
-        out, _ = self.target_process.communicate("foo")
-        self.assertIn(f"pid = {self.target_process.pid}", out)
+        proc = self.lastSubprocess
+        if proc is None:
+            self.fail(f"lastSubprocess is None")
+        out, _ = proc.communicate("foo")
+        self.assertIn(f"pid = {proc.pid}", out)
 
     def test_by_pid(self):
         """
         Tests attaching to a process by process ID.
         """
         program = self.build_and_create_debug_adapter_for_attach()
-        self.spawn([program])
-        self.attach(pid=self.target_process.pid)
+        proc = self.spawn(program=program)
+        self.attach(pid=proc.pid)
         self.continue_and_verify_pid()
 
     def test_by_name(self):
@@ -58,7 +60,7 @@ def test_by_name(self):
         pid_file_path = lldbutil.append_to_process_working_directory(
             self, "pid_file_%d" % (int(time.time()))
         )
-        self.spawn([program, pid_file_path])
+        self.spawn(program=program, args=[pid_file_path])
         lldbutil.wait_for_file_on_target(self, pid_file_path)
 
         self.attach(program=program)

>From 215bfc872e8bbaa87e9d6e205acbd8ffcfd30ef7 Mon Sep 17 00:00:00 2001
From: Charles Zablit <[email protected]>
Date: Fri, 19 Dec 2025 15:05:36 +0000
Subject: [PATCH 3/3] add kill method

---
 lldb/packages/Python/lldbsuite/test/lldbtest.py | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py 
b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index 321320910db02..67b94989f584e 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -461,6 +461,9 @@ def poll(self):
     def wait(self, timeout=None):
         return self._proc.wait(timeout)
 
+    def kill(self):
+        return self._proc.kill()
+
 
 class _RemoteProcess(_BaseProcess):
     def __init__(self, install_remote):

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to