[Lldb-commits] [lldb] [lldb-dap][windows] add --check-python command (PR #180784)
Charles Zablit via lldb-commits
lldb-commits at lists.llvm.org
Tue Feb 10 09:22:49 PST 2026
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 <c_zablit at apple.com>
Date: Tue, 10 Feb 2026 17:06:32 +0000
Subject: [PATCH 1/3] [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 <c_zablit at apple.com>
Date: Tue, 10 Feb 2026 17:14:10 +0000
Subject: [PATCH 2/3] 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 <c_zablit at apple.com>
Date: Tue, 10 Feb 2026 17:22:34 +0000
Subject: [PATCH 3/3] 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()
More information about the lldb-commits
mailing list