-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[lldb][windows] print an error if python.dll is not in the DLL search path #164893
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3d2976b
d502ba9
c73bf5f
71178bb
6071b08
855a405
6ee7fce
8b34fea
2bde6e8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -433,7 +433,8 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) { | |
| return error; | ||
| } | ||
|
|
||
| #if defined(_WIN32) && defined(LLDB_PYTHON_DLL_RELATIVE_PATH) | ||
| #ifdef _WIN32 | ||
| #ifdef LLDB_PYTHON_DLL_RELATIVE_PATH | ||
| /// Returns the full path to the lldb.exe executable. | ||
| inline std::wstring GetPathToExecutableW() { | ||
| // Iterate until we reach the Windows API maximum path length (32,767). | ||
|
|
@@ -447,30 +448,73 @@ inline std::wstring GetPathToExecutableW() { | |
| return L""; | ||
| } | ||
|
|
||
| /// Resolve the full path of the directory defined by | ||
| /// \brief 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() { | ||
| /// \return `true` if the library was added to the search path. | ||
| /// `false` otherwise. | ||
| bool AddPythonDLLToSearchPath() { | ||
| std::wstring modulePath = GetPathToExecutableW(); | ||
| if (modulePath.empty()) { | ||
| llvm::errs() << "error: unable to find python.dll." << '\n'; | ||
| return; | ||
| } | ||
| if (modulePath.empty()) | ||
| return false; | ||
|
|
||
| SmallVector<char, MAX_PATH> utf8Path; | ||
| if (sys::windows::UTF16ToUTF8(modulePath.c_str(), modulePath.length(), | ||
| utf8Path)) | ||
| return; | ||
| return false; | ||
| sys::path::remove_filename(utf8Path); | ||
| sys::path::append(utf8Path, LLDB_PYTHON_DLL_RELATIVE_PATH); | ||
| sys::fs::make_absolute(utf8Path); | ||
|
|
||
| SmallVector<wchar_t, 1> widePath; | ||
| if (sys::windows::widenPath(utf8Path.data(), widePath)) | ||
| return; | ||
| return false; | ||
|
|
||
| if (sys::fs::exists(utf8Path)) | ||
| SetDllDirectoryW(widePath.data()); | ||
| return SetDllDirectoryW(widePath.data()); | ||
| return false; | ||
| } | ||
| #endif | ||
|
|
||
| #ifdef LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME | ||
| /// Returns whether `python3x.dll` is in the DLL search path. | ||
| bool IsPythonDLLInPath() { | ||
| #define WIDEN2(x) L##x | ||
| #define WIDEN(x) WIDEN2(x) | ||
| WCHAR foundPath[MAX_PATH]; | ||
| DWORD result = | ||
| SearchPathW(nullptr, WIDEN(LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME), nullptr, | ||
| MAX_PATH, foundPath, nullptr); | ||
| #undef WIDEN2 | ||
| #undef WIDEN | ||
|
|
||
| return result > 0; | ||
| } | ||
| #endif | ||
|
|
||
| /// Try to setup the DLL search path for the Python Runtime Library | ||
| /// (python3xx.dll). | ||
| /// | ||
| /// If `LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME` is set, we first check if | ||
| /// python3xx.dll is in the search path. If it's not, we try to add it and | ||
| /// check for it a second time. | ||
| /// If only `LLDB_PYTHON_DLL_RELATIVE_PATH` is set, we try to add python3xx.dll | ||
| /// to the search path python.dll is already in the search path or not. | ||
| void SetupPythonRuntimeLibrary() { | ||
| #ifdef LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME | ||
| if (IsPythonDLLInPath()) | ||
| return; | ||
| #ifdef LLDB_PYTHON_DLL_RELATIVE_PATH | ||
| if (AddPythonDLLToSearchPath() && IsPythonDLLInPath()) | ||
| return; | ||
| #endif | ||
| llvm::errs() << "error: unable to find '" | ||
| << LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME << "'.\n"; | ||
| return; | ||
| #elif defined(LLDB_PYTHON_DLL_RELATIVE_PATH) | ||
| if (!AddPythonDLLToSearchPath()) | ||
| llvm::errs() << "error: unable to find the Python runtime library.\n"; | ||
| #endif | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that we can merge the two paths and just conditionally emit the diagnostic, the handling feels identical otherwise. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My reasoning for keeping the two paths separate is to make sure the installed Python's dll takes precedence over the one we might bundle in the installer (
compnerd marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| #endif | ||
|
|
||
|
|
@@ -776,8 +820,8 @@ int main(int argc, char const *argv[]) { | |
| "~/Library/Logs/DiagnosticReports/.\n"); | ||
| #endif | ||
|
|
||
| #if defined(_WIN32) && defined(LLDB_PYTHON_DLL_RELATIVE_PATH) | ||
| AddPythonDLLToSearchPath(); | ||
| #ifdef _WIN32 | ||
| SetupPythonRuntimeLibrary(); | ||
| #endif | ||
|
|
||
| // Parse arguments. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In an earlier revision of this PR, we did a second
IsPythonDLLInPath()check after a successfulAddPythonDLLToSearchPath()- even though we did add a path, we don't still really know if it does contain the DLL we want or not.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added another call to
IsPythonDLLInPathafter a successfulAddPythonDLLToSearchPath👍