[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