[Lldb-commits] [lldb] [lldb][AArch64][Linux] Fix memory tagging tests (PR #192421)

David Spickett via lldb-commits lldb-commits at lists.llvm.org
Thu Apr 16 03:05:23 PDT 2026


https://github.com/DavidSpickett updated https://github.com/llvm/llvm-project/pull/192421

>From 0ff922f51ce6ad2fc4fd0986a671c521456cfae3 Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at arm.com>
Date: Mon, 13 Apr 2026 13:44:11 +0000
Subject: [PATCH 1/2] [lldb][AArch64][Linux] Fix some memory tagging tests

The test program was relying on mmap calls to allocate
pages that were next to each other, which is not guaranteed
but I got away with it on our simulated systems for a time.

Instead of taking this chance, allocate all the pages once
and then split the allocation by changing the permissions
of each page. That ordering we can rely on.

The repeating tag options test is broken due
to #192057 so I've xfailed it.
---
 .../TestAArch64LinuxMTEMemoryTagAccess.py     |  4 ++
 .../API/linux/aarch64/mte_tag_access/main.c   | 47 +++++++++----------
 2 files changed, 27 insertions(+), 24 deletions(-)

diff --git a/lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py b/lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py
index 33f8c1c0830b1..bfaaea684e24b 100644
--- a/lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py
+++ b/lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py
@@ -590,8 +590,12 @@ def test_mte_memory_read_tag_display(self):
     @skipUnlessArch("aarch64")
     @skipUnlessPlatform(["linux"])
     @skipUnlessAArch64MTELinuxCompiler
+    # Repeating options currently does not work, see
+    # https://github.com/llvm/llvm-project/issues/192057.
+    @expectedFailureAll(oslist=["linux"])
     def test_mte_memory_read_tag_display_repeated(self):
         """Test that the --show-tags option is kept when repeating the memory read command."""
+
         self.setup_mte_test()
 
         self.expect(
diff --git a/lldb/test/API/linux/aarch64/mte_tag_access/main.c b/lldb/test/API/linux/aarch64/mte_tag_access/main.c
index 934cce8c3fa6c..f96316fe22b07 100644
--- a/lldb/test/API/linux/aarch64/mte_tag_access/main.c
+++ b/lldb/test/API/linux/aarch64/mte_tag_access/main.c
@@ -11,13 +11,19 @@
 // This file uses ACLE intrinsics as detailed in:
 // https://developer.arm.com/documentation/101028/0012/10--Memory-tagging-intrinsics?lang=en
 
-char *checked_mmap(size_t page_size, int prot) {
-  char *ptr = mmap(0, page_size, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+char *checked_mmap(size_t size, int prot) {
+  char *ptr = mmap(0, size, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
   if (ptr == MAP_FAILED)
     exit(1);
   return ptr;
 }
 
+char *checked_mprotect(char *addr, size_t size, int prot) {
+  if (mprotect(addr, size, prot) != 0)
+    exit(1);
+  return addr;
+}
+
 int main(int argc, char const *argv[]) {
   // We assume that the test runner has checked we're on an MTE system
 
@@ -30,29 +36,22 @@ int main(int argc, char const *argv[]) {
     return 1;
   }
 
-  size_t page_size = sysconf(_SC_PAGESIZE);
-
-  // We're going to mmap pages in this order:
-  // <high addres>
-  // MTE read/write
-  // MTE read/write executable
-  // non MTE
-  // MTE read only
-  // <low address>
-  //
-  // This means that the first two MTE pages end up next
-  // to each other. Since the second one is also executable
-  // it will create a new entry in /proc/smaps.
-  int mte_prot = PROT_READ | PROT_MTE;
-
-  char *mte_buf_2 = checked_mmap(page_size, mte_prot | PROT_WRITE);
-  char *mte_buf = checked_mmap(page_size, mte_prot | PROT_WRITE | PROT_EXEC);
-  // We expect the mappings to be next to each other
-  if (mte_buf_2 - mte_buf != page_size)
-    return 1;
+  const size_t page_size = sysconf(_SC_PAGESIZE);
+  // Each time we change the permissions of a page, it becomes its own unique
+  // mapping.
+  char *pages = checked_mmap(page_size * 4, 0);
 
-  char *non_mte_buf = checked_mmap(page_size, PROT_READ);
-  char *mte_read_only = checked_mmap(page_size, mte_prot);
+  // The order and layout of these mappings is important. They start with
+  // the lowest address.
+  char *mte_read_only =
+      checked_mprotect(pages, page_size, PROT_MTE | PROT_READ);
+  char *non_mte_buf =
+      checked_mprotect(mte_read_only + page_size, page_size, PROT_READ);
+  char *mte_buf =
+      checked_mprotect(non_mte_buf + page_size, page_size,
+                       PROT_READ | PROT_MTE | PROT_WRITE | PROT_EXEC);
+  char *mte_buf_2 = checked_mprotect(mte_buf + page_size, page_size,
+                                     PROT_MTE | PROT_READ | PROT_WRITE);
 
   // Target value for "memory find" testing.
   strncpy(mte_buf+128, "LLDB", 4);

>From 985001e0c85f3e50dfb0b2f744aeb6110de45eab Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at arm.com>
Date: Thu, 16 Apr 2026 10:05:07 +0000
Subject: [PATCH 2/2] remove whitespace

---
 .../aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py b/lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py
index bfaaea684e24b..f5c49ec0dd38b 100644
--- a/lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py
+++ b/lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py
@@ -595,7 +595,6 @@ def test_mte_memory_read_tag_display(self):
     @expectedFailureAll(oslist=["linux"])
     def test_mte_memory_read_tag_display_repeated(self):
         """Test that the --show-tags option is kept when repeating the memory read command."""
-
         self.setup_mte_test()
 
         self.expect(



More information about the lldb-commits mailing list