[libc-commits] [libc] [libc][mincore] use correct page_size for test (PR #73984)

Schrodinger ZHU Yifan via libc-commits libc-commits at lists.llvm.org
Thu Nov 30 16:36:55 PST 2023


https://github.com/SchrodingerZhu updated https://github.com/llvm/llvm-project/pull/73984

>From 3a4df5b7abc70841b561734ececf162e92ce5fe6 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Thu, 30 Nov 2023 15:41:16 -0500
Subject: [PATCH 1/2] [libc][mincore] use correct page_size for test

---
 libc/test/src/sys/mman/linux/CMakeLists.txt   |  1 +
 libc/test/src/sys/mman/linux/mincore_test.cpp | 54 ++++++++++---------
 2 files changed, 30 insertions(+), 25 deletions(-)

diff --git a/libc/test/src/sys/mman/linux/CMakeLists.txt b/libc/test/src/sys/mman/linux/CMakeLists.txt
index 5402ae030b345c6..c60377eb2cc1f73 100644
--- a/libc/test/src/sys/mman/linux/CMakeLists.txt
+++ b/libc/test/src/sys/mman/linux/CMakeLists.txt
@@ -76,5 +76,6 @@ add_libc_unittest(
     libc.src.sys.mman.munmap
     libc.src.sys.mman.madvise
     libc.src.sys.mman.mincore
+    libc.src.unistd.sysconf
     libc.test.UnitTest.ErrnoSetterMatcher
 )
diff --git a/libc/test/src/sys/mman/linux/mincore_test.cpp b/libc/test/src/sys/mman/linux/mincore_test.cpp
index 7c8ca3b4ffa4ccc..596e74aada1c89d 100644
--- a/libc/test/src/sys/mman/linux/mincore_test.cpp
+++ b/libc/test/src/sys/mman/linux/mincore_test.cpp
@@ -11,12 +11,13 @@
 #include "src/sys/mman/mincore.h"
 #include "src/sys/mman/mmap.h"
 #include "src/sys/mman/munmap.h"
+#include "src/unistd/sysconf.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/LibcTest.h"
 #include "test/UnitTest/Test.h"
 
-#include <linux/param.h> // For EXEC_PAGESIZE
 #include <sys/mman.h>
+#include <unistd.h> // For sysconf.
 
 using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
 using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
@@ -29,66 +30,69 @@ TEST(LlvmLibcMincoreTest, UnMappedMemory) {
 }
 
 TEST(LlvmLibcMincoreTest, InvalidVec) {
-  void *addr = LIBC_NAMESPACE::mmap(nullptr, 4 * EXEC_PAGESIZE, PROT_READ,
+  size_t page_size = static_cast<size_t>(LIBC_NAMESPACE::sysconf(_SC_PAGESIZE));
+  void *addr = LIBC_NAMESPACE::mmap(nullptr, 4 * page_size, PROT_READ,
                                     MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
   EXPECT_NE(addr, MAP_FAILED);
-  EXPECT_EQ(reinterpret_cast<unsigned long>(addr) % EXEC_PAGESIZE, 0ul);
+  EXPECT_EQ(reinterpret_cast<unsigned long>(addr) % page_size, 0ul);
   libc_errno = 0;
   int res = LIBC_NAMESPACE::mincore(addr, 1, nullptr);
   EXPECT_THAT(res, Fails(EFAULT, -1));
-  void *area =
-      LIBC_NAMESPACE::mmap(nullptr, EXEC_PAGESIZE, PROT_READ | PROT_WRITE,
-                           MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+  void *area = LIBC_NAMESPACE::mmap(nullptr, page_size, PROT_READ | PROT_WRITE,
+                                    MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
   EXPECT_NE(area, MAP_FAILED);
-  unsigned char *ptr = static_cast<unsigned char *>(area) + EXEC_PAGESIZE - 3;
-  res = LIBC_NAMESPACE::mincore(addr, 4 * EXEC_PAGESIZE, ptr);
+  unsigned char *ptr = static_cast<unsigned char *>(area) + page_size - 3;
+  res = LIBC_NAMESPACE::mincore(addr, 4 * page_size, ptr);
   EXPECT_THAT(res, Fails(EFAULT, -1));
-  EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, EXEC_PAGESIZE), Succeeds());
+  EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, page_size), Succeeds());
   EXPECT_THAT(LIBC_NAMESPACE::munmap(area, 2), Succeeds());
 }
 
 TEST(LlvmLibcMincoreTest, UnalignedAddr) {
-  void *addr = LIBC_NAMESPACE::mmap(nullptr, EXEC_PAGESIZE, PROT_READ,
+  size_t page_size = static_cast<size_t>(LIBC_NAMESPACE::sysconf(_SC_PAGESIZE));
+  void *addr = LIBC_NAMESPACE::mmap(nullptr, page_size, PROT_READ,
                                     MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
   EXPECT_NE(addr, MAP_FAILED);
-  EXPECT_EQ(reinterpret_cast<unsigned long>(addr) % EXEC_PAGESIZE, 0ul);
+  EXPECT_EQ(reinterpret_cast<unsigned long>(addr) % page_size, 0ul);
   libc_errno = 0;
   int res = LIBC_NAMESPACE::mincore(static_cast<char *>(addr) + 1, 1, nullptr);
   EXPECT_THAT(res, Fails(EINVAL, -1));
-  EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, EXEC_PAGESIZE), Succeeds());
+  EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, page_size), Succeeds());
 }
 
 TEST(LlvmLibcMincoreTest, NoError) {
-  void *addr = LIBC_NAMESPACE::mmap(nullptr, EXEC_PAGESIZE, PROT_READ,
+  size_t page_size = static_cast<size_t>(LIBC_NAMESPACE::sysconf(_SC_PAGESIZE));
+  void *addr = LIBC_NAMESPACE::mmap(nullptr, page_size, PROT_READ,
                                     MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
   EXPECT_NE(addr, MAP_FAILED);
-  EXPECT_EQ(reinterpret_cast<unsigned long>(addr) % EXEC_PAGESIZE, 0ul);
+  EXPECT_EQ(reinterpret_cast<unsigned long>(addr) % page_size, 0ul);
   unsigned char vec;
   libc_errno = 0;
   int res = LIBC_NAMESPACE::mincore(addr, 1, &vec);
   EXPECT_THAT(res, Succeeds());
-  EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, EXEC_PAGESIZE), Succeeds());
+  EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, page_size), Succeeds());
 }
 
 TEST(LlvmLibcMincoreTest, NegativeLength) {
-  void *addr = LIBC_NAMESPACE::mmap(nullptr, EXEC_PAGESIZE, PROT_READ,
+  size_t page_size = static_cast<size_t>(LIBC_NAMESPACE::sysconf(_SC_PAGESIZE));
+  void *addr = LIBC_NAMESPACE::mmap(nullptr, page_size, PROT_READ,
                                     MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
   EXPECT_NE(addr, MAP_FAILED);
-  EXPECT_EQ(reinterpret_cast<unsigned long>(addr) % EXEC_PAGESIZE, 0ul);
+  EXPECT_EQ(reinterpret_cast<unsigned long>(addr) % page_size, 0ul);
   unsigned char vec;
   libc_errno = 0;
   int res = LIBC_NAMESPACE::mincore(addr, -1, &vec);
   EXPECT_THAT(res, Fails(ENOMEM, -1));
-  EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, EXEC_PAGESIZE), Succeeds());
+  EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, page_size), Succeeds());
 }
 
 TEST(LlvmLibcMincoreTest, PageOut) {
   unsigned char vec;
-  void *addr =
-      LIBC_NAMESPACE::mmap(nullptr, EXEC_PAGESIZE, PROT_READ | PROT_WRITE,
-                           MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+  size_t page_size = static_cast<size_t>(LIBC_NAMESPACE::sysconf(_SC_PAGESIZE));
+  void *addr = LIBC_NAMESPACE::mmap(nullptr, page_size, PROT_READ | PROT_WRITE,
+                                    MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
   EXPECT_NE(addr, MAP_FAILED);
-  EXPECT_EQ(reinterpret_cast<unsigned long>(addr) % EXEC_PAGESIZE, 0ul);
+  EXPECT_EQ(reinterpret_cast<unsigned long>(addr) % page_size, 0ul);
 
   // touch the page
   {
@@ -102,14 +106,14 @@ TEST(LlvmLibcMincoreTest, PageOut) {
   // page out the memory
   {
     libc_errno = 0;
-    EXPECT_THAT(LIBC_NAMESPACE::madvise(addr, EXEC_PAGESIZE, MADV_DONTNEED),
+    EXPECT_THAT(LIBC_NAMESPACE::madvise(addr, page_size, MADV_DONTNEED),
                 Succeeds());
 
     libc_errno = 0;
-    int res = LIBC_NAMESPACE::mincore(addr, EXEC_PAGESIZE, &vec);
+    int res = LIBC_NAMESPACE::mincore(addr, page_size, &vec);
     EXPECT_EQ(vec & 1u, 0u);
     EXPECT_THAT(res, Succeeds());
   }
 
-  EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, EXEC_PAGESIZE), Succeeds());
+  EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, page_size), Succeeds());
 }

>From 0628a2e45ca62068e282611c17e6b59c803265ca Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Thu, 30 Nov 2023 19:34:53 -0500
Subject: [PATCH 2/2] workaround asan problem

---
 libc/test/src/sys/mman/linux/mincore_test.cpp | 56 ++++++++++++-------
 1 file changed, 36 insertions(+), 20 deletions(-)

diff --git a/libc/test/src/sys/mman/linux/mincore_test.cpp b/libc/test/src/sys/mman/linux/mincore_test.cpp
index 596e74aada1c89d..99147fc21177d1c 100644
--- a/libc/test/src/sys/mman/linux/mincore_test.cpp
+++ b/libc/test/src/sys/mman/linux/mincore_test.cpp
@@ -16,6 +16,7 @@
 #include "test/UnitTest/LibcTest.h"
 #include "test/UnitTest/Test.h"
 
+#include <cstdint>
 #include <sys/mman.h>
 #include <unistd.h> // For sysconf.
 
@@ -29,23 +30,35 @@ TEST(LlvmLibcMincoreTest, UnMappedMemory) {
   EXPECT_THAT(res, Fails(ENOMEM, -1));
 }
 
+// It is always possible to find an aligned boundary if we allocate page sized
+// memory.
+static char *aligned_addr(void *addr, size_t alignment) {
+  char *byte_addr = static_cast<char *>(addr);
+  uintptr_t addr_val = reinterpret_cast<uintptr_t>(addr);
+  uintptr_t offset =
+      addr_val % alignment == 0 ? 0 : alignment - (addr_val % alignment);
+  return byte_addr + offset;
+}
+
 TEST(LlvmLibcMincoreTest, InvalidVec) {
   size_t page_size = static_cast<size_t>(LIBC_NAMESPACE::sysconf(_SC_PAGESIZE));
-  void *addr = LIBC_NAMESPACE::mmap(nullptr, 4 * page_size, PROT_READ,
+  void *addr = LIBC_NAMESPACE::mmap(nullptr, 5 * page_size, PROT_READ,
                                     MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
   EXPECT_NE(addr, MAP_FAILED);
-  EXPECT_EQ(reinterpret_cast<unsigned long>(addr) % page_size, 0ul);
+  // Since we allocated 5 pages, we can find an aligned boundary after which
+  // there are at least 4 pages
+  char *aligned = aligned_addr(addr, page_size);
   libc_errno = 0;
-  int res = LIBC_NAMESPACE::mincore(addr, 1, nullptr);
+  int res = LIBC_NAMESPACE::mincore(aligned, 1, nullptr);
   EXPECT_THAT(res, Fails(EFAULT, -1));
   void *area = LIBC_NAMESPACE::mmap(nullptr, page_size, PROT_READ | PROT_WRITE,
                                     MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
   EXPECT_NE(area, MAP_FAILED);
   unsigned char *ptr = static_cast<unsigned char *>(area) + page_size - 3;
-  res = LIBC_NAMESPACE::mincore(addr, 4 * page_size, ptr);
+  res = LIBC_NAMESPACE::mincore(aligned, 4 * page_size, ptr);
   EXPECT_THAT(res, Fails(EFAULT, -1));
-  EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, page_size), Succeeds());
-  EXPECT_THAT(LIBC_NAMESPACE::munmap(area, 2), Succeeds());
+  EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, 5 * page_size), Succeeds());
+  EXPECT_THAT(LIBC_NAMESPACE::munmap(area, page_size), Succeeds());
 }
 
 TEST(LlvmLibcMincoreTest, UnalignedAddr) {
@@ -53,9 +66,10 @@ TEST(LlvmLibcMincoreTest, UnalignedAddr) {
   void *addr = LIBC_NAMESPACE::mmap(nullptr, page_size, PROT_READ,
                                     MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
   EXPECT_NE(addr, MAP_FAILED);
-  EXPECT_EQ(reinterpret_cast<unsigned long>(addr) % page_size, 0ul);
+  char *aligned = aligned_addr(addr, page_size);
   libc_errno = 0;
-  int res = LIBC_NAMESPACE::mincore(static_cast<char *>(addr) + 1, 1, nullptr);
+  int res =
+      LIBC_NAMESPACE::mincore(static_cast<char *>(aligned) + 1, 1, nullptr);
   EXPECT_THAT(res, Fails(EINVAL, -1));
   EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, page_size), Succeeds());
 }
@@ -65,10 +79,10 @@ TEST(LlvmLibcMincoreTest, NoError) {
   void *addr = LIBC_NAMESPACE::mmap(nullptr, page_size, PROT_READ,
                                     MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
   EXPECT_NE(addr, MAP_FAILED);
-  EXPECT_EQ(reinterpret_cast<unsigned long>(addr) % page_size, 0ul);
+  char *aligned = aligned_addr(addr, page_size);
   unsigned char vec;
   libc_errno = 0;
-  int res = LIBC_NAMESPACE::mincore(addr, 1, &vec);
+  int res = LIBC_NAMESPACE::mincore(aligned, 1, &vec);
   EXPECT_THAT(res, Succeeds());
   EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, page_size), Succeeds());
 }
@@ -78,10 +92,10 @@ TEST(LlvmLibcMincoreTest, NegativeLength) {
   void *addr = LIBC_NAMESPACE::mmap(nullptr, page_size, PROT_READ,
                                     MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
   EXPECT_NE(addr, MAP_FAILED);
-  EXPECT_EQ(reinterpret_cast<unsigned long>(addr) % page_size, 0ul);
+  char *aligned = aligned_addr(addr, page_size);
   unsigned char vec;
   libc_errno = 0;
-  int res = LIBC_NAMESPACE::mincore(addr, -1, &vec);
+  int res = LIBC_NAMESPACE::mincore(aligned, -1, &vec);
   EXPECT_THAT(res, Fails(ENOMEM, -1));
   EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, page_size), Succeeds());
 }
@@ -89,16 +103,18 @@ TEST(LlvmLibcMincoreTest, NegativeLength) {
 TEST(LlvmLibcMincoreTest, PageOut) {
   unsigned char vec;
   size_t page_size = static_cast<size_t>(LIBC_NAMESPACE::sysconf(_SC_PAGESIZE));
-  void *addr = LIBC_NAMESPACE::mmap(nullptr, page_size, PROT_READ | PROT_WRITE,
-                                    MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+  // allocate 2 pages since we need to page out page_size bytes
+  void *addr =
+      LIBC_NAMESPACE::mmap(nullptr, 2 * page_size, PROT_READ | PROT_WRITE,
+                           MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
   EXPECT_NE(addr, MAP_FAILED);
-  EXPECT_EQ(reinterpret_cast<unsigned long>(addr) % page_size, 0ul);
+  char *aligned = aligned_addr(addr, page_size);
 
   // touch the page
   {
-    static_cast<char *>(addr)[0] = 0;
+    aligned[0] = 0;
     libc_errno = 0;
-    int res = LIBC_NAMESPACE::mincore(addr, 1, &vec);
+    int res = LIBC_NAMESPACE::mincore(aligned, 1, &vec);
     EXPECT_EQ(vec & 1u, 1u);
     EXPECT_THAT(res, Succeeds());
   }
@@ -106,14 +122,14 @@ TEST(LlvmLibcMincoreTest, PageOut) {
   // page out the memory
   {
     libc_errno = 0;
-    EXPECT_THAT(LIBC_NAMESPACE::madvise(addr, page_size, MADV_DONTNEED),
+    EXPECT_THAT(LIBC_NAMESPACE::madvise(aligned, page_size, MADV_DONTNEED),
                 Succeeds());
 
     libc_errno = 0;
-    int res = LIBC_NAMESPACE::mincore(addr, page_size, &vec);
+    int res = LIBC_NAMESPACE::mincore(aligned, 1, &vec);
     EXPECT_EQ(vec & 1u, 0u);
     EXPECT_THAT(res, Succeeds());
   }
 
-  EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, page_size), Succeeds());
+  EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, 2 * page_size), Succeeds());
 }



More information about the libc-commits mailing list