https://github.com/charles-zablit updated https://github.com/llvm/llvm-project/pull/180784
>From 6d3d1f3ef63917549ae730d7887c407fd84c9402 Mon Sep 17 00:00:00 2001 From: Charles Zablit <[email protected]> Date: Tue, 10 Feb 2026 17:06:32 +0000 Subject: [PATCH 1/5] [lldb-dap][windows] add --check-python command --- .../windows/PythonPathSetup/PythonPathSetup.h | 7 +++- .../PythonPathSetup/PythonPathSetup.cpp | 34 ++++++++++++------- lldb/tools/driver/Driver.cpp | 6 ++-- lldb/tools/lldb-dap/tool/Options.td | 4 +++ lldb/tools/lldb-dap/tool/lldb-dap.cpp | 23 ++++++++++--- 5 files changed, 54 insertions(+), 20 deletions(-) diff --git a/lldb/include/lldb/Host/windows/PythonPathSetup/PythonPathSetup.h b/lldb/include/lldb/Host/windows/PythonPathSetup/PythonPathSetup.h index 5016e35304f70..ca46c8b823cd1 100644 --- a/lldb/include/lldb/Host/windows/PythonPathSetup/PythonPathSetup.h +++ b/lldb/include/lldb/Host/windows/PythonPathSetup/PythonPathSetup.h @@ -42,6 +42,11 @@ bool AddPythonDLLToSearchPath(); /// can be loaded. If successful, returns immediately. Otherwise, attempts to /// resolve the relative path and add it to the DLL search path, then checks /// again if python3xx.dll can be loaded. -llvm::Error SetupPythonRuntimeLibrary(); +/// +/// \return If LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME is defined, return the +/// absolute path of the Python shared library which was resolved or an error if +/// it could not be found. If LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME and +/// LLDB_PYTHON_DLL_RELATIVE_PATH are not defined, return an empty string. +llvm::Expected<std::string> SetupPythonRuntimeLibrary(); #endif // LLDB_SOURCE_HOST_PYTHONPATHSETUP_H diff --git a/lldb/source/Host/windows/PythonPathSetup/PythonPathSetup.cpp b/lldb/source/Host/windows/PythonPathSetup/PythonPathSetup.cpp index d378e6984b056..c1c6cac7a9b08 100644 --- a/lldb/source/Host/windows/PythonPathSetup/PythonPathSetup.cpp +++ b/lldb/source/Host/windows/PythonPathSetup/PythonPathSetup.cpp @@ -20,11 +20,10 @@ using namespace llvm; #ifdef LLDB_PYTHON_DLL_RELATIVE_PATH -/// Returns the full path to the lldb.exe executable. -static std::wstring GetPathToExecutableW() { +static std::wstring GetModulePathW(HMODULE module) { std::vector<WCHAR> buffer(MAX_PATH); while (buffer.size() <= PATHCCH_MAX_CCH) { - DWORD len = GetModuleFileNameW(NULL, buffer.data(), buffer.size()); + DWORD len = GetModuleFileNameW(module, buffer.data(), buffer.size()); if (len == 0) return L""; if (len < buffer.size()) @@ -35,6 +34,9 @@ static std::wstring GetPathToExecutableW() { return L""; } +/// Returns the full path to the lldb.exe executable. +static std::wstring GetPathToExecutableW() { return GetModulePathW(NULL); } + bool AddPythonDLLToSearchPath() { std::wstring modulePath = GetPathToExecutableW(); if (modulePath.empty()) @@ -59,26 +61,34 @@ bool AddPythonDLLToSearchPath() { #endif #ifdef LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME -bool IsPythonDLLInPath() { +std::optional<std::string> GetPythonDLLPath() { #define WIDEN2(x) L##x #define WIDEN(x) WIDEN2(x) HMODULE h = LoadLibraryW(WIDEN(LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME)); if (!h) - return false; + return std::nullopt; + + std::wstring path = GetModulePathW(h); FreeLibrary(h); - return true; + + std::string utf8_path; + if (!convertWideToUTF8(path, utf8_path)) + return std::nullopt; + return utf8_path; #undef WIDEN2 #undef WIDEN } #endif -llvm::Error SetupPythonRuntimeLibrary() { +llvm::Expected<std::string> SetupPythonRuntimeLibrary() { #ifdef LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME - if (IsPythonDLLInPath()) - return Error::success(); + if (std::optional<std::string> python_path = GetPythonDLLPath()) + return *python_path; #ifdef LLDB_PYTHON_DLL_RELATIVE_PATH - if (AddPythonDLLToSearchPath() && IsPythonDLLInPath()) - return Error::success(); + if (AddPythonDLLToSearchPath()) { + if (std::optional<std::string> python_path = GetPythonDLLPath()) + return *python_path; + } #endif return createStringError( inconvertibleErrorCode(), @@ -88,5 +98,5 @@ llvm::Error SetupPythonRuntimeLibrary() { return createStringError(inconvertibleErrorCode(), "unable to find the Python runtime library"); #endif - return Error::success(); + return ""; } diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp index 1f333cea9b50d..f0742e13c36f9 100644 --- a/lldb/tools/driver/Driver.cpp +++ b/lldb/tools/driver/Driver.cpp @@ -737,8 +737,10 @@ int main(int argc, char const *argv[]) { #endif #ifdef _WIN32 - if (llvm::Error error = SetupPythonRuntimeLibrary()) - llvm::WithColor::error() << llvm::toString(std::move(error)) << '\n'; + auto python_path_or_err = SetupPythonRuntimeLibrary(); + if (!python_path_or_err) + llvm::WithColor::error() + << llvm::toString(python_path_or_err.takeError()) << '\n'; #endif // Parse arguments. diff --git a/lldb/tools/lldb-dap/tool/Options.td b/lldb/tools/lldb-dap/tool/Options.td index 339a64fed6c32..8f346e9c6eed7 100644 --- a/lldb/tools/lldb-dap/tool/Options.td +++ b/lldb/tools/lldb-dap/tool/Options.td @@ -17,6 +17,10 @@ def: Flag<["-"], "v">, Alias<version>, HelpText<"Alias for --version">; +def check_python : F<"check-python">, + HelpText<"Prints the path to the resolved Python DLL. 0 if " + "Python was not resolved (windows only).">; + def wait_for_debugger: F<"wait-for-debugger">, HelpText<"Pause the program at startup.">; def: Flag<["-"], "g">, diff --git a/lldb/tools/lldb-dap/tool/lldb-dap.cpp b/lldb/tools/lldb-dap/tool/lldb-dap.cpp index bfd7c5d39ec4a..1ead98443c33d 100644 --- a/lldb/tools/lldb-dap/tool/lldb-dap.cpp +++ b/lldb/tools/lldb-dap/tool/lldb-dap.cpp @@ -523,11 +523,6 @@ int main(int argc, char *argv[]) { "~/Library/Logs/DiagnosticReports/.\n"); #endif -#ifdef _WIN32 - if (llvm::Error error = SetupPythonRuntimeLibrary()) - llvm::WithColor::error() << llvm::toString(std::move(error)) << '\n'; -#endif - llvm::SmallString<256> program_path(argv[0]); llvm::sys::fs::make_absolute(program_path); DAP::debug_adapter_path = program_path; @@ -547,6 +542,24 @@ int main(int argc, char *argv[]) { return EXIT_SUCCESS; } + if (input_args.hasArg(OPT_check_python)) { + auto python_path_or_err = SetupPythonRuntimeLibrary(); + if (!python_path_or_err) { + llvm::WithColor::error() + << llvm::toString(python_path_or_err.takeError()) << '\n'; + return EXIT_FAILURE; + } + llvm::outs() << *python_path_or_err << '\n'; + return EXIT_SUCCESS; + } + +#ifdef _WIN32 + auto python_path_or_err = SetupPythonRuntimeLibrary(); + if (!python_path_or_err) + llvm::WithColor::error() + << llvm::toString(python_path_or_err.takeError()) << '\n'; +#endif + if (input_args.hasArg(OPT_client)) { if (llvm::Error error = LaunchClient(input_args)) { llvm::WithColor::error() << llvm::toString(std::move(error)) << '\n'; >From 21bf1ad565fb5ec6e4940174e95ce1c5f2d96e61 Mon Sep 17 00:00:00 2001 From: Charles Zablit <[email protected]> Date: Tue, 10 Feb 2026 17:14:10 +0000 Subject: [PATCH 2/5] use std::string instead of std::wstring --- .../PythonPathSetup/PythonPathSetup.cpp | 46 +++++++++---------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/lldb/source/Host/windows/PythonPathSetup/PythonPathSetup.cpp b/lldb/source/Host/windows/PythonPathSetup/PythonPathSetup.cpp index c1c6cac7a9b08..937977a6851c6 100644 --- a/lldb/source/Host/windows/PythonPathSetup/PythonPathSetup.cpp +++ b/lldb/source/Host/windows/PythonPathSetup/PythonPathSetup.cpp @@ -20,42 +20,43 @@ using namespace llvm; #ifdef LLDB_PYTHON_DLL_RELATIVE_PATH -static std::wstring GetModulePathW(HMODULE module) { +static std::string GetModulePath(HMODULE module) { std::vector<WCHAR> buffer(MAX_PATH); while (buffer.size() <= PATHCCH_MAX_CCH) { DWORD len = GetModuleFileNameW(module, buffer.data(), buffer.size()); if (len == 0) - return L""; - if (len < buffer.size()) - return std::wstring(buffer.data(), len); + return ""; + if (len < buffer.size()) { + std::string buffer_utf8; + if (convertWideToUTF8(std::wstring(buffer.data(), len), buffer_utf8)) + return buffer_utf8; + return ""; + } if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) buffer.resize(buffer.size() * 2); } - return L""; + return ""; } /// Returns the full path to the lldb.exe executable. -static std::wstring GetPathToExecutableW() { return GetModulePathW(NULL); } +static std::string GetPathToExecutable() { return GetModulePath(NULL); } bool AddPythonDLLToSearchPath() { - std::wstring modulePath = GetPathToExecutableW(); - if (modulePath.empty()) + std::string path_str = GetPathToExecutable(); + if (path_str.empty()) return false; - SmallVector<char, MAX_PATH> utf8Path; - if (sys::windows::UTF16ToUTF8(modulePath.c_str(), modulePath.length(), - utf8Path)) - return false; - sys::path::remove_filename(utf8Path); - sys::path::append(utf8Path, LLDB_PYTHON_DLL_RELATIVE_PATH); - sys::fs::make_absolute(utf8Path); + SmallVector<char, MAX_PATH> path(path_str.begin(), path_str.end()); + sys::path::remove_filename(path); + sys::path::append(path, LLDB_PYTHON_DLL_RELATIVE_PATH); + sys::fs::make_absolute(path); - SmallVector<wchar_t, 1> widePath; - if (sys::windows::widenPath(utf8Path.data(), widePath)) + SmallVector<wchar_t, 1> path_wide; + if (sys::windows::widenPath(path.data(), path_wide)) return false; - if (sys::fs::exists(utf8Path)) - return SetDllDirectoryW(widePath.data()); + if (sys::fs::exists(path)) + return SetDllDirectoryW(path_wide.data()); return false; } #endif @@ -68,13 +69,10 @@ std::optional<std::string> GetPythonDLLPath() { if (!h) return std::nullopt; - std::wstring path = GetModulePathW(h); + std::string path = GetModulePath(h); FreeLibrary(h); - std::string utf8_path; - if (!convertWideToUTF8(path, utf8_path)) - return std::nullopt; - return utf8_path; + return path; #undef WIDEN2 #undef WIDEN } >From 3e30a96ccc85a7a9fad66e3c17d536a4ed7301de Mon Sep 17 00:00:00 2001 From: Charles Zablit <[email protected]> Date: Tue, 10 Feb 2026 17:22:34 +0000 Subject: [PATCH 3/5] fixup! [lldb-dap][windows] add --check-python command --- lldb/tools/lldb-dap/tool/lldb-dap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/tools/lldb-dap/tool/lldb-dap.cpp b/lldb/tools/lldb-dap/tool/lldb-dap.cpp index 1ead98443c33d..a764b986d1917 100644 --- a/lldb/tools/lldb-dap/tool/lldb-dap.cpp +++ b/lldb/tools/lldb-dap/tool/lldb-dap.cpp @@ -542,6 +542,7 @@ int main(int argc, char *argv[]) { return EXIT_SUCCESS; } +#ifdef _WIN32 if (input_args.hasArg(OPT_check_python)) { auto python_path_or_err = SetupPythonRuntimeLibrary(); if (!python_path_or_err) { @@ -553,7 +554,6 @@ int main(int argc, char *argv[]) { return EXIT_SUCCESS; } -#ifdef _WIN32 auto python_path_or_err = SetupPythonRuntimeLibrary(); if (!python_path_or_err) llvm::WithColor::error() >From 60424ab8421520e96666673625e531a281b78582 Mon Sep 17 00:00:00 2001 From: Charles Zablit <[email protected]> Date: Wed, 11 Feb 2026 12:44:16 +0100 Subject: [PATCH 4/5] make command description clearer --- lldb/tools/lldb-dap/tool/Options.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lldb/tools/lldb-dap/tool/Options.td b/lldb/tools/lldb-dap/tool/Options.td index 8f346e9c6eed7..f8adef7a19672 100644 --- a/lldb/tools/lldb-dap/tool/Options.td +++ b/lldb/tools/lldb-dap/tool/Options.td @@ -18,8 +18,8 @@ def: Flag<["-"], "v">, HelpText<"Alias for --version">; def check_python : F<"check-python">, - HelpText<"Prints the path to the resolved Python DLL. 0 if " - "Python was not resolved (windows only).">; + HelpText<"Prints the path to the resolved Python DLL. " + "(Windows only).">; def wait_for_debugger: F<"wait-for-debugger">, HelpText<"Pause the program at startup.">; >From a4e3242902b7e1bc00bd5c61130c7ed173934fb7 Mon Sep 17 00:00:00 2001 From: Charles Zablit <[email protected]> Date: Wed, 11 Feb 2026 12:53:30 +0100 Subject: [PATCH 5/5] more explicit error message --- lldb/tools/lldb-dap/tool/lldb-dap.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lldb/tools/lldb-dap/tool/lldb-dap.cpp b/lldb/tools/lldb-dap/tool/lldb-dap.cpp index a764b986d1917..af5c743a5edf1 100644 --- a/lldb/tools/lldb-dap/tool/lldb-dap.cpp +++ b/lldb/tools/lldb-dap/tool/lldb-dap.cpp @@ -550,7 +550,13 @@ int main(int argc, char *argv[]) { << llvm::toString(python_path_or_err.takeError()) << '\n'; return EXIT_FAILURE; } - llvm::outs() << *python_path_or_err << '\n'; + std::string python_path = *python_path_or_err; + if (python_path.empty()) { + llvm::WithColor::error() + << "unable to look for the Python shared library" << '\n'; + return EXIT_FAILURE; + } + llvm::outs() << python_path << '\n'; return EXIT_SUCCESS; } _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
