[Lldb-commits] [lldb] 643969e - [lldb] Run the LLDB test suite under MTE on capable Apple HW (#185780)

via lldb-commits lldb-commits at lists.llvm.org
Thu Mar 12 09:24:21 PDT 2026


Author: Jonas Devlieghere
Date: 2026-03-12T09:24:15-07:00
New Revision: 643969e78040401f2c18f6f853be53f87c3a753e

URL: https://github.com/llvm/llvm-project/commit/643969e78040401f2c18f6f853be53f87c3a753e
DIFF: https://github.com/llvm/llvm-project/commit/643969e78040401f2c18f6f853be53f87c3a753e.diff

LOG: [lldb] Run the LLDB test suite under MTE on capable Apple HW (#185780)

This PR adds support for running the LLDB test suite under MTE. It's
enabled by default on capable hardware when asserts are enabled. It
relies on a launcher (#185921) which launches the process with the
appropriate posix_spawn attribute. One thing worth noting here is that
child processes inherit the MTE property, so binaries launched by the
test suite in this mode also run under MTE.

Besides the logic to detect the default and thread through the launcher,
I also had to make a small change to LLVM LIT's `ToolSubst` class to
support an optional launcher for the shell tests.

Added: 
    

Modified: 
    lldb/cmake/modules/LLDBConfig.cmake
    lldb/test/API/lit.site.cfg.py.in
    lldb/test/API/lldbtest.py
    lldb/test/CMakeLists.txt
    lldb/test/Shell/helper/toolchain.py
    lldb/test/Shell/lit.site.cfg.py.in
    lldb/tools/CMakeLists.txt
    llvm/utils/lit/lit/llvm/subst.py

Removed: 
    


################################################################################
diff  --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig.cmake
index 42af86b57cfcc..291f189c2bee8 100644
--- a/lldb/cmake/modules/LLDBConfig.cmake
+++ b/lldb/cmake/modules/LLDBConfig.cmake
@@ -163,6 +163,27 @@ if (LLDB_ENABLE_LIBEDIT)
   set(CMAKE_EXTRA_INCLUDE_FILES)
 endif()
 
+if (APPLE)
+  set(default_enable_mte OFF)
+
+  execute_process(
+      COMMAND sysctl -n hw.optional.arm.FEAT_MTE4
+      OUTPUT_VARIABLE SYSCTL_OUTPUT
+      ERROR_QUIET
+      RESULT_VARIABLE SYSCTL_RESULT
+      OUTPUT_STRIP_TRAILING_WHITESPACE
+  )
+  if(SYSCTL_RESULT EQUAL 0)
+    set(default_enable_mte ON)
+  endif()
+
+  option(LLDB_ENABLE_MTE "Run the LLDB test suite with MTE enabled." ${default_enable_mte})
+
+  if (LLDB_ENABLE_MTE)
+    message(STATUS "Running the LLDB test suite with MTE")
+  endif()
+endif()
+
 if (LLDB_ENABLE_PYTHON)
   if(CMAKE_SYSTEM_NAME MATCHES "Windows")
     set(default_embed_python_home ON)

diff  --git a/lldb/test/API/lit.site.cfg.py.in b/lldb/test/API/lit.site.cfg.py.in
index c4e4352fe7915..6cc4542bca75e 100644
--- a/lldb/test/API/lit.site.cfg.py.in
+++ b/lldb/test/API/lit.site.cfg.py.in
@@ -42,6 +42,7 @@ config.has_libcxx = @LLDB_HAS_LIBCXX@
 config.libcxx_libs_dir = "@LIBCXX_LIBRARY_DIR@"
 config.libcxx_include_dir = "@LIBCXX_GENERATED_INCLUDE_DIR@"
 config.libcxx_include_target_dir = "@LIBCXX_GENERATED_INCLUDE_TARGET_DIR@"
+config.lldb_launcher = "@LLDB_LAUNCHER@"
 # The API tests use their own module caches.
 config.lldb_module_cache = os.path.join("@LLDB_TEST_MODULE_CACHE_LLDB@", "lldb-api")
 config.clang_module_cache = os.path.join("@LLDB_TEST_MODULE_CACHE_CLANG@", "lldb-api")

diff  --git a/lldb/test/API/lldbtest.py b/lldb/test/API/lldbtest.py
index acd018236e440..9762c47205647 100644
--- a/lldb/test/API/lldbtest.py
+++ b/lldb/test/API/lldbtest.py
@@ -55,6 +55,10 @@ def execute(self, test, litConfig):
         # python exe as the first parameter of the command.
         cmd = [executable] + self.dotest_cmd + [testPath, "-p", testFile]
 
+        launcher = getattr(test.config, "lldb_launcher", None)
+        if launcher:
+            cmd = [launcher] + cmd
+
         if isLuaTest:
             cmd.extend(["--env", "LUA_EXECUTABLE=%s" % test.config.lua_executable])
             cmd.extend(["--env", "LLDB_LUA_CPATH=%s" % test.config.lldb_lua_cpath])

diff  --git a/lldb/test/CMakeLists.txt b/lldb/test/CMakeLists.txt
index 513d1ec493ee1..d7d745a512002 100644
--- a/lldb/test/CMakeLists.txt
+++ b/lldb/test/CMakeLists.txt
@@ -132,6 +132,11 @@ if(TARGET lldb-framework)
   add_lldb_test_dependency(lldb-framework)
 endif()
 
+if(TARGET darwin-mte-launcher)
+  add_lldb_test_dependency(darwin-mte-launcher)
+  set(LLDB_LAUNCHER ${LLVM_RUNTIME_OUTPUT_INTDIR}/darwin-mte-launcher${CMAKE_EXECUTABLE_SUFFIX})
+endif()
+
 if (LLDB_CAN_USE_LLDB_RPC_SERVER)
   add_lldb_test_dependency(lldb-rpc-generate-sources)
 endif()

diff  --git a/lldb/test/Shell/helper/toolchain.py b/lldb/test/Shell/helper/toolchain.py
index 66664561a249d..df20a4ae7af5e 100644
--- a/lldb/test/Shell/helper/toolchain.py
+++ b/lldb/test/Shell/helper/toolchain.py
@@ -118,24 +118,28 @@ def use_lldb_substitutions(config):
         build_script_args.append("--sysroot={0}".format(config.cmake_sysroot))
 
     lldb_init = _get_lldb_init_path(config)
+    launcher = getattr(config, "lldb_launcher", None)
 
     primary_tools = [
         ToolSubst(
             "%lldb",
             command=FindTool("lldb"),
             extra_args=get_lldb_args(config),
+            launcher=launcher,
             unresolved="fatal",
         ),
         ToolSubst(
             "%lldb-init",
             command=FindTool("lldb"),
             extra_args=["-S", lldb_init],
+            launcher=launcher,
             unresolved="fatal",
         ),
         ToolSubst(
             "%lldb-noinit",
             command=FindTool("lldb"),
             extra_args=["--no-lldbinit"],
+            launcher=launcher,
             unresolved="fatal",
         ),
         ToolSubst(

diff  --git a/lldb/test/Shell/lit.site.cfg.py.in b/lldb/test/Shell/lit.site.cfg.py.in
index 47beac002a19c..b260b2fce90b7 100644
--- a/lldb/test/Shell/lit.site.cfg.py.in
+++ b/lldb/test/Shell/lit.site.cfg.py.in
@@ -35,6 +35,7 @@ config.lldb_system_debugserver = @LLDB_USE_SYSTEM_DEBUGSERVER@
 config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@"
 config.lldb_has_lldbrpc = @LLDB_BUILD_LLDBRPC@
 config.have_dia_sdk = @LLVM_ENABLE_DIA_SDK@
+config.lldb_launcher = "@LLDB_LAUNCHER@"
 # The shell tests use their own module caches.
 config.lldb_module_cache = os.path.join("@LLDB_TEST_MODULE_CACHE_LLDB@", "lldb-shell")
 config.clang_module_cache = os.path.join("@LLDB_TEST_MODULE_CACHE_CLANG@", "lldb-shell")

diff  --git a/lldb/tools/CMakeLists.txt b/lldb/tools/CMakeLists.txt
index eaa74f1953b3c..4e6600e3d2eec 100644
--- a/lldb/tools/CMakeLists.txt
+++ b/lldb/tools/CMakeLists.txt
@@ -20,7 +20,9 @@ endif()
 
 if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
   add_lldb_tool_subdirectory(darwin-debug)
-  add_lldb_tool_subdirectory(darwin-mte-launcher)
+  if (LLDB_ENABLE_MTE)
+    add_lldb_tool_subdirectory(darwin-mte-launcher)
+  endif()
   if(NOT LLDB_USE_SYSTEM_DEBUGSERVER)
     add_lldb_tool_subdirectory(debugserver)
   endif()

diff  --git a/llvm/utils/lit/lit/llvm/subst.py b/llvm/utils/lit/lit/llvm/subst.py
index 09ab3555a6b44..39a6a75e4c79b 100644
--- a/llvm/utils/lit/lit/llvm/subst.py
+++ b/llvm/utils/lit/lit/llvm/subst.py
@@ -44,6 +44,7 @@ def __init__(
         verbatim=False,
         unresolved="warn",
         extra_args=None,
+        launcher=None,
     ):
         """Construct a ToolSubst.
 
@@ -79,6 +80,7 @@ def __init__(
         """
         self.unresolved = unresolved
         self.extra_args = extra_args
+        self.launcher = launcher
         self.key = key
         self.command = command if command is not None else FindTool(key)
         self.was_resolved = False
@@ -120,6 +122,8 @@ def resolve(self, config, search_dirs):
         if command_str:
             if self.extra_args:
                 command_str = " ".join([command_str] + self.extra_args)
+            if self.launcher:
+                command_str = self.launcher + " " + command_str
         else:
             if self.unresolved == "warn":
                 # Warn, but still provide a substitution.


        


More information about the lldb-commits mailing list