Skip to content

Conversation

@charles-zablit
Copy link
Contributor

@charles-zablit charles-zablit commented Nov 27, 2025

This is an NFC patch which fully qualifies references to MemoryRegionInfo in lldb.

The Windows API exposes an enum value named MemoryRegionInfo which causes a build error when building with NTDDI_VERSION >= NTDDI_WIN10_RS1:

// memoryapi.h
#if (NTDDI_VERSION >= NTDDI_WIN10_RS1)

typedef enum WIN32_MEMORY_INFORMATION_CLASS {
    MemoryRegionInfo
} WIN32_MEMORY_INFORMATION_CLASS;

Please refer to https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-queryvirtualmemoryinformation#requirements for the minimum version.

This causes an unresolved symbol error due to ambiguity. Fully qualifying the name removes this ambiguity.

Please note that this patch is a preface to:

@llvmbot
Copy link
Member

llvmbot commented Nov 27, 2025

@llvm/pr-subscribers-platform-windows

@llvm/pr-subscribers-lldb

Author: Charles Zablit (charles-zablit)

Changes

This is an NFC patch which fully qualifies references to MemoryRegionInfo in lldb.

The Windows API exposes an enum value named MemoryRegionInfo which causes a build error when editing building with NTDDI_VERSION >= NTDDI_WIN10_RS1.

// memoryapi.h
#if (NTDDI_VERSION >= NTDDI_WIN10_RS1)

typedef enum WIN32_MEMORY_INFORMATION_CLASS {
    MemoryRegionInfo
} WIN32_MEMORY_INFORMATION_CLASS;

This causes an unresolved symbol error due to ambiguity. Fully qualifying the name removes this ambiguity.

Please note that this patch is a preface to:


Full diff: https://github.com/llvm/llvm-project/pull/169845.diff

3 Files Affected:

  • (modified) lldb/source/Interpreter/ScriptInterpreter.cpp (+1-1)
  • (modified) lldb/source/Target/Process.cpp (+9-8)
  • (modified) lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp (+19-15)
diff --git a/lldb/source/Interpreter/ScriptInterpreter.cpp b/lldb/source/Interpreter/ScriptInterpreter.cpp
index 211868b51facb..d2fd372bfe9e3 100644
--- a/lldb/source/Interpreter/ScriptInterpreter.cpp
+++ b/lldb/source/Interpreter/ScriptInterpreter.cpp
@@ -136,7 +136,7 @@ SymbolContext ScriptInterpreter::GetOpaqueTypeFromSBSymbolContext(
   return {};
 }
 
-std::optional<MemoryRegionInfo>
+std::optional<lldb_private::MemoryRegionInfo>
 ScriptInterpreter::GetOpaqueTypeFromSBMemoryRegionInfo(
     const lldb::SBMemoryRegionInfo &mem_region) const {
   if (!mem_region.m_opaque_up)
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 69edea503002e..b483fbaea256a 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -6545,7 +6545,7 @@ Status Process::WriteMemoryTags(lldb::addr_t addr, size_t len,
 
 // Create a CoreFileMemoryRange from a MemoryRegionInfo
 static CoreFileMemoryRange
-CreateCoreFileMemoryRange(const MemoryRegionInfo &region) {
+CreateCoreFileMemoryRange(const lldb_private::MemoryRegionInfo &region) {
   const addr_t addr = region.GetRange().GetRangeBase();
   llvm::AddressRange range(addr, addr + region.GetRange().GetByteSize());
   return {range, region.GetLLDBPermissions()};
@@ -6554,7 +6554,7 @@ CreateCoreFileMemoryRange(const MemoryRegionInfo &region) {
 // Add dirty pages to the core file ranges and return true if dirty pages
 // were added. Return false if the dirty page information is not valid or in
 // the region.
-static bool AddDirtyPages(const MemoryRegionInfo &region,
+static bool AddDirtyPages(const lldb_private::MemoryRegionInfo &region,
                           CoreFileMemoryRanges &ranges) {
   const auto &dirty_page_list = region.GetDirtyPageList();
   if (!dirty_page_list)
@@ -6593,8 +6593,8 @@ static bool AddDirtyPages(const MemoryRegionInfo &region,
 // given region. If the region has dirty page information, only dirty pages
 // will be added to \a ranges, else the entire range will be added to \a
 // ranges.
-static void AddRegion(const MemoryRegionInfo &region, bool try_dirty_pages,
-                      CoreFileMemoryRanges &ranges) {
+static void AddRegion(const lldb_private::MemoryRegionInfo &region,
+                      bool try_dirty_pages, CoreFileMemoryRanges &ranges) {
   // Don't add empty ranges.
   if (region.GetRange().GetByteSize() == 0)
     return;
@@ -6617,7 +6617,7 @@ static void SaveDynamicLoaderSections(Process &process,
   if (!dyld)
     return;
 
-  std::vector<MemoryRegionInfo> dynamic_loader_mem_regions;
+  std::vector<lldb_private::MemoryRegionInfo> dynamic_loader_mem_regions;
   std::function<bool(const lldb_private::Thread &)> save_thread_predicate =
       [&](const lldb_private::Thread &t) -> bool {
     return options.ShouldThreadBeSaved(t.GetID());
@@ -6742,10 +6742,11 @@ static void GetCoreFileSaveRangesStackOnly(Process &process,
 
 // TODO: We should refactor CoreFileMemoryRanges to use the lldb range type, and
 // then add an intersect method on it, or MemoryRegionInfo.
-static MemoryRegionInfo Intersect(const MemoryRegionInfo &lhs,
-                                  const MemoryRegionInfo::RangeType &rhs) {
+static lldb_private::MemoryRegionInfo
+Intersect(const lldb_private::MemoryRegionInfo &lhs,
+          const lldb_private::MemoryRegionInfo::RangeType &rhs) {
 
-  MemoryRegionInfo region_info;
+  lldb_private::MemoryRegionInfo region_info;
   region_info.SetLLDBPermissions(lhs.GetLLDBPermissions());
   region_info.GetRange() = lhs.GetRange().Intersect(rhs);
 
diff --git a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
index 012eae02d5857..966b37e09ee55 100644
--- a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
+++ b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
@@ -326,7 +326,7 @@ TEST_F(GDBRemoteCommunicationClientTest, SendSignalsToIgnore) {
 
 TEST_F(GDBRemoteCommunicationClientTest, GetMemoryRegionInfo) {
   const lldb::addr_t addr = 0xa000;
-  MemoryRegionInfo region_info;
+  lldb_private::MemoryRegionInfo region_info;
   std::future<Status> result = std::async(std::launch::async, [&] {
     return client.GetMemoryRegionInfo(addr, region_info);
   });
@@ -343,13 +343,16 @@ TEST_F(GDBRemoteCommunicationClientTest, GetMemoryRegionInfo) {
   EXPECT_TRUE(result.get().Success());
   EXPECT_EQ(addr, region_info.GetRange().GetRangeBase());
   EXPECT_EQ(0x2000u, region_info.GetRange().GetByteSize());
-  EXPECT_EQ(MemoryRegionInfo::eYes, region_info.GetReadable());
-  EXPECT_EQ(MemoryRegionInfo::eNo, region_info.GetWritable());
-  EXPECT_EQ(MemoryRegionInfo::eYes, region_info.GetExecutable());
+  EXPECT_EQ(lldb_private::MemoryRegionInfo::eYes, region_info.GetReadable());
+  EXPECT_EQ(lldb_private::MemoryRegionInfo::eNo, region_info.GetWritable());
+  EXPECT_EQ(lldb_private::MemoryRegionInfo::eYes, region_info.GetExecutable());
   EXPECT_EQ("/foo/bar.so", region_info.GetName().GetStringRef());
-  EXPECT_EQ(MemoryRegionInfo::eDontKnow, region_info.GetMemoryTagged());
-  EXPECT_EQ(MemoryRegionInfo::eDontKnow, region_info.IsStackMemory());
-  EXPECT_EQ(MemoryRegionInfo::eDontKnow, region_info.IsShadowStack());
+  EXPECT_EQ(lldb_private::MemoryRegionInfo::eDontKnow,
+            region_info.GetMemoryTagged());
+  EXPECT_EQ(lldb_private::MemoryRegionInfo::eDontKnow,
+            region_info.IsStackMemory());
+  EXPECT_EQ(lldb_private::MemoryRegionInfo::eDontKnow,
+            region_info.IsShadowStack());
 
   result = std::async(std::launch::async, [&] {
     return client.GetMemoryRegionInfo(addr, region_info);
@@ -358,9 +361,9 @@ TEST_F(GDBRemoteCommunicationClientTest, GetMemoryRegionInfo) {
   HandlePacket(server, "qMemoryRegionInfo:a000",
                "start:a000;size:2000;flags:;type:stack;");
   EXPECT_TRUE(result.get().Success());
-  EXPECT_EQ(MemoryRegionInfo::eNo, region_info.GetMemoryTagged());
-  EXPECT_EQ(MemoryRegionInfo::eYes, region_info.IsStackMemory());
-  EXPECT_EQ(MemoryRegionInfo::eNo, region_info.IsShadowStack());
+  EXPECT_EQ(lldb_private::MemoryRegionInfo::eNo, region_info.GetMemoryTagged());
+  EXPECT_EQ(lldb_private::MemoryRegionInfo::eYes, region_info.IsStackMemory());
+  EXPECT_EQ(lldb_private::MemoryRegionInfo::eNo, region_info.IsShadowStack());
 
   result = std::async(std::launch::async, [&] {
     return client.GetMemoryRegionInfo(addr, region_info);
@@ -369,9 +372,10 @@ TEST_F(GDBRemoteCommunicationClientTest, GetMemoryRegionInfo) {
   HandlePacket(server, "qMemoryRegionInfo:a000",
                "start:a000;size:2000;flags: mt  zz mt ss  ;type:ha,ha,stack;");
   EXPECT_TRUE(result.get().Success());
-  EXPECT_EQ(MemoryRegionInfo::eYes, region_info.GetMemoryTagged());
-  EXPECT_EQ(MemoryRegionInfo::eYes, region_info.IsStackMemory());
-  EXPECT_EQ(MemoryRegionInfo::eYes, region_info.IsShadowStack());
+  EXPECT_EQ(lldb_private::MemoryRegionInfo::eYes,
+            region_info.GetMemoryTagged());
+  EXPECT_EQ(lldb_private::MemoryRegionInfo::eYes, region_info.IsStackMemory());
+  EXPECT_EQ(lldb_private::MemoryRegionInfo::eYes, region_info.IsShadowStack());
 
   result = std::async(std::launch::async, [&] {
     return client.GetMemoryRegionInfo(addr, region_info);
@@ -380,12 +384,12 @@ TEST_F(GDBRemoteCommunicationClientTest, GetMemoryRegionInfo) {
   HandlePacket(server, "qMemoryRegionInfo:a000",
                "start:a000;size:2000;type:heap;");
   EXPECT_TRUE(result.get().Success());
-  EXPECT_EQ(MemoryRegionInfo::eNo, region_info.IsStackMemory());
+  EXPECT_EQ(lldb_private::MemoryRegionInfo::eNo, region_info.IsStackMemory());
 }
 
 TEST_F(GDBRemoteCommunicationClientTest, GetMemoryRegionInfoInvalidResponse) {
   const lldb::addr_t addr = 0x4000;
-  MemoryRegionInfo region_info;
+  lldb_private::MemoryRegionInfo region_info;
   std::future<Status> result = std::async(std::launch::async, [&] {
     return client.GetMemoryRegionInfo(addr, region_info);
   });

@DavidSpickett
Copy link
Collaborator

which causes a build error when editing building with

"when building with"

Copy link
Collaborator

@DavidSpickett DavidSpickett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Please include a docs link in the PR description. I think https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-queryvirtualmemoryinformation is good enough, the table at the bottom has minimum versions.

Nothing seems to tell us what MemoryRegionInfo actually is, but the name existing is enough for the purposes of this PR.

@charles-zablit
Copy link
Contributor Author

which causes a build error when editing building with

"when building with"

Fixed, thanks!

@charles-zablit charles-zablit merged commit fb3bf5b into llvm:main Nov 28, 2025
13 checks passed
@charles-zablit charles-zablit deleted the charles-zablit/lldb/windows/add-namespace-to-memoryregioninfo branch November 28, 2025 11:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants