[Lldb-commits] [lldb] [lldb][test] Only calculate LLDB python path once (PR #201327)

Raphael Isemann via lldb-commits lldb-commits at lists.llvm.org
Mon Jun 8 01:55:24 PDT 2026


https://github.com/Teemperor updated https://github.com/llvm/llvm-project/pull/201327

>From 8bd83e07cef79f28668056e8dafd904109f2f58e Mon Sep 17 00:00:00 2001
From: Raphael Isemann <rise at apple.com>
Date: Wed, 3 Jun 2026 11:17:17 +0100
Subject: [PATCH 1/2] [lldb][test] Don't print LLDB version in every test

An empty minimal API test currently runs for 330ms on my macOS system.
Of these 330ms, we spend 70ms (20%) just to print the lldb version
number at the start of each test.

This patch disables this behavior by default and instead prints the
LLDB version number once at the start of the LIT test suite. This
saves about 2 minutes of CPU time in an LLDB test suite run.
---
 .../Python/lldbsuite/test/configuration.py         |  3 +++
 lldb/packages/Python/lldbsuite/test/dotest.py      |  6 +++++-
 lldb/packages/Python/lldbsuite/test/dotest_args.py |  6 ++++++
 lldb/test/API/lit.cfg.py                           | 14 ++++++++++++++
 4 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/lldb/packages/Python/lldbsuite/test/configuration.py b/lldb/packages/Python/lldbsuite/test/configuration.py
index d1c933b35fcdf..8347565dc26a4 100644
--- a/lldb/packages/Python/lldbsuite/test/configuration.py
+++ b/lldb/packages/Python/lldbsuite/test/configuration.py
@@ -154,6 +154,9 @@
 # Whether debugserver is built with arm64e support.
 arm64e_debugserver = False
 
+# Whether to print the lldb version banner during test setup.
+print_lldb_version = False
+
 # the build type of lldb
 # Typical values include Debug, Release, RelWithDebInfo and MinSizeRel
 cmake_build_type = None
diff --git a/lldb/packages/Python/lldbsuite/test/dotest.py b/lldb/packages/Python/lldbsuite/test/dotest.py
index 888d980e398d3..252d02c9b6d72 100644
--- a/lldb/packages/Python/lldbsuite/test/dotest.py
+++ b/lldb/packages/Python/lldbsuite/test/dotest.py
@@ -472,6 +472,9 @@ def parseOptionsAndInitTestdirs():
     if args.arm64e_debugserver:
         configuration.arm64e_debugserver = True
 
+    if args.print_lldb_version:
+        configuration.print_lldb_version = True
+
     # Gather all the dirs passed on the command line.
     if len(args.args) > 0:
         configuration.testdirs = [
@@ -568,7 +571,8 @@ def setupSysPath():
         )
         sys.exit(-1)
 
-    os.system("%s -v" % lldbtest_config.lldbExec)
+    if configuration.print_lldb_version:
+        os.system("%s -v" % lldbtest_config.lldbExec)
 
     lldbDir = os.path.dirname(lldbtest_config.lldbExec)
 
diff --git a/lldb/packages/Python/lldbsuite/test/dotest_args.py b/lldb/packages/Python/lldbsuite/test/dotest_args.py
index f3b0837bdc4ab..c9d91718b3339 100644
--- a/lldb/packages/Python/lldbsuite/test/dotest_args.py
+++ b/lldb/packages/Python/lldbsuite/test/dotest_args.py
@@ -281,6 +281,12 @@ def create_parser():
         action="store_true",
         help="Indicate that debugserver is built with arm64e support.",
     )
+    group.add_argument(
+        "--print-lldb-version",
+        dest="print_lldb_version",
+        action="store_true",
+        help="Print the lldb version banner during test setup.",
+    )
 
     # Configuration options
     group = parser.add_argument_group("Remote platform options")
diff --git a/lldb/test/API/lit.cfg.py b/lldb/test/API/lit.cfg.py
index 2662a77199641..930f1b40f309a 100644
--- a/lldb/test/API/lit.cfg.py
+++ b/lldb/test/API/lit.cfg.py
@@ -255,6 +255,20 @@ def delete_module_cache(path):
 
 if is_configured("lldb_executable"):
     dotest_cmd += ["--executable", config.lldb_executable]
+    try:
+        version_output = subprocess.check_output(
+            [config.lldb_executable, "--version"],
+            stderr=subprocess.STDOUT,
+            text=True,
+        ).strip()
+        for line in version_output.splitlines():
+            lit_config.note(line.strip())
+    except (subprocess.CalledProcessError, OSError) as e:
+        lit_config.warning(
+            "Could not get lldb version from {}: {}".format(
+                config.lldb_executable, e
+            )
+        )
 
 if is_configured("test_compiler"):
     dotest_cmd += ["--compiler", config.test_compiler]

>From 39b70cac3e29d0d05214428b256384cb10cb122f Mon Sep 17 00:00:00 2001
From: Raphael Isemann <rise at apple.com>
Date: Wed, 3 Jun 2026 12:51:15 +0100
Subject: [PATCH 2/2] [lldb][test] Only calculate LLDB python path once

We spend about 70ms each dotest invocation recalculating the path where
the LLDB module is. This patch changes this so that dotest calculates
this path once and passes it to every dotest invocation.

As a fallback, we still support inferring the location from LLDB as
before, but I would propose we drop this support in the future.
---
 .../Python/lldbsuite/test/configuration.py    |  5 +++
 lldb/packages/Python/lldbsuite/test/dotest.py | 40 ++++++++++++++-----
 .../Python/lldbsuite/test/dotest_args.py      |  6 +++
 lldb/test/API/lit.cfg.py                      | 22 ++++++++++
 4 files changed, 62 insertions(+), 11 deletions(-)

diff --git a/lldb/packages/Python/lldbsuite/test/configuration.py b/lldb/packages/Python/lldbsuite/test/configuration.py
index 8347565dc26a4..d16af69e96f35 100644
--- a/lldb/packages/Python/lldbsuite/test/configuration.py
+++ b/lldb/packages/Python/lldbsuite/test/configuration.py
@@ -157,6 +157,11 @@
 # Whether to print the lldb version banner during test setup.
 print_lldb_version = False
 
+# Path to the directory containing the 'lldb' Python module (i.e. the directory
+# that contains 'lldb/__init__.py'). When set, dotest skips the `lldb -P`
+# subprocess used to discover this path.
+lldb_python_dir = None
+
 # the build type of lldb
 # Typical values include Debug, Release, RelWithDebInfo and MinSizeRel
 cmake_build_type = None
diff --git a/lldb/packages/Python/lldbsuite/test/dotest.py b/lldb/packages/Python/lldbsuite/test/dotest.py
index 252d02c9b6d72..41270505b2b8d 100644
--- a/lldb/packages/Python/lldbsuite/test/dotest.py
+++ b/lldb/packages/Python/lldbsuite/test/dotest.py
@@ -475,6 +475,9 @@ def parseOptionsAndInitTestdirs():
     if args.print_lldb_version:
         configuration.print_lldb_version = True
 
+    if args.lldb_python_dir:
+        configuration.lldb_python_dir = args.lldb_python_dir
+
     # Gather all the dirs passed on the command line.
     if len(args.args) > 0:
         configuration.testdirs = [
@@ -586,17 +589,32 @@ def setupSysPath():
 
     lldbPythonDir = None  # The directory that contains 'lldb/__init__.py'
 
-    # If our lldb supports the -P option, use it to find the python path:
-    lldb_dash_p_result = subprocess.check_output(
-        [lldbtest_config.lldbExec, "-P"], universal_newlines=True
-    )
-    if lldb_dash_p_result:
-        for line in lldb_dash_p_result.splitlines():
-            if os.path.isdir(line) and os.path.exists(
-                os.path.join(line, "lldb", "__init__.py")
-            ):
-                lldbPythonDir = line
-                break
+    if configuration.lldb_python_dir:
+        # The path was passed in (typically by LIT, which discovers it once for
+        # the whole test run). Trust it without spawning lldb.
+        candidate = configuration.lldb_python_dir
+        if os.path.isdir(candidate) and os.path.exists(
+            os.path.join(candidate, "lldb", "__init__.py")
+        ):
+            lldbPythonDir = candidate
+        else:
+            print(
+                "warning: --lldb-python-dir '%s' does not contain 'lldb/__init__.py'; "
+                "falling back to '%s -P'" % (candidate, lldbtest_config.lldbExec)
+            )
+
+    if not lldbPythonDir:
+        # If our lldb supports the -P option, use it to find the python path:
+        lldb_dash_p_result = subprocess.check_output(
+            [lldbtest_config.lldbExec, "-P"], universal_newlines=True
+        )
+        if lldb_dash_p_result:
+            for line in lldb_dash_p_result.splitlines():
+                if os.path.isdir(line) and os.path.exists(
+                    os.path.join(line, "lldb", "__init__.py")
+                ):
+                    lldbPythonDir = line
+                    break
 
     if not lldbPythonDir:
         print(
diff --git a/lldb/packages/Python/lldbsuite/test/dotest_args.py b/lldb/packages/Python/lldbsuite/test/dotest_args.py
index c9d91718b3339..f52b318af8099 100644
--- a/lldb/packages/Python/lldbsuite/test/dotest_args.py
+++ b/lldb/packages/Python/lldbsuite/test/dotest_args.py
@@ -287,6 +287,12 @@ def create_parser():
         action="store_true",
         help="Print the lldb version banner during test setup.",
     )
+    group.add_argument(
+        "--lldb-python-dir",
+        dest="lldb_python_dir",
+        metavar="path",
+        help="Path to the directory that contains the 'lldb' Python module. ",
+    )
 
     # Configuration options
     group = parser.add_argument_group("Remote platform options")
diff --git a/lldb/test/API/lit.cfg.py b/lldb/test/API/lit.cfg.py
index 930f1b40f309a..fcf5e2e0d812c 100644
--- a/lldb/test/API/lit.cfg.py
+++ b/lldb/test/API/lit.cfg.py
@@ -270,6 +270,28 @@ def delete_module_cache(path):
             )
         )
 
+    # Discover the directory that contains the 'lldb' Python module once here,
+    # so each dotest invocation doesn't have to spawn '<lldb> -P' itself.
+    try:
+        lldb_dash_p_output = subprocess.check_output(
+            [config.lldb_executable, "-P"],
+            stderr=subprocess.STDOUT,
+            text=True,
+        )
+        for line in lldb_dash_p_output.splitlines():
+            line = line.strip()
+            if os.path.isdir(line) and os.path.exists(
+                os.path.join(line, "lldb", "__init__.py")
+            ):
+                dotest_cmd += ["--lldb-python-dir", line]
+                break
+    except (subprocess.CalledProcessError, OSError) as e:
+        lit_config.warning(
+            "Could not discover lldb python path from {}: {}".format(
+                config.lldb_executable, e
+            )
+        )
+
 if is_configured("test_compiler"):
     dotest_cmd += ["--compiler", config.test_compiler]
 



More information about the lldb-commits mailing list