[Lldb-commits] [lldb] [lldb][windows] support long path in loaded modules cache (PR #206117)
via lldb-commits
lldb-commits at lists.llvm.org
Fri Jun 26 08:55:06 PDT 2026
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
More information about the lldb-commits
mailing list