Skip to content

Commit 764df35

Browse files
[lldb][windows] delay loading python.dll
1 parent 840bc2a commit 764df35

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed

lldb/cmake/modules/AddLLDB.cmake

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,12 @@ function(add_lldb_executable name)
283283
)
284284

285285
target_link_libraries(${name} PRIVATE ${ARG_LINK_LIBS})
286+
if(WIN32)
287+
list(FIND ARG_LINK_LIBS liblldb LIBLLD_INDEX)
288+
if(NOT LIBLLD_INDEX EQUAL -1)
289+
target_link_options(${name} PRIVATE "/DELAYLOAD:$<TARGET_FILE_BASE_NAME:liblldb>.dll")
290+
endif()
291+
endif()
286292
if(CLANG_LINK_CLANG_DYLIB)
287293
target_link_libraries(${name} PRIVATE clang-cpp)
288294
else()

lldb/tools/driver/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ add_dependencies(lldb
2828
${tablegen_deps}
2929
)
3030

31+
if(DEFINED Python3_VERSION)
32+
target_compile_definitions(lldb PRIVATE Python3_VERSION=${Python3_VERSION})
33+
endif()
34+
3135
if(LLDB_BUILD_FRAMEWORK)
3236
# In the build-tree, we know the exact path to the framework directory.
3337
# The installed framework can be in different locations.

lldb/tools/driver/Driver.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@
2020
#include "lldb/API/SBStructuredData.h"
2121
#include "lldb/Host/Config.h"
2222

23+
#include "llvm/ADT/SmallString.h"
2324
#include "llvm/ADT/StringRef.h"
25+
#include "llvm/Support/ConvertUTF.h"
26+
#include "llvm/Support/FileSystem.h"
2427
#include "llvm/Support/Format.h"
2528
#include "llvm/Support/InitLLVM.h"
2629
#include "llvm/Support/Path.h"
@@ -423,6 +426,64 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) {
423426
return error;
424427
}
425428

429+
#ifdef _WIN32
430+
inline std::wstring GetPathToExecutableW() {
431+
// Iterate until we max out the Windows max path length (256*2^7 > 32,767).
432+
static const size_t maximumIterations = 7;
433+
std::wstring buffer;
434+
DWORD bufferSize = MAX_PATH;
435+
for (size_t i = 0; i < maximumIterations; i++) {
436+
buffer.resize(bufferSize);
437+
DWORD length = GetModuleFileNameW(NULL, &buffer[0], bufferSize);
438+
if (length < buffer.length()) {
439+
buffer.resize(length);
440+
return buffer;
441+
}
442+
bufferSize *= 2;
443+
}
444+
return L"";
445+
}
446+
447+
// Resolve the Embeddable Python directory bundled with the Swift toolchain.
448+
// If it exists, add it to the list of DLL search directories.
449+
// The installation of Embeddable Python is optional when installing the Swift
450+
// toolchain, therefore the directory might not exist.
451+
void AddPythonDLLToSearchPath() {
452+
std::wstring modulePath = GetPathToExecutableW();
453+
if (modulePath.empty()) {
454+
WithColor::error() << "Failed to get module file path. Error: "
455+
<< GetLastError() << "\n";
456+
return;
457+
}
458+
459+
SmallVector<char, MAX_PATH> utf8Path;
460+
if (sys::windows::UTF16ToUTF8(modulePath.c_str(), modulePath.length(),
461+
utf8Path))
462+
return;
463+
464+
SmallString<MAX_PATH> pythonDir(utf8Path.begin(), utf8Path.end());
465+
// Python-${Version} is located in the Swift directory and lldb.exe is in:
466+
// `Swift/Toolchains/x.x.x/usr/bin/lldb.exe`.
467+
for (int i = 0; i < 5; i++) {
468+
sys::path::remove_filename(pythonDir);
469+
}
470+
#define TO_STRING_IMPL(x) #x
471+
#define TO_STRING(x) TO_STRING_IMPL(x)
472+
std::string pythonDirName = "Python-" TO_STRING(Python3_VERSION);
473+
#undef TO_STRING_IMPL
474+
#undef TO_STRING
475+
476+
sys::path::append(pythonDir, pythonDirName);
477+
478+
SmallVector<wchar_t, 1> widePythonDir;
479+
if (sys::windows::UTF8ToUTF16(pythonDir.str(), widePythonDir))
480+
return;
481+
482+
if (sys::fs::exists(pythonDir))
483+
SetDllDirectoryW(widePythonDir.data());
484+
}
485+
#endif
486+
426487
std::string EscapeString(std::string arg) {
427488
std::string::size_type pos = 0;
428489
while ((pos = arg.find_first_of("\"\\", pos)) != std::string::npos) {
@@ -753,6 +814,10 @@ int main(int argc, char const *argv[]) {
753814
"~/Library/Logs/DiagnosticReports/.\n");
754815
#endif
755816

817+
#ifdef _WIN32
818+
AddPythonDLLToSearchPath();
819+
#endif
820+
756821
// Parse arguments.
757822
LLDBOptTable T;
758823
unsigned MissingArgIndex;

0 commit comments

Comments
 (0)