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"
38bool IsPythonAlreadyLoaded() {
40 HMODULE main = ::GetModuleHandleW(
nullptr);
41 return ::GetProcAddress(main,
"Py_IsInitialized") !=
nullptr &&
42 ::GetProcAddress(main,
"Py_InitializeFromConfig") !=
nullptr;
44 return ::dlsym(RTLD_DEFAULT,
"Py_IsInitialized") !=
nullptr &&
45 ::dlsym(RTLD_DEFAULT,
"Py_InitializeFromConfig") !=
nullptr;
49llvm::Error TryLoad(
const char *path) {
51 llvm::sys::DynamicLibrary lib =
52 llvm::sys::DynamicLibrary::getPermanentLibrary(path, &err_msg);
54 return llvm::createStringErrorV(
"could not load '{0}': {1}", path, err_msg);
58 if (!lib.getAddressOfSymbol(
"Py_IsInitialized"))
59 return llvm::createStringErrorV(
60 "'{0}' does not export Py_IsInitialized; not a Python runtime", path);
62 return llvm::Error::success();
65llvm::Expected<std::string> LoadPythonRuntime() {
66 if (IsPythonAlreadyLoaded())
69 llvm::Error failures =
70 llvm::createStringError(
"could not locate the Python runtime library");
73 auto try_path = [&](
const char *path) ->
bool {
74 if (llvm::Error err = TryLoad(path)) {
75 failures = llvm::joinErrors(std::move(failures), std::move(err));
82 if (
const char *override_path = std::getenv(
"LLDB_PYTHON_LIBRARY");
83 override_path && *override_path) {
84 if (try_path(override_path)) {
85 consumeError(std::move(failures));
90#ifdef LLDB_PYTHON_RUNTIME_LIBRARY_BUILD_PATH
93 if (try_path(LLDB_PYTHON_RUNTIME_LIBRARY_BUILD_PATH)) {
94 consumeError(std::move(failures));
101 [&](
const char *candidate) {
return found = try_path(candidate); });
104 consumeError(std::move(failures));
107 return std::move(failures);
112 llvm::Error
Load()
override {
114 if (m_error_message.empty())
115 return llvm::Error::success();
116 return llvm::createStringError(m_error_message);
119 llvm::Expected<llvm::StringRef> GetLoadedPath()
override {
121 if (!m_error_message.empty())
122 return llvm::createStringError(m_error_message);
123 return llvm::StringRef(m_path);
126 bool IsLoaded()
override {
return IsPythonAlreadyLoaded(); }
129 void EnsureLoaded() {
130 llvm::call_once(m_once, [
this] {
131 if (llvm::Expected<std::string> result = LoadPythonRuntime()) {
132 m_path = std::move(*result);
139 llvm::SmallString<256> stable_abi_path(m_path);
140 llvm::sys::path::remove_filename(stable_abi_path);
141#if defined(__MINGW32__)
142 llvm::sys::path::append(stable_abi_path,
"libpython3.dll");
144 llvm::sys::path::append(stable_abi_path,
"python3.dll");
147 llvm::sys::DynamicLibrary::getPermanentLibrary(stable_abi_path.c_str(),
151 m_error_message = llvm::toString(result.takeError());
158 llvm::once_flag m_once;
160 std::string m_error_message;
165llvm::Expected<ScriptInterpreterRuntimeLoader &>
169 static PythonRuntimeLoader instance;
175 return llvm::createStringError(
176 "no runtime loader for the requested script language");
178 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.