https://github.com/charles-zablit updated 
https://github.com/llvm/llvm-project/pull/206117

>From 451a57ee3e8b1da968e48cae1c7c5ffe22e98762 Mon Sep 17 00:00:00 2001
From: Charles Zablit <[email protected]>
Date: Fri, 26 Jun 2026 16:52:40 +0100
Subject: [PATCH 1/2] [lldb][windows] support long path in loaded modules cache

---
 .../Windows/Common/NativeProcessWindows.cpp   | 65 ++++++++++++++-----
 1 file changed, 48 insertions(+), 17 deletions(-)

diff --git 
a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp 
b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
index ada92894efc47..146e053dbd867 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
@@ -9,6 +9,7 @@
 #include "lldb/Host/windows/windows.h"
 #include <dbghelp.h>
 #include <excpt.h>
+#include <pathcch.h>
 #include <psapi.h>
 
 #include "NativeProcessWindows.h"
@@ -397,27 +398,57 @@ Status NativeProcessWindows::CacheLoadedModules() {
   if (!m_loaded_modules.empty())
     return Status();
 
-  // Retrieve loaded modules by a Target/Module-free implementation.
-  AutoHandle snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetID()));
-  if (snapshot.IsValid()) {
-    MODULEENTRY32W me;
-    me.dwSize = sizeof(MODULEENTRY32W);
-    if (Module32FirstW(snapshot.get(), &me)) {
-      do {
-        std::string path;
-        if (!llvm::convertWideToUTF8(me.szExePath, path))
-          continue;
-
-        FileSpec file_spec(path);
-        FileSystem::Instance().Resolve(file_spec);
-        m_loaded_modules[file_spec] = (addr_t)me.modBaseAddr;
-      } while (Module32Next(snapshot.get(), &me));
+  AutoHandle process(::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
+                                   FALSE, GetID()),
+                     nullptr);
+  if (!process.IsValid())
+    return Status(::GetLastError(), eErrorTypeWin32);
+
+  std::vector<HMODULE> modules(256);
+  DWORD bytes_needed = 0;
+  while (true) {
+    if (!::EnumProcessModulesEx(
+            process.get(), modules.data(),
+            static_cast<DWORD>(modules.size() * sizeof(HMODULE)), 
&bytes_needed,
+            LIST_MODULES_ALL))
+      return Status(::GetLastError(), eErrorTypeWin32);
+    size_t count = bytes_needed / sizeof(HMODULE);
+    if (count <= modules.size()) {
+      modules.resize(count);
+      break;
     }
+    modules.resize(count);
+  }
 
-    if (!m_loaded_modules.empty())
-      return Status();
+  for (HMODULE hmod : modules) {
+    std::vector<wchar_t> name(MAX_PATH);
+    DWORD len = 0;
+    while (name.size() <= PATHCCH_MAX_CCH) {
+      len = ::GetModuleFileNameExW(process.get(), hmod, name.data(),
+                                   static_cast<DWORD>(name.size()));
+      if (len == 0 || len < name.size())
+        break;
+      name.resize(name.size() * 2);
+    }
+    if (len == 0)
+      continue;
+
+    std::string path;
+    if (!llvm::convertWideToUTF8(std::wstring(name.data(), len), path))
+      continue;
+
+    MODULEINFO mi = {};
+    if (!::GetModuleInformation(process.get(), hmod, &mi, sizeof(mi)))
+      continue;
+
+    FileSpec file_spec(path);
+    FileSystem::Instance().Resolve(file_spec);
+    m_loaded_modules[file_spec] = reinterpret_cast<addr_t>(mi.lpBaseOfDll);
   }
 
+  if (!m_loaded_modules.empty())
+    return Status();
+
   error = Status(::GetLastError(), lldb::ErrorType::eErrorTypeWin32);
   return error;
 }

>From 289a9dfe89fa2bdb49bea6f593191bf2d9d02465 Mon Sep 17 00:00:00 2001
From: Charles Zablit <[email protected]>
Date: Wed, 15 Jul 2026 12:23:57 +0100
Subject: [PATCH 2/2] fixup! [lldb][windows] support long path in loaded
 modules cache

---
 .../Windows/Common/NativeProcessWindows.cpp   | 110 +++++++++++-------
 1 file changed, 71 insertions(+), 39 deletions(-)

diff --git 
a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp 
b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
index 146e053dbd867..ae3d677ce01c1 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
@@ -393,57 +393,89 @@ Status 
NativeProcessWindows::RemoveBreakpoint(lldb::addr_t addr,
   return RemoveSoftwareBreakpoint(addr);
 }
 
+// Resolve the fully qualified, normalized on disk path of a module loaded in
+// the target process.
+static bool GetLoadedModulePath(HANDLE process, HMODULE module,
+                                std::string &path) {
+  std::vector<wchar_t> name(MAX_PATH);
+  DWORD len = 0;
+  while (true) {
+    len = ::GetModuleFileNameExW(process, module, name.data(),
+                                 static_cast<DWORD>(name.size()));
+    if (len == 0)
+      return false;
+    if (len < name.size())
+      break;
+    if (name.size() >= PATHCCH_MAX_CCH)
+      return false;
+    name.resize(name.size() * 2);
+  }
+
+  std::wstring wpath(name.data(), len);
+
+  // Canonicalize through a handle to the image file so the reported path
+  // matches the on-disk name exactly.
+  AutoHandle file(::CreateFileW(wpath.c_str(), 0,
+                                FILE_SHARE_READ | FILE_SHARE_WRITE |
+                                    FILE_SHARE_DELETE,
+                                nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
+                                nullptr));
+
+  if (!file.IsValid())
+    return llvm::convertWideToUTF8(wpath, path);
+
+  std::vector<wchar_t> full(MAX_PATH);
+  while (true) {
+    DWORD needed = ::GetFinalPathNameByHandleW(
+        file.get(), full.data(), static_cast<DWORD>(full.size()),
+        FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
+    if (needed == 0)
+      break;
+    if (needed < full.size()) {
+      std::wstring canonical(full.data(), needed);
+      // GetFinalPathNameByHandleW returns an extended-length ("\\?\") path.
+      static const wchar_t kUNCPrefix[] = L"\\\\?\\UNC\\";
+      static const wchar_t kDOSPrefix[] = L"\\\\?\\";
+      if (canonical.rfind(kUNCPrefix, 0) == 0)
+        canonical.replace(0, wcslen(kUNCPrefix), L"\\\\");
+      else if (canonical.rfind(kDOSPrefix, 0) == 0)
+        canonical.erase(0, wcslen(kDOSPrefix));
+      wpath = std::move(canonical);
+      break;
+    }
+    full.resize(needed);
+  }
+
+  return llvm::convertWideToUTF8(wpath, path);
+}
+
 Status NativeProcessWindows::CacheLoadedModules() {
   Status error;
   if (!m_loaded_modules.empty())
     return Status();
 
+  AutoHandle snapshot(::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetID()));
+  if (!snapshot.IsValid())
+    return Status(::GetLastError(), eErrorTypeWin32);
+
   AutoHandle process(::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
                                    FALSE, GetID()),
                      nullptr);
   if (!process.IsValid())
     return Status(::GetLastError(), eErrorTypeWin32);
 
-  std::vector<HMODULE> modules(256);
-  DWORD bytes_needed = 0;
-  while (true) {
-    if (!::EnumProcessModulesEx(
-            process.get(), modules.data(),
-            static_cast<DWORD>(modules.size() * sizeof(HMODULE)), 
&bytes_needed,
-            LIST_MODULES_ALL))
-      return Status(::GetLastError(), eErrorTypeWin32);
-    size_t count = bytes_needed / sizeof(HMODULE);
-    if (count <= modules.size()) {
-      modules.resize(count);
-      break;
-    }
-    modules.resize(count);
-  }
-
-  for (HMODULE hmod : modules) {
-    std::vector<wchar_t> name(MAX_PATH);
-    DWORD len = 0;
-    while (name.size() <= PATHCCH_MAX_CCH) {
-      len = ::GetModuleFileNameExW(process.get(), hmod, name.data(),
-                                   static_cast<DWORD>(name.size()));
-      if (len == 0 || len < name.size())
-        break;
-      name.resize(name.size() * 2);
-    }
-    if (len == 0)
-      continue;
-
-    std::string path;
-    if (!llvm::convertWideToUTF8(std::wstring(name.data(), len), path))
-      continue;
-
-    MODULEINFO mi = {};
-    if (!::GetModuleInformation(process.get(), hmod, &mi, sizeof(mi)))
-      continue;
+  MODULEENTRY32W me;
+  me.dwSize = sizeof(MODULEENTRY32W);
+  if (::Module32FirstW(snapshot.get(), &me)) {
+    do {
+      std::string path;
+      if (!GetLoadedModulePath(process.get(), me.hModule, path))
+        continue;
 
-    FileSpec file_spec(path);
-    FileSystem::Instance().Resolve(file_spec);
-    m_loaded_modules[file_spec] = reinterpret_cast<addr_t>(mi.lpBaseOfDll);
+      FileSpec file_spec(path);
+      FileSystem::Instance().Resolve(file_spec);
+      m_loaded_modules[file_spec] = reinterpret_cast<addr_t>(me.modBaseAddr);
+    } while (::Module32NextW(snapshot.get(), &me));
   }
 
   if (!m_loaded_modules.empty())

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to