[Lldb-commits] [lldb] 4a8900f - [lldb][windows] add sibling-import fallback to LoadImage helper (#197218)
via lldb-commits
lldb-commits at lists.llvm.org
Wed May 13 07:16:25 PDT 2026
Author: Charles Zablit
Date: 2026-05-13T16:16:19+02:00
New Revision: 4a8900ff41ca51528d44bc384a9b8dc327ccf8ae
URL: https://github.com/llvm/llvm-project/commit/4a8900ff41ca51528d44bc384a9b8dc327ccf8ae
DIFF: https://github.com/llvm/llvm-project/commit/4a8900ff41ca51528d44bc384a9b8dc327ccf8ae.diff
LOG: [lldb][windows] add sibling-import fallback to LoadImage helper (#197218)
`PlatformWindows::DoLoadImage` injects `__lldb_LoadLibraryHelper` which
registers each caller-supplied search path via `AddDllDirectory()` and
calls `LoadLibraryExW(name, nullptr, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)`.
In practice however, this flow fails for a common layout where a DLL
lives next to its sibling imports. LoadLibraryExW returns
ERROR_CANT_RESOLVE_FILENAME and the load is reported as unrecoverable,
even though every required DLL is present in one of the search paths.
This patch adds a fallback after the first `LoadLibraryExW(name,
nullptr, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)` call: if it fails, iterate
the caller-provided search paths and try `LoadLibraryExW(path, nullptr,
LOAD_WITH_ALTERED_SEARCH_PATH)`. `LOAD_WITH_ALTERED_SEARCH_PATH`
instructs the Windows loader to add the DLL's own directory to the
dependency search.
See
https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexa.
---------
Co-authored-by: Nerixyz <nero.9 at hotmail.de>
Added:
Modified:
lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
Removed:
################################################################################
diff --git a/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp b/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
index c82841ab029aa..eecbe53d46c24 100644
--- a/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
+++ b/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
@@ -645,6 +645,11 @@ extern "C" {
// application should include in its DLL search path.
#define LOAD_LIBRARY_SEARCH_DEFAULT_DIRS 0x00001000
+// If this value is used, and lpFileName specifies an absolute path, the system
+// uses the alternate file search strategy to find associated executable
+// modules.
+#define LOAD_WITH_ALTERED_SEARCH_PATH 0x00000008
+
// WINBASEAPI DWORD WINAPI GetLastError(VOID);
/* __declspec(dllimport) */ uint32_t __stdcall GetLastError();
@@ -688,6 +693,32 @@ void * __lldb_LoadLibraryHelper(const wchar_t *name, const wchar_t *paths,
result->ImageBase = LoadLibraryExW(name, nullptr,
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
+
+ // Fallback: if the AddDllDirectory + LOAD_LIBRARY_SEARCH_DEFAULT_DIRS path
+ // failed to find the library, iterate the search paths ourselves and
+ // load by absolute path using LOAD_WITH_ALTERED_SEARCH_PATH, which makes
+ // Windows use the loaded DLL's own directory to resolve its sibling imports.
+ if (result->ImageBase == nullptr) {
+ wchar_t full[4096];
+ for (const wchar_t *path = paths; path && *path; path += wcslen(path) + 1) {
+ size_t plen = wcslen(path);
+ size_t nlen = wcslen(name);
+ // Need room for: path + '\\' + name + '\0'
+ if (plen + 1 + nlen + 1 > 4096)
+ continue;
+ wchar_t *p = full;
+ for (size_t i = 0; i < plen; ++i)
+ *p++ = path[i];
+ *p++ = L'\\';
+ for (size_t i = 0; i <= nlen; ++i) // Copy name including trailing '\0'.
+ *p++ = name[i];
+ result->ImageBase = LoadLibraryExW(full, nullptr,
+ LOAD_WITH_ALTERED_SEARCH_PATH);
+ if (result->ImageBase != nullptr)
+ break;
+ }
+ }
+
if (result->ImageBase == nullptr)
result->ErrorCode = GetLastError();
else
More information about the lldb-commits
mailing list