llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Charles Zablit (charles-zablit)

<details>
<summary>Changes</summary>

Enumerate the loaded modules with `EnumProcessModulesEx` / 
`GetModuleFileNameExW` instead of the Toolhelp32 snapshot APIs, whose 
`MODULEENTRY32W::szExePath` is a fixed `MAX_PATH`.

A truncated path never matches the module's real FileSpec, so 
`GetFileLoadAddress()` fails to find modules loaded from deep directories and 
breakpoints in them never resolve.

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


1 Files Affected:

- (modified) 
lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp (+48-17) 


``````````diff
diff --git 
a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp 
b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
index 889a2e743c07f..b96d1eec24bab 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"
@@ -357,27 +358,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;
 }

``````````

</details>


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

Reply via email to