[lldb] [llvm] [lldb] Run the LLDB test suite under MTE on capable Apple HW (PR #185780)
Jonas Devlieghere via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 10 20:00:49 PDT 2026
https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/185780
>From bcf7a93795f62e64ba5db148fd413c1ac0c8f18b Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Tue, 10 Mar 2026 15:07:18 -0700
Subject: [PATCH 1/2] [lldb] Add darwin-mte-launcher
---
lldb/tools/CMakeLists.txt | 1 +
lldb/tools/darwin-mte-launch/CMakeLists.txt | 6 ++
.../darwin-mte-launch/darwin-mte-launch.cpp | 74 +++++++++++++++++++
3 files changed, 81 insertions(+)
create mode 100644 lldb/tools/darwin-mte-launch/CMakeLists.txt
create mode 100644 lldb/tools/darwin-mte-launch/darwin-mte-launch.cpp
diff --git a/lldb/tools/CMakeLists.txt b/lldb/tools/CMakeLists.txt
index 4b54c1a50eb2f..7376c30958e06 100644
--- a/lldb/tools/CMakeLists.txt
+++ b/lldb/tools/CMakeLists.txt
@@ -20,6 +20,7 @@ endif()
if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
add_lldb_tool_subdirectory(darwin-debug)
+ add_lldb_tool_subdirectory(darwin-mte-launch)
if(NOT LLDB_USE_SYSTEM_DEBUGSERVER)
add_lldb_tool_subdirectory(debugserver)
endif()
diff --git a/lldb/tools/darwin-mte-launch/CMakeLists.txt b/lldb/tools/darwin-mte-launch/CMakeLists.txt
new file mode 100644
index 0000000000000..95212d7cbbb2f
--- /dev/null
+++ b/lldb/tools/darwin-mte-launch/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_lldb_tool(darwin-mte-launch
+ darwin-mte-launch.cpp
+
+ LINK_COMPONENTS
+ Support
+)
diff --git a/lldb/tools/darwin-mte-launch/darwin-mte-launch.cpp b/lldb/tools/darwin-mte-launch/darwin-mte-launch.cpp
new file mode 100644
index 0000000000000..f5f7f74279864
--- /dev/null
+++ b/lldb/tools/darwin-mte-launch/darwin-mte-launch.cpp
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/WithColor.h"
+#include <dlfcn.h>
+#include <spawn.h>
+#include <string.h>
+#include <vector>
+
+using namespace llvm;
+
+int main(int argc, const char *argv[], const char *envp[]) {
+ const char *program = argv[1];
+
+ posix_spawnattr_t attr;
+ int ret = posix_spawnattr_init(&attr);
+ if (ret != 0) {
+ WithColor::error() << "posix_spawnattr_init failed\n";
+ return EXIT_FAILURE;
+ }
+
+ typedef int (*posix_spawnattr_set_use_sec_transition_shims_np_t)(
+ posix_spawnattr_t *attr, uint32_t flags);
+ posix_spawnattr_set_use_sec_transition_shims_np_t
+ posix_spawnattr_set_use_sec_transition_shims_np_fn =
+ (posix_spawnattr_set_use_sec_transition_shims_np_t)dlsym(
+ RTLD_DEFAULT, "posix_spawnattr_set_use_sec_transition_shims_np");
+
+ if (!posix_spawnattr_set_use_sec_transition_shims_np_fn) {
+ WithColor::error()
+ << "posix_spawnattr_set_use_sec_transition_shims_np not available\n";
+ return EXIT_FAILURE;
+ }
+
+ ret = posix_spawnattr_set_use_sec_transition_shims_np_fn(&attr, /*unused=*/0);
+ if (ret != 0) {
+ WithColor::error()
+ << "posix_spawnattr_set_use_sec_transition_shims_np failed\n";
+ return EXIT_FAILURE;
+ }
+
+ std::vector<char *> new_args;
+ for (int i = 1; i < argc; ++i)
+ new_args.push_back(const_cast<char *>(argv[i]));
+ new_args.push_back(nullptr);
+
+ std::vector<char *> new_envp;
+ for (const char **e = envp; *e; ++e)
+ new_envp.push_back(const_cast<char *>(*e));
+ new_envp.push_back(const_cast<char *>("PYTHONMALLOC=malloc"));
+ new_envp.push_back(nullptr);
+
+ pid_t pid;
+ ret =
+ posix_spawn(&pid, program, NULL, &attr, new_args.data(), new_envp.data());
+ if (ret != 0) {
+ WithColor::error() << "posix_spawn() failed with error " << ret << "("
+ << strerror(ret) << ")\n";
+ return EXIT_FAILURE;
+ }
+
+ int status;
+ if (waitpid(pid, &status, 0) == -1) {
+ WithColor::error() << "waitpid failed\n";
+ return EXIT_FAILURE;
+ }
+
+ return WEXITSTATUS(status);
+}
>From fad625190ddb90ebf498fe68d1360508feb65478 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Tue, 10 Mar 2026 17:07:34 -0700
Subject: [PATCH 2/2] [lldb] Run tests under MTE on capable HW
---
lldb/cmake/modules/LLDBConfig.cmake | 24 ++++++++++++++++++++++++
lldb/test/API/lit.site.cfg.py.in | 1 +
lldb/test/API/lldbtest.py | 4 ++++
lldb/test/CMakeLists.txt | 5 +++++
lldb/test/Shell/helper/toolchain.py | 4 ++++
lldb/test/Shell/lit.site.cfg.py.in | 1 +
lldb/tools/CMakeLists.txt | 4 +++-
llvm/utils/lit/lit/llvm/subst.py | 4 ++++
8 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig.cmake
index 42af86b57cfcc..89989b2881b42 100644
--- a/lldb/cmake/modules/LLDBConfig.cmake
+++ b/lldb/cmake/modules/LLDBConfig.cmake
@@ -163,6 +163,30 @@ if (LLDB_ENABLE_LIBEDIT)
set(CMAKE_EXTRA_INCLUDE_FILES)
endif()
+if (APPLE)
+ set(default_enable_mte OFF)
+
+ # Default to ON on capable hardware when assertions are enabled.
+ if (LLVM_ENABLE_ASSERTIONS)
+ 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()
+ 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 d6b79ebc2c434..f586a34f9e95f 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..8504c7d55e905 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-launch)
+ add_lldb_test_dependency(darwin-mte-launch)
+ set(LLDB_LAUNCHER ${LLVM_RUNTIME_OUTPUT_INTDIR}/darwin-mte-launch${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 7376c30958e06..6d49b83eb6874 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-launch)
+ if (LLDB_ENABLE_MTE)
+ add_lldb_tool_subdirectory(darwin-mte-launch)
+ 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 llvm-commits
mailing list