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/3] [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/3] 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()) >From f46af2fc0e5d89fc06efcde94c65c245d7da51fe Mon Sep 17 00:00:00 2001 From: Charles Zablit <[email protected]> Date: Wed, 15 Jul 2026 12:31:18 +0100 Subject: [PATCH 3/3] fix formatting --- .../Process/Windows/Common/NativeProcessWindows.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp index ae3d677ce01c1..d65459288a97b 100644 --- a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp +++ b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp @@ -415,11 +415,9 @@ static bool GetLoadedModulePath(HANDLE process, HMODULE module, // 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)); + 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); _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
