From 37cf46ea187afd50ce8b1eae58239aafe9b115db Mon Sep 17 00:00:00 2001 From: Charles Zablit Date: Wed, 8 Oct 2025 17:18:51 +0100 Subject: [PATCH 1/4] [lldb][windows] add support for out of PATH python.dll resolution --- lldb/cmake/modules/AddLLDB.cmake | 6 ++++ lldb/tools/driver/CMakeLists.txt | 4 +++ lldb/tools/driver/Driver.cpp | 49 ++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) diff --git a/lldb/cmake/modules/AddLLDB.cmake b/lldb/cmake/modules/AddLLDB.cmake index 28bf8d816d89a..4d2036e68704f 100644 --- a/lldb/cmake/modules/AddLLDB.cmake +++ b/lldb/cmake/modules/AddLLDB.cmake @@ -167,6 +167,12 @@ function(add_lldb_executable name) ) target_link_libraries(${name} PRIVATE ${ARG_LINK_LIBS}) + if(WIN32) + list(FIND ARG_LINK_LIBS liblldb LIBLLD_INDEX) + if(NOT LIBLLD_INDEX EQUAL -1) + target_link_options(${name} PRIVATE "/DELAYLOAD:$.dll") + endif() + endif() if(CLANG_LINK_CLANG_DYLIB) target_link_libraries(${name} PRIVATE clang-cpp) else() diff --git a/lldb/tools/driver/CMakeLists.txt b/lldb/tools/driver/CMakeLists.txt index 5c0cac484cc94..941ef0d83385b 100644 --- a/lldb/tools/driver/CMakeLists.txt +++ b/lldb/tools/driver/CMakeLists.txt @@ -34,6 +34,10 @@ add_dependencies(lldb ${tablegen_deps} ) +if(DEFINED LLDB_PYTHON_DLL_RELATIVE_PATH) + target_compile_definitions(lldb PRIVATE LLDB_PYTHON_DLL_RELATIVE_PATH="${LLDB_PYTHON_DLL_RELATIVE_PATH}") +endif() + if(LLDB_BUILD_FRAMEWORK) # In the build-tree, we know the exact path to the framework directory. # The installed framework can be in different locations. diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp index 16cc736441b59..df31d649ada48 100644 --- a/lldb/tools/driver/Driver.cpp +++ b/lldb/tools/driver/Driver.cpp @@ -22,11 +22,15 @@ #include "lldb/Host/MainLoop.h" #include "lldb/Host/MainLoopBase.h" #include "lldb/Utility/Status.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/ConvertUTF.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" #include "llvm/Support/InitLLVM.h" #include "llvm/Support/Path.h" #include "llvm/Support/Signals.h" +#include "llvm/Support/Windows/WindowsSupport.h" #include "llvm/Support/WithColor.h" #include "llvm/Support/raw_ostream.h" @@ -426,6 +430,47 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) { return error; } +#ifdef _WIN32 +// Returns the full path to the lldb.exe executable +inline std::wstring GetPathToExecutableW() { + // Iterate until we reach the Windows max path length (32,767). + std::vector buffer; + buffer.resize(MAX_PATH); + while (buffer.size() < 32767) { + if (GetModuleFileNameW(NULL, buffer.data(), buffer.size()) < buffer.size()) + return std::wstring(buffer.begin(), buffer.end()); + buffer.resize(buffer.size() * 2); + } + return L""; +} + +// Resolve the full path of the directory defined by +// LLDB_PYTHON_DLL_RELATIVE_PATH. If it exists, add it to the list of DLL search +// directories. +void AddPythonDLLToSearchPath() { + std::wstring modulePath = GetPathToExecutableW(); + if (modulePath.empty()) { + WithColor::error() << "Unable to find python: " << GetLastError() << '\n'; + return; + } + + SmallVector utf8Path; + if (sys::windows::UTF16ToUTF8(modulePath.c_str(), modulePath.length(), + utf8Path)) + return; + sys::path::remove_filename(utf8Path); + sys::path::append(utf8Path, LLDB_PYTHON_DLL_RELATIVE_PATH); + sys::fs::make_absolute(utf8Path); + + SmallVector widePath; + if (sys::windows::widenPath(utf8Path.data(), widePath)) + return; + + if (sys::fs::exists(utf8Path)) + SetDllDirectoryW(widePath.data()); +} +#endif + std::string EscapeString(std::string arg) { std::string::size_type pos = 0; while ((pos = arg.find_first_of("\"\\", pos)) != std::string::npos) { @@ -728,6 +773,10 @@ int main(int argc, char const *argv[]) { "~/Library/Logs/DiagnosticReports/.\n"); #endif +#ifdef _WIN32 + AddPythonDLLToSearchPath(); +#endif + // Parse arguments. LLDBOptTable T; unsigned MissingArgIndex; From 2f7a6f1bc40143dbfcef85cc903167fc0ac6e5e0 Mon Sep 17 00:00:00 2001 From: Charles Zablit Date: Wed, 8 Oct 2025 17:35:32 +0100 Subject: [PATCH 2/4] fixup! [lldb][windows] add support for out of PATH python.dll resolution --- lldb/tools/driver/Driver.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp index df31d649ada48..d35c30d2c6aea 100644 --- a/lldb/tools/driver/Driver.cpp +++ b/lldb/tools/driver/Driver.cpp @@ -30,10 +30,13 @@ #include "llvm/Support/InitLLVM.h" #include "llvm/Support/Path.h" #include "llvm/Support/Signals.h" -#include "llvm/Support/Windows/WindowsSupport.h" #include "llvm/Support/WithColor.h" #include "llvm/Support/raw_ostream.h" +#if _WIN32 +#include "llvm/Support/Windows/WindowsSupport.h" +#endif + #include #include #include @@ -773,7 +776,7 @@ int main(int argc, char const *argv[]) { "~/Library/Logs/DiagnosticReports/.\n"); #endif -#ifdef _WIN32 +#if defined(_WIN32) && defined(LLDB_PYTHON_DLL_RELATIVE_PATH) AddPythonDLLToSearchPath(); #endif From e9625a456ad2dc9f22952f86d70ac8d3af9a5fbd Mon Sep 17 00:00:00 2001 From: Charles Zablit Date: Thu, 9 Oct 2025 10:36:13 +0100 Subject: [PATCH 3/4] address comments --- lldb/cmake/modules/AddLLDB.cmake | 4 ++-- lldb/tools/driver/Driver.cpp | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lldb/cmake/modules/AddLLDB.cmake b/lldb/cmake/modules/AddLLDB.cmake index 4d2036e68704f..bdd6f73238422 100644 --- a/lldb/cmake/modules/AddLLDB.cmake +++ b/lldb/cmake/modules/AddLLDB.cmake @@ -168,8 +168,8 @@ function(add_lldb_executable name) target_link_libraries(${name} PRIVATE ${ARG_LINK_LIBS}) if(WIN32) - list(FIND ARG_LINK_LIBS liblldb LIBLLD_INDEX) - if(NOT LIBLLD_INDEX EQUAL -1) + list(FIND ARG_LINK_LIBS liblldb LIBLLDB_INDEX) + if(NOT LIBLLDB_INDEX EQUAL -1) target_link_options(${name} PRIVATE "/DELAYLOAD:$.dll") endif() endif() diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp index d35c30d2c6aea..ad887fc9bc675 100644 --- a/lldb/tools/driver/Driver.cpp +++ b/lldb/tools/driver/Driver.cpp @@ -33,7 +33,7 @@ #include "llvm/Support/WithColor.h" #include "llvm/Support/raw_ostream.h" -#if _WIN32 +#ifdef _WIN32 #include "llvm/Support/Windows/WindowsSupport.h" #endif @@ -434,11 +434,11 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) { } #ifdef _WIN32 -// Returns the full path to the lldb.exe executable +/// Returns the full path to the lldb.exe executable. inline std::wstring GetPathToExecutableW() { - // Iterate until we reach the Windows max path length (32,767). + // Iterate until we reach the Windows API maximum path length (32,767). std::vector buffer; - buffer.resize(MAX_PATH); + buffer.resize(MAX_PATH/*=260*/); while (buffer.size() < 32767) { if (GetModuleFileNameW(NULL, buffer.data(), buffer.size()) < buffer.size()) return std::wstring(buffer.begin(), buffer.end()); @@ -447,9 +447,9 @@ inline std::wstring GetPathToExecutableW() { return L""; } -// Resolve the full path of the directory defined by -// LLDB_PYTHON_DLL_RELATIVE_PATH. If it exists, add it to the list of DLL search -// directories. +/// Resolve the full path of the directory defined by +/// LLDB_PYTHON_DLL_RELATIVE_PATH. If it exists, add it to the list of DLL search +/// directories. void AddPythonDLLToSearchPath() { std::wstring modulePath = GetPathToExecutableW(); if (modulePath.empty()) { From 93c0a4b9b072e2db61e732f0e4adbd3157284bf1 Mon Sep 17 00:00:00 2001 From: Charles Zablit Date: Thu, 9 Oct 2025 10:52:22 +0100 Subject: [PATCH 4/4] fixup! address comments --- lldb/tools/driver/Driver.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp index ad887fc9bc675..325533c85e172 100644 --- a/lldb/tools/driver/Driver.cpp +++ b/lldb/tools/driver/Driver.cpp @@ -438,7 +438,7 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) { inline std::wstring GetPathToExecutableW() { // Iterate until we reach the Windows API maximum path length (32,767). std::vector buffer; - buffer.resize(MAX_PATH/*=260*/); + buffer.resize(MAX_PATH /*=260*/); while (buffer.size() < 32767) { if (GetModuleFileNameW(NULL, buffer.data(), buffer.size()) < buffer.size()) return std::wstring(buffer.begin(), buffer.end()); @@ -448,12 +448,12 @@ inline std::wstring GetPathToExecutableW() { } /// Resolve the full path of the directory defined by -/// LLDB_PYTHON_DLL_RELATIVE_PATH. If it exists, add it to the list of DLL search -/// directories. +/// LLDB_PYTHON_DLL_RELATIVE_PATH. If it exists, add it to the list of DLL +/// search directories. void AddPythonDLLToSearchPath() { std::wstring modulePath = GetPathToExecutableW(); if (modulePath.empty()) { - WithColor::error() << "Unable to find python: " << GetLastError() << '\n'; + llvm::errs() << "error: unable to find python.dll." << '\n'; return; }