9#include "lldb/Host/Config.h"
15#include "llvm/ADT/SmallString.h"
16#include "llvm/Support/DynamicLibrary.h"
17#include "llvm/Support/ErrorExtras.h"
18#include "llvm/Support/Path.h"
19#include "llvm/Support/Threading.h"
27#include "llvm/Support/Windows/WindowsSupport.h"
37#ifndef LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
38#define LOAD_LIBRARY_SEARCH_DEFAULT_DIRS 0x00001000
41using SetDefaultDllDirectoriesFn = BOOL(WINAPI *)(DWORD);
42using AddDllDirectoryFn = PVOID(WINAPI *)(PCWSTR);
46void RegisterDllSearchDirectory(llvm::StringRef path) {
47 llvm::StringRef dir = llvm::sys::path::parent_path(path);
53 if (!add_dll_directory)
56 static llvm::once_flag opt_in_once;
57 llvm::call_once(opt_in_once, [] {
59 L
"Kernel32.dll",
"SetDefaultDllDirectories"};
60 if (set_default_dll_directories)
61 (*set_default_dll_directories)(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
64 llvm::SmallVector<wchar_t, MAX_PATH> wide_dir;
65 if (llvm::sys::windows::widenPath(dir, wide_dir))
67 (*add_dll_directory)(wide_dir.data());
75bool IsPythonAlreadyLoaded() {
77 HMODULE main = ::GetModuleHandleW(
nullptr);
78 return ::GetProcAddress(main,
"Py_IsInitialized") !=
nullptr &&
79 ::GetProcAddress(main,
"Py_InitializeFromConfig") !=
nullptr;
81 return ::dlsym(RTLD_DEFAULT,
"Py_IsInitialized") !=
nullptr &&
82 ::dlsym(RTLD_DEFAULT,
"Py_InitializeFromConfig") !=
nullptr;
86llvm::Error TryLoad(
const char *path) {
88 RegisterDllSearchDirectory(path);
91 llvm::sys::DynamicLibrary lib =
92 llvm::sys::DynamicLibrary::getPermanentLibrary(path, &err_msg);
94 return llvm::createStringErrorV(
"could not load '{0}': {1}", path, err_msg);
98 if (!lib.getAddressOfSymbol(
"Py_IsInitialized"))
99 return llvm::createStringErrorV(
100 "'{0}' does not export Py_IsInitialized; not a Python runtime", path);
102 return llvm::Error::success();
105llvm::Expected<std::string> LoadPythonRuntime() {
106 if (IsPythonAlreadyLoaded())
107 return std::string();
109 const char *override_path = std::getenv(
"LLDB_PYTHON_LIBRARY");
110 if (override_path && !*override_path)
111 override_path =
nullptr;
113 llvm::Error failures = llvm::createStringError(
114 override_path ?
"could not locate the Python runtime library"
115 :
"could not locate the Python runtime library, set "
116 "LLDB_PYTHON_LIBRARY to its path");
119 auto try_path = [&](
const char *path) ->
bool {
120 if (llvm::Error err = TryLoad(path)) {
121 failures = llvm::joinErrors(std::move(failures), std::move(err));
128 if (override_path && try_path(override_path)) {
129 consumeError(std::move(failures));
133#ifdef LLDB_PYTHON_RUNTIME_LIBRARY_BUILD_PATH
136 if (try_path(LLDB_PYTHON_RUNTIME_LIBRARY_BUILD_PATH)) {
137 consumeError(std::move(failures));
144 [&](
const char *candidate) {
return found = try_path(candidate); });
147 consumeError(std::move(failures));
150 return std::move(failures);
155 llvm::Error
Load()
override {
157 if (m_error_message.empty())
158 return llvm::Error::success();
159 return llvm::createStringError(m_error_message);
162 llvm::Expected<llvm::StringRef> GetLoadedPath()
override {
164 if (!m_error_message.empty())
165 return llvm::createStringError(m_error_message);
166 return llvm::StringRef(m_path);
169 bool IsLoaded()
override {
return IsPythonAlreadyLoaded(); }
172 void EnsureLoaded() {
173 llvm::call_once(m_once, [
this] {
174 if (llvm::Expected<std::string> result = LoadPythonRuntime()) {
175 m_path = std::move(*result);
182 llvm::SmallString<256> stable_abi_path(m_path);
183 llvm::sys::path::remove_filename(stable_abi_path);
184#if defined(__MINGW32__)
185 llvm::sys::path::append(stable_abi_path,
"libpython3.dll");
187 llvm::sys::path::append(stable_abi_path,
"python3.dll");
190 llvm::sys::DynamicLibrary::getPermanentLibrary(stable_abi_path.c_str(),
194 m_error_message = llvm::toString(result.takeError());
201 llvm::once_flag m_once;
203 std::string m_error_message;
208llvm::Expected<ScriptInterpreterRuntimeLoader &>
212 static PythonRuntimeLoader instance;
218 return llvm::createStringError(
219 "no runtime loader for the requested script language");
221 llvm_unreachable(
"unhandled ScriptLanguage");
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Loads a script-interpreter runtime into the current process before its plugin is dlopened.
static llvm::Expected< ScriptInterpreterRuntimeLoader & > Get(lldb::ScriptLanguage language)
Returns the loader for language.
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
void ForEachPythonRuntimeCandidate(llvm::function_ref< bool(const char *)> callback)
Visits candidate Python runtime paths in priority order, stopping at the first call that returns true...
static std::enable_if_t< is_load< I >, bool > Load(EmulateInstructionRISCV &emulator, I inst, uint64_t(*extend)(E))
ScriptLanguage
Script interpreter types.