[Lldb-commits] [lldb] [lldb-dap] refactor monitor thread in tests (PR #172879)
Charles Zablit via lldb-commits
lldb-commits at lists.llvm.org
Fri Dec 19 07:05:49 PST 2025
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 <c_zablit at apple.com>
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 <c_zablit at apple.com>
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 <c_zablit at apple.com>
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):
More information about the lldb-commits
mailing list