[Lldb-commits] [lldb] [lldb][test] Allow dotest.py to call for Xcode to attach (PR #209628)
David Mentler via lldb-commits
lldb-commits at lists.llvm.org
Thu Jul 16 10:15:29 PDT 2026
https://github.com/mentlerd updated https://github.com/llvm/llvm-project/pull/209628
>From 9a4fb0e45c6bd37e726509c6f18ac668ecacc567 Mon Sep 17 00:00:00 2001
From: mentlerd <mentlerd at gmail.com>
Date: Tue, 14 Jul 2026 19:17:40 +0200
Subject: [PATCH 1/2] Allow dotest.py to call for Xcode to attach
This makes debugging API tests much simpler.
---
lldb/docs/resources/test.md | 3 +++
.../Python/lldbsuite/support/xcode.py | 24 +++++++++++++++++++
lldb/packages/Python/lldbsuite/test/dotest.py | 8 +++++--
.../Python/lldbsuite/test/dotest_args.py | 4 ++++
4 files changed, 37 insertions(+), 2 deletions(-)
create mode 100644 lldb/packages/Python/lldbsuite/support/xcode.py
diff --git a/lldb/docs/resources/test.md b/lldb/docs/resources/test.md
index 9b6d3912659a5..f305e1cf85093 100644
--- a/lldb/docs/resources/test.md
+++ b/lldb/docs/resources/test.md
@@ -698,6 +698,9 @@ On non-Windows platforms, you can use the `-d` option to `dotest.py` which
will cause the script to print out the pid of the test and wait for a while
until a debugger is attached. Then run `lldb -p <pid>` to attach.
+Xcode users may instead use the `--attach-xcode` option, which automatically
+attaches the IDE to the test process.
+
To instead debug a test's python source, edit the test and insert `import pdb; pdb.set_trace()` or `breakpoint()` (Python 3 only) at the point you want to start debugging. The `breakpoint()` command can be used for any LLDB Python script, not just for API tests.
In addition to pdb's debugging facilities, lldb commands can be executed with the
diff --git a/lldb/packages/Python/lldbsuite/support/xcode.py b/lldb/packages/Python/lldbsuite/support/xcode.py
new file mode 100644
index 0000000000000..278e138d99cf5
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/support/xcode.py
@@ -0,0 +1,24 @@
+import subprocess
+
+
+def attach(pid: int, suspended: bool = False) -> None:
+ script = """
+ on run argv
+ set targetPID to item 1 of argv as integer
+ set shouldSuspend to item 2 of argv as boolean
+
+ tell application "Xcode"
+ activate
+
+ if (count of workspace documents) is greater than 0 then
+ set debuggingWorkspace to workspace document 1
+ else
+ set debuggingWorkspace to create temporary debugging workspace
+ end if
+
+ attach debuggingWorkspace to process identifier targetPID suspended shouldSuspend
+ end tell
+ end run
+ """
+
+ subprocess.run(["osascript", "-e", script, str(pid), str(suspended)], check=True)
diff --git a/lldb/packages/Python/lldbsuite/test/dotest.py b/lldb/packages/Python/lldbsuite/test/dotest.py
index b1145f8f96078..c6c1e4e8d4b54 100644
--- a/lldb/packages/Python/lldbsuite/test/dotest.py
+++ b/lldb/packages/Python/lldbsuite/test/dotest.py
@@ -44,7 +44,7 @@
from . import test_result
from ..support import seven
from ..support import temp_file
-
+from ..support import xcode
def is_exe(fpath):
"""Returns true if fpath is an executable."""
@@ -381,12 +381,16 @@ def parseOptionsAndInitTestdirs():
setting_list = setting[0].split("=", 1)
configuration.settings.append((setting_list[0], setting_list[1]))
- if args.d:
+ if args.d or args.attach_xcode:
sys.stdout.write(
"Suspending the process %d to wait for debugger to attach...\n"
% os.getpid()
)
sys.stdout.flush()
+
+ if args.attach_xcode:
+ xcode.attach(os.getpid())
+
os.kill(os.getpid(), signal.SIGSTOP)
if args.f:
diff --git a/lldb/packages/Python/lldbsuite/test/dotest_args.py b/lldb/packages/Python/lldbsuite/test/dotest_args.py
index 13b3d85628dc2..5d02b59b0f11e 100644
--- a/lldb/packages/Python/lldbsuite/test/dotest_args.py
+++ b/lldb/packages/Python/lldbsuite/test/dotest_args.py
@@ -346,6 +346,10 @@ def create_parser():
"-d",
"Suspend the process after launch to wait indefinitely for a debugger to attach",
)
+ X(
+ "--attach-xcode",
+ "Suspend the process after launch, and instruct Xcode to attach to it",
+ )
X("-t", "Turn on tracing of lldb command and other detailed test executions")
group.add_argument(
"-u",
>From 3c054d63d8fc52fb5a002442fa4b09cca58b00ab Mon Sep 17 00:00:00 2001
From: mentlerd <mentlerd at gmail.com>
Date: Thu, 16 Jul 2026 19:14:59 +0200
Subject: [PATCH 2/2] Make debugger choice argument more generic for future
expansion
---
lldb/docs/resources/test.md | 7 ++++---
lldb/packages/Python/lldbsuite/test/dotest.py | 4 ++--
lldb/packages/Python/lldbsuite/test/dotest_args.py | 8 +++++---
3 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/lldb/docs/resources/test.md b/lldb/docs/resources/test.md
index f305e1cf85093..e3c02c25553f0 100644
--- a/lldb/docs/resources/test.md
+++ b/lldb/docs/resources/test.md
@@ -696,10 +696,11 @@ work with Arm or AArch64, but support for other architectures can be added easil
On non-Windows platforms, you can use the `-d` option to `dotest.py` which
will cause the script to print out the pid of the test and wait for a while
-until a debugger is attached. Then run `lldb -p <pid>` to attach.
+until a debugger is attached. Then run `lldb -p <pid>` to attach manually.
-Xcode users may instead use the `--attach-xcode` option, which automatically
-attaches the IDE to the test process.
+Alternatively, `dotest.py` can invoke a supported debugging tool and have it
+attach to the test process automatically. Use `--debug-with=...` to select the
+debugger.
To instead debug a test's python source, edit the test and insert `import pdb; pdb.set_trace()` or `breakpoint()` (Python 3 only) at the point you want to start debugging. The `breakpoint()` command can be used for any LLDB Python script, not just for API tests.
diff --git a/lldb/packages/Python/lldbsuite/test/dotest.py b/lldb/packages/Python/lldbsuite/test/dotest.py
index c6c1e4e8d4b54..4ab53a872cf04 100644
--- a/lldb/packages/Python/lldbsuite/test/dotest.py
+++ b/lldb/packages/Python/lldbsuite/test/dotest.py
@@ -381,14 +381,14 @@ def parseOptionsAndInitTestdirs():
setting_list = setting[0].split("=", 1)
configuration.settings.append((setting_list[0], setting_list[1]))
- if args.d or args.attach_xcode:
+ if args.d or args.debug_with:
sys.stdout.write(
"Suspending the process %d to wait for debugger to attach...\n"
% os.getpid()
)
sys.stdout.flush()
- if args.attach_xcode:
+ if args.debug_with == "xcode":
xcode.attach(os.getpid())
os.kill(os.getpid(), signal.SIGSTOP)
diff --git a/lldb/packages/Python/lldbsuite/test/dotest_args.py b/lldb/packages/Python/lldbsuite/test/dotest_args.py
index 5d02b59b0f11e..73aa708ddae08 100644
--- a/lldb/packages/Python/lldbsuite/test/dotest_args.py
+++ b/lldb/packages/Python/lldbsuite/test/dotest_args.py
@@ -346,9 +346,11 @@ def create_parser():
"-d",
"Suspend the process after launch to wait indefinitely for a debugger to attach",
)
- X(
- "--attach-xcode",
- "Suspend the process after launch, and instruct Xcode to attach to it",
+ group.add_argument(
+ "--debug-with",
+ dest="debug_with",
+ choices=["xcode"],
+ help="Suspend the process after launch, and instruct the specified debugger to attach to it",
)
X("-t", "Turn on tracing of lldb command and other detailed test executions")
group.add_argument(
More information about the lldb-commits
mailing list