aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-03-20 11:40:34 +0000
committerDimitry Andric <dim@FreeBSD.org>2022-05-14 11:43:05 +0000
commit349cc55c9796c4596a5b9904cd3281af295f878f (patch)
tree410c5a785075730a35f1272ca6a7adf72222ad03 /contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python
parentcb2ae6163174b90e999326ecec3699ee093a5d43 (diff)
parentc0981da47d5696fe36474fcf86b4ce03ae3ff818 (diff)
Diffstat (limited to 'contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python')
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp29
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h12
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp44
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h18
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp285
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h25
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp92
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h151
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp140
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h48
12 files changed, 584 insertions, 273 deletions
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
index f51d9b3a796c..7c71c9329e57 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -998,20 +998,6 @@ bool PythonFile::Check(PyObject *py_obj) {
#endif
}
-namespace {
-class GIL {
-public:
- GIL() {
- m_state = PyGILState_Ensure();
- assert(!PyErr_Occurred());
- }
- ~GIL() { PyGILState_Release(m_state); }
-
-protected:
- PyGILState_STATE m_state;
-};
-} // namespace
-
const char *PythonException::toCString() const {
if (!m_repr_bytes)
return "unknown exception";
@@ -1114,10 +1100,12 @@ GetOptionsForPyObject(const PythonObject &obj) {
auto writable = As<bool>(obj.CallMethod("writable"));
if (!writable)
return writable.takeError();
- if (readable.get())
- options |= File::eOpenOptionRead;
- if (writable.get())
- options |= File::eOpenOptionWrite;
+ if (readable.get() && writable.get())
+ options |= File::eOpenOptionReadWrite;
+ else if (writable.get())
+ options |= File::eOpenOptionWriteOnly;
+ else if (readable.get())
+ options |= File::eOpenOptionReadOnly;
return options;
#else
PythonString py_mode = obj.GetAttributeValue("mode").AsType<PythonString>();
@@ -1413,7 +1401,10 @@ llvm::Expected<FileSP> PythonFile::ConvertToFile(bool borrowed) {
if (!options)
return options.takeError();
- if (options.get() & File::eOpenOptionWrite) {
+ File::OpenOptions rw =
+ options.get() & (File::eOpenOptionReadOnly | File::eOpenOptionWriteOnly |
+ File::eOpenOptionReadWrite);
+ if (rw == File::eOpenOptionWriteOnly || rw == File::eOpenOptionReadWrite) {
// LLDB and python will not share I/O buffers. We should probably
// flush the python buffers now.
auto r = CallMethod("flush");
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
index 4577253227cd..56bc55d239d1 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
@@ -71,6 +71,18 @@ class PythonDictionary;
class PythonInteger;
class PythonException;
+class GIL {
+public:
+ GIL() {
+ m_state = PyGILState_Ensure();
+ assert(!PyErr_Occurred());
+ }
+ ~GIL() { PyGILState_Release(m_state); }
+
+protected:
+ PyGILState_STATE m_state;
+};
+
class StructuredPythonObject : public StructuredData::Generic {
public:
StructuredPythonObject() : StructuredData::Generic() {}
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
index 1ef792bcf303..798d947a0a7d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
@@ -46,9 +46,15 @@ extern "C" void *LLDBSwigPythonCreateScriptedProcess(
const lldb::TargetSP &target_sp, StructuredDataImpl *args_impl,
std::string &error_string);
+extern "C" void *LLDBSwigPythonCreateScriptedThread(
+ const char *python_class_name, const char *session_dictionary_name,
+ const lldb::ProcessSP &process_sp, StructuredDataImpl *args_impl,
+ std::string &error_string);
+
extern "C" void *LLDBSWIGPython_CastPyObjectToSBData(void *data);
extern "C" void *LLDBSWIGPython_CastPyObjectToSBError(void *data);
extern "C" void *LLDBSWIGPython_CastPyObjectToSBValue(void *data);
+extern "C" void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(void *data);
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 7ad63722c31c..c1f4c2d3b4d3 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -355,7 +355,6 @@ private:
PyEval_InitThreads();
}
- TerminalState m_stdin_tty_state;
PyGILState_STATE m_gil_state = PyGILState_UNLOCKED;
bool m_was_already_initialized = false;
};
@@ -411,6 +410,36 @@ FileSpec ScriptInterpreterPython::GetPythonDir() {
return g_spec;
}
+static const char GetInterpreterInfoScript[] = R"(
+import os
+import sys
+
+def main(lldb_python_dir, python_exe_relative_path):
+ info = {
+ "lldb-pythonpath": lldb_python_dir,
+ "language": "python",
+ "prefix": sys.prefix,
+ "executable": os.path.join(sys.prefix, python_exe_relative_path)
+ }
+ return info
+)";
+
+static const char python_exe_relative_path[] = LLDB_PYTHON_EXE_RELATIVE_PATH;
+
+StructuredData::DictionarySP ScriptInterpreterPython::GetInterpreterInfo() {
+ GIL gil;
+ FileSpec python_dir_spec = GetPythonDir();
+ if (!python_dir_spec)
+ return nullptr;
+ PythonScript get_info(GetInterpreterInfoScript);
+ auto info_json = unwrapIgnoringErrors(
+ As<PythonDictionary>(get_info(PythonString(python_dir_spec.GetPath()),
+ PythonString(python_exe_relative_path))));
+ if (!info_json)
+ return nullptr;
+ return info_json.CreateStructuredDictionary();
+}
+
void ScriptInterpreterPython::SharedLibraryDirectoryHelper(
FileSpec &this_file) {
// When we're loaded from python, this_file will point to the file inside the
@@ -437,12 +466,7 @@ void ScriptInterpreterPython::SharedLibraryDirectoryHelper(
#endif
}
-lldb_private::ConstString ScriptInterpreterPython::GetPluginNameStatic() {
- static ConstString g_name("script-python");
- return g_name;
-}
-
-const char *ScriptInterpreterPython::GetPluginDescriptionStatic() {
+llvm::StringRef ScriptInterpreterPython::GetPluginDescriptionStatic() {
return "Embedded Python interpreter";
}
@@ -591,12 +615,6 @@ ScriptInterpreterPythonImpl::~ScriptInterpreterPythonImpl() {
PyGILState_Release(gil_state);
}
-lldb_private::ConstString ScriptInterpreterPythonImpl::GetPluginName() {
- return GetPluginNameStatic();
-}
-
-uint32_t ScriptInterpreterPythonImpl::GetPluginVersion() { return 1; }
-
void ScriptInterpreterPythonImpl::IOHandlerActivated(IOHandler &io_handler,
bool interactive) {
const char *instructions = nullptr;
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
index b8b978118218..8cfc24e71283 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
@@ -13,8 +13,6 @@
#if LLDB_ENABLE_PYTHON
-#include "ScriptedProcessPythonInterface.h"
-
#include "lldb/Breakpoint/BreakpointOptions.h"
#include "lldb/Core/IOHandler.h"
#include "lldb/Core/StructuredDataImpl.h"
@@ -48,10 +46,11 @@ public:
: ScriptInterpreter(debugger, lldb::eScriptLanguagePython),
IOHandlerDelegateMultiline("DONE") {}
+ StructuredData::DictionarySP GetInterpreterInfo() override;
static void Initialize();
static void Terminate();
- static lldb_private::ConstString GetPluginNameStatic();
- static const char *GetPluginDescriptionStatic();
+ static llvm::StringRef GetPluginNameStatic() { return "script-python"; }
+ static llvm::StringRef GetPluginDescriptionStatic();
static FileSpec GetPythonDir();
static void SharedLibraryDirectoryHelper(FileSpec &this_file);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
index d1b0b3fda1ef..a3f83b696ed4 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -292,9 +292,7 @@ public:
static lldb::ScriptInterpreterSP CreateInstance(Debugger &debugger);
// PluginInterface protocol
- lldb_private::ConstString GetPluginName() override;
-
- uint32_t GetPluginVersion() override;
+ llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
class Locker : public ScriptInterpreterLocker {
public:
@@ -432,13 +430,12 @@ public:
int stdin_fd = GetInputFD();
if (stdin_fd >= 0) {
Terminal terminal(stdin_fd);
- TerminalState terminal_state;
- const bool is_a_tty = terminal.IsATerminal();
+ TerminalState terminal_state(terminal);
- if (is_a_tty) {
- terminal_state.Save(stdin_fd, false);
- terminal.SetCanonical(false);
- terminal.SetEcho(true);
+ if (terminal.IsATerminal()) {
+ // FIXME: error handling?
+ llvm::consumeError(terminal.SetCanonical(false));
+ llvm::consumeError(terminal.SetEcho(true));
}
ScriptInterpreterPythonImpl::Locker locker(
@@ -466,9 +463,6 @@ public:
run_string.Printf("run_python_interpreter (%s)",
m_python->GetDictionaryName());
PyRun_SimpleString(run_string.GetData());
-
- if (is_a_tty)
- terminal_state.Restore();
}
}
SetIsDone(true);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
index ce262c930f8b..29680dab5a14 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
@@ -7,6 +7,8 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/Config.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Logging.h"
#include "lldb/lldb-enumerations.h"
#if LLDB_ENABLE_PYTHON
@@ -17,36 +19,40 @@
#include "SWIGPythonBridge.h"
#include "ScriptInterpreterPythonImpl.h"
#include "ScriptedProcessPythonInterface.h"
+#include "ScriptedThreadPythonInterface.h"
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::python;
using Locker = ScriptInterpreterPythonImpl::Locker;
+ScriptedProcessPythonInterface::ScriptedProcessPythonInterface(
+ ScriptInterpreterPythonImpl &interpreter)
+ : ScriptedProcessInterface(), ScriptedPythonInterface(interpreter) {}
+
StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject(
- const llvm::StringRef class_name, lldb::TargetSP target_sp,
+ llvm::StringRef class_name, ExecutionContext &exe_ctx,
StructuredData::DictionarySP args_sp) {
if (class_name.empty())
return {};
- std::string error_string;
+ TargetSP target_sp = exe_ctx.GetTargetSP();
StructuredDataImpl *args_impl = nullptr;
if (args_sp) {
args_impl = new StructuredDataImpl();
args_impl->SetObjectSP(args_sp);
}
+ std::string error_string;
- void *ret_val;
-
- {
+ Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
+ Locker::FreeLock);
- Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
- Locker::FreeLock);
+ void *ret_val = LLDBSwigPythonCreateScriptedProcess(
+ class_name.str().c_str(), m_interpreter.GetDictionaryName(), target_sp,
+ args_impl, error_string);
- ret_val = LLDBSwigPythonCreateScriptedProcess(
- class_name.str().c_str(), m_interpreter.GetDictionaryName(), target_sp,
- args_impl, error_string);
- }
+ if (!ret_val)
+ return {};
m_object_instance_sp =
StructuredData::GenericSP(new StructuredPythonObject(ret_val));
@@ -63,244 +69,101 @@ Status ScriptedProcessPythonInterface::Resume() {
}
bool ScriptedProcessPythonInterface::ShouldStop() {
- llvm::Optional<unsigned long long> should_stop =
- GetGenericInteger("should_stop");
+ Status error;
+ StructuredData::ObjectSP obj = Dispatch("is_alive", error);
- if (!should_stop)
- return false;
+ if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
+ return {};
- return static_cast<bool>(*should_stop);
+ return obj->GetBooleanValue();
}
Status ScriptedProcessPythonInterface::Stop() {
return GetStatusFromMethod("stop");
}
-Status ScriptedProcessPythonInterface::GetStatusFromMethod(
- llvm::StringRef method_name) {
- Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
- Locker::FreeLock);
-
- if (!m_object_instance_sp)
- return Status("Python object ill-formed.");
-
- if (!m_object_instance_sp)
- return Status("Cannot convert Python object to StructuredData::Generic.");
- PythonObject implementor(PyRefType::Borrowed,
- (PyObject *)m_object_instance_sp->GetValue());
-
- if (!implementor.IsAllocated())
- return Status("Python implementor not allocated.");
-
- PythonObject pmeth(
- PyRefType::Owned,
- PyObject_GetAttrString(implementor.get(), method_name.str().c_str()));
-
- if (PyErr_Occurred())
- PyErr_Clear();
-
- if (!pmeth.IsAllocated())
- return Status("Python method not allocated.");
-
- if (PyCallable_Check(pmeth.get()) == 0) {
- if (PyErr_Occurred())
- PyErr_Clear();
- return Status("Python method not callable.");
- }
-
- if (PyErr_Occurred())
- PyErr_Clear();
-
- PythonObject py_return(PyRefType::Owned,
- PyObject_CallMethod(implementor.get(),
- method_name.str().c_str(),
- nullptr));
-
- if (PyErr_Occurred()) {
- PyErr_Print();
- PyErr_Clear();
- return Status("Python method could not be called.");
- }
-
- if (PyObject *py_ret_ptr = py_return.get()) {
- lldb::SBError *sb_error =
- (lldb::SBError *)LLDBSWIGPython_CastPyObjectToSBError(py_ret_ptr);
-
- if (!sb_error)
- return Status("Couldn't cast lldb::SBError to lldb::Status.");
-
- Status status = m_interpreter.GetStatusFromSBError(*sb_error);
-
- if (status.Fail())
- return Status("error: %s", status.AsCString());
+llvm::Optional<MemoryRegionInfo>
+ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress(
+ lldb::addr_t address, Status &error) {
+ auto mem_region = Dispatch<llvm::Optional<MemoryRegionInfo>>(
+ "get_memory_region_containing_address", error, address);
- return status;
+ if (error.Fail()) {
+ return ErrorWithMessage<MemoryRegionInfo>(LLVM_PRETTY_FUNCTION,
+ error.AsCString(), error);
}
- return Status("Returned object is null.");
+ return mem_region;
}
-llvm::Optional<unsigned long long>
-ScriptedProcessPythonInterface::GetGenericInteger(llvm::StringRef method_name) {
- Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
- Locker::FreeLock);
-
- if (!m_object_instance_sp)
- return llvm::None;
-
- if (!m_object_instance_sp)
- return llvm::None;
- PythonObject implementor(PyRefType::Borrowed,
- (PyObject *)m_object_instance_sp->GetValue());
-
- if (!implementor.IsAllocated())
- return llvm::None;
-
- PythonObject pmeth(
- PyRefType::Owned,
- PyObject_GetAttrString(implementor.get(), method_name.str().c_str()));
-
- if (PyErr_Occurred())
- PyErr_Clear();
-
- if (!pmeth.IsAllocated())
- return llvm::None;
-
- if (PyCallable_Check(pmeth.get()) == 0) {
- if (PyErr_Occurred())
- PyErr_Clear();
- return llvm::None;
- }
-
- if (PyErr_Occurred())
- PyErr_Clear();
-
- PythonObject py_return(PyRefType::Owned,
- PyObject_CallMethod(implementor.get(),
- method_name.str().c_str(),
- nullptr));
-
- if (PyErr_Occurred()) {
- PyErr_Print();
- PyErr_Clear();
- }
-
- if (!py_return.get())
- return llvm::None;
+StructuredData::DictionarySP
+ScriptedProcessPythonInterface::GetThreadWithID(lldb::tid_t tid) {
+ Status error;
+ StructuredData::ObjectSP obj = Dispatch("get_thread_with_id", error, tid);
- llvm::Expected<unsigned long long> size = py_return.AsUnsignedLongLong();
- // FIXME: Handle error.
- if (!size)
- return llvm::None;
+ if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
+ return {};
- return *size;
-}
+ StructuredData::DictionarySP dict{obj->GetAsDictionary()};
-lldb::MemoryRegionInfoSP
-ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress(
- lldb::addr_t address) {
- // TODO: Implement
- return nullptr;
-}
-
-StructuredData::DictionarySP
-ScriptedProcessPythonInterface::GetThreadWithID(lldb::tid_t tid) {
- // TODO: Implement
- return nullptr;
+ return dict;
}
StructuredData::DictionarySP
ScriptedProcessPythonInterface::GetRegistersForThread(lldb::tid_t tid) {
// TODO: Implement
- return nullptr;
+ return {};
}
lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress(
lldb::addr_t address, size_t size, Status &error) {
- Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
- Locker::FreeLock);
-
- auto error_with_message = [&error](llvm::StringRef message) {
- error.SetErrorString(message);
- return nullptr;
- };
-
- static char callee_name[] = "read_memory_at_address";
- std::string param_format = GetPythonValueFormatString(address);
- param_format += GetPythonValueFormatString(size);
-
- if (!m_object_instance_sp)
- return error_with_message("Python object ill-formed.");
-
- if (!m_object_instance_sp)
- return error_with_message("Python method not callable.");
-
- PythonObject implementor(PyRefType::Borrowed,
- (PyObject *)m_object_instance_sp->GetValue());
-
- if (!implementor.IsAllocated())
- return error_with_message("Python implementor not allocated.");
-
- PythonObject pmeth(PyRefType::Owned,
- PyObject_GetAttrString(implementor.get(), callee_name));
-
- if (PyErr_Occurred())
- PyErr_Clear();
-
- if (!pmeth.IsAllocated())
- return error_with_message("Python method not allocated.");
-
- if (PyCallable_Check(pmeth.get()) == 0) {
- if (PyErr_Occurred())
- PyErr_Clear();
- return error_with_message("Python method not callable.");
- }
+ return Dispatch<lldb::DataExtractorSP>("read_memory_at_address", error,
+ address, size);
+}
- if (PyErr_Occurred())
- PyErr_Clear();
+StructuredData::DictionarySP ScriptedProcessPythonInterface::GetLoadedImages() {
+ // TODO: Implement
+ return {};
+}
- PythonObject py_return(PyRefType::Owned,
- PyObject_CallMethod(implementor.get(), callee_name,
- param_format.c_str(), address,
- size));
+lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() {
+ Status error;
+ StructuredData::ObjectSP obj = Dispatch("get_process_id", error);
- if (PyErr_Occurred()) {
- PyErr_Print();
- PyErr_Clear();
- return error_with_message("Python method could not be called.");
- }
+ if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
+ return LLDB_INVALID_PROCESS_ID;
- if (PyObject *py_ret_ptr = py_return.get()) {
- lldb::SBData *sb_data =
- (lldb::SBData *)LLDBSWIGPython_CastPyObjectToSBData(py_ret_ptr);
+ return obj->GetIntegerValue(LLDB_INVALID_PROCESS_ID);
+}
- if (!sb_data)
- return error_with_message(
- "Couldn't cast lldb::SBData to lldb::DataExtractor.");
+bool ScriptedProcessPythonInterface::IsAlive() {
+ Status error;
+ StructuredData::ObjectSP obj = Dispatch("is_alive", error);
- return m_interpreter.GetDataExtractorFromSBData(*sb_data);
- }
+ if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
+ return {};
- return error_with_message("Returned object is null.");
+ return obj->GetBooleanValue();
}
-StructuredData::DictionarySP ScriptedProcessPythonInterface::GetLoadedImages() {
- // TODO: Implement
- return nullptr;
-}
+llvm::Optional<std::string>
+ScriptedProcessPythonInterface::GetScriptedThreadPluginName() {
+ Status error;
+ StructuredData::ObjectSP obj = Dispatch("get_scripted_thread_plugin", error);
-lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() {
- llvm::Optional<unsigned long long> pid = GetGenericInteger("get_process_id");
- return (!pid) ? LLDB_INVALID_PROCESS_ID : *pid;
-}
+ if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
+ return {};
-bool ScriptedProcessPythonInterface::IsAlive() {
- llvm::Optional<unsigned long long> is_alive = GetGenericInteger("is_alive");
+ return obj->GetStringValue().str();
+}
- if (!is_alive)
- return false;
+lldb::ScriptedThreadInterfaceSP
+ScriptedProcessPythonInterface::GetScriptedThreadInterface() {
+ if (!m_scripted_thread_interface_sp)
+ m_scripted_thread_interface_sp =
+ std::make_shared<ScriptedThreadPythonInterface>(m_interpreter);
- return static_cast<bool>(*is_alive);
+ return m_scripted_thread_interface_sp;
}
#endif
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
index 30cb5a882af2..421bdd59887c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
@@ -13,17 +13,18 @@
#if LLDB_ENABLE_PYTHON
+#include "ScriptedPythonInterface.h"
#include "lldb/Interpreter/ScriptedProcessInterface.h"
namespace lldb_private {
-class ScriptInterpreterPythonImpl;
-class ScriptedProcessPythonInterface : public ScriptedProcessInterface {
+class ScriptedProcessPythonInterface : public ScriptedProcessInterface,
+ public ScriptedPythonInterface {
public:
- ScriptedProcessPythonInterface(ScriptInterpreterPythonImpl &interpreter)
- : ScriptedProcessInterface(), m_interpreter(interpreter) {}
+ ScriptedProcessPythonInterface(ScriptInterpreterPythonImpl &interpreter);
StructuredData::GenericSP
- CreatePluginObject(const llvm::StringRef class_name, lldb::TargetSP target_sp,
+ CreatePluginObject(const llvm::StringRef class_name,
+ ExecutionContext &exe_ctx,
StructuredData::DictionarySP args_sp) override;
Status Launch() override;
@@ -34,8 +35,9 @@ public:
Status Stop() override;
- lldb::MemoryRegionInfoSP
- GetMemoryRegionContainingAddress(lldb::addr_t address) override;
+ llvm::Optional<MemoryRegionInfo>
+ GetMemoryRegionContainingAddress(lldb::addr_t address,
+ Status &error) override;
StructuredData::DictionarySP GetThreadWithID(lldb::tid_t tid) override;
@@ -50,15 +52,10 @@ public:
bool IsAlive() override;
-protected:
- llvm::Optional<unsigned long long>
- GetGenericInteger(llvm::StringRef method_name);
- Status GetStatusFromMethod(llvm::StringRef method_name);
+ llvm::Optional<std::string> GetScriptedThreadPluginName() override;
private:
- // The lifetime is managed by the ScriptInterpreter
- ScriptInterpreterPythonImpl &m_interpreter;
- StructuredData::GenericSP m_object_instance_sp;
+ lldb::ScriptedThreadInterfaceSP GetScriptedThreadInterface() override;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp
new file mode 100644
index 000000000000..07bf952bf840
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp
@@ -0,0 +1,92 @@
+//===-- ScriptedPythonInterface.cpp ---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/Config.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Logging.h"
+#include "lldb/lldb-enumerations.h"
+
+#if LLDB_ENABLE_PYTHON
+
+// LLDB Python header must be included first
+#include "lldb-python.h"
+
+#include "SWIGPythonBridge.h"
+#include "ScriptInterpreterPythonImpl.h"
+#include "ScriptedPythonInterface.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+ScriptedPythonInterface::ScriptedPythonInterface(
+ ScriptInterpreterPythonImpl &interpreter)
+ : ScriptedInterface(), m_interpreter(interpreter) {}
+
+Status
+ScriptedPythonInterface::GetStatusFromMethod(llvm::StringRef method_name) {
+ Status error;
+ Dispatch<Status>(method_name, error);
+
+ return error;
+}
+
+template <>
+StructuredData::DictionarySP
+ScriptedPythonInterface::ExtractValueFromPythonObject<
+ StructuredData::DictionarySP>(python::PythonObject &p, Status &error) {
+ python::PythonDictionary result_dict(python::PyRefType::Borrowed, p.get());
+ return result_dict.CreateStructuredDictionary();
+}
+
+template <>
+Status ScriptedPythonInterface::ExtractValueFromPythonObject<Status>(
+ python::PythonObject &p, Status &error) {
+ if (lldb::SBError *sb_error = reinterpret_cast<lldb::SBError *>(
+ LLDBSWIGPython_CastPyObjectToSBError(p.get())))
+ error = m_interpreter.GetStatusFromSBError(*sb_error);
+ else
+ error.SetErrorString("Couldn't cast lldb::SBError to lldb::Status.");
+
+ return error;
+}
+
+template <>
+lldb::DataExtractorSP
+ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::DataExtractorSP>(
+ python::PythonObject &p, Status &error) {
+ lldb::SBData *sb_data = reinterpret_cast<lldb::SBData *>(
+ LLDBSWIGPython_CastPyObjectToSBData(p.get()));
+
+ if (!sb_data) {
+ error.SetErrorString(
+ "Couldn't cast lldb::SBData to lldb::DataExtractorSP.");
+ return nullptr;
+ }
+
+ return m_interpreter.GetDataExtractorFromSBData(*sb_data);
+}
+
+template <>
+llvm::Optional<MemoryRegionInfo>
+ScriptedPythonInterface::ExtractValueFromPythonObject<
+ llvm::Optional<MemoryRegionInfo>>(python::PythonObject &p, Status &error) {
+
+ lldb::SBMemoryRegionInfo *sb_mem_reg_info =
+ reinterpret_cast<lldb::SBMemoryRegionInfo *>(
+ LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(p.get()));
+
+ if (!sb_mem_reg_info) {
+ error.SetErrorString(
+ "Couldn't cast lldb::SBMemoryRegionInfo to lldb::MemoryRegionInfoSP.");
+ return {};
+ }
+
+ return m_interpreter.GetOpaqueTypeFromSBMemoryRegionInfo(*sb_mem_reg_info);
+}
+
+#endif
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
new file mode 100644
index 000000000000..da112eb72022
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
@@ -0,0 +1,151 @@
+//===-- ScriptedPythonInterface.h -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPYTHONINTERFACE_H
+#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPYTHONINTERFACE_H
+
+#include "lldb/Host/Config.h"
+
+#if LLDB_ENABLE_PYTHON
+
+#include "lldb/Interpreter/ScriptedInterface.h"
+#include "lldb/Utility/DataBufferHeap.h"
+
+#include "PythonDataObjects.h"
+#include "SWIGPythonBridge.h"
+#include "ScriptInterpreterPythonImpl.h"
+
+namespace lldb_private {
+class ScriptInterpreterPythonImpl;
+class ScriptedPythonInterface : virtual public ScriptedInterface {
+public:
+ ScriptedPythonInterface(ScriptInterpreterPythonImpl &interpreter);
+ virtual ~ScriptedPythonInterface() = default;
+
+protected:
+ template <typename T = StructuredData::ObjectSP>
+ T ExtractValueFromPythonObject(python::PythonObject &p, Status &error) {
+ return p.CreateStructuredObject();
+ }
+
+ template <typename T = StructuredData::ObjectSP, typename... Args>
+ T Dispatch(llvm::StringRef method_name, Status &error, Args... args) {
+ using namespace python;
+ using Locker = ScriptInterpreterPythonImpl::Locker;
+
+ std::string caller_signature =
+ llvm::Twine(LLVM_PRETTY_FUNCTION + llvm::Twine(" (") +
+ llvm::Twine(method_name) + llvm::Twine(")"))
+ .str();
+ if (!m_object_instance_sp)
+ return ErrorWithMessage<T>(caller_signature, "Python object ill-formed",
+ error);
+
+ Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
+ Locker::FreeLock);
+
+ PythonObject implementor(PyRefType::Borrowed,
+ (PyObject *)m_object_instance_sp->GetValue());
+
+ if (!implementor.IsAllocated())
+ return ErrorWithMessage<T>(caller_signature,
+ "Python implementor not allocated.", error);
+
+ PythonObject pmeth(
+ PyRefType::Owned,
+ PyObject_GetAttrString(implementor.get(), method_name.str().c_str()));
+
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ if (!pmeth.IsAllocated())
+ return ErrorWithMessage<T>(caller_signature,
+ "Python method not allocated.", error);
+
+ if (PyCallable_Check(pmeth.get()) == 0) {
+ if (PyErr_Occurred())
+ PyErr_Clear();
+ return ErrorWithMessage<T>(caller_signature,
+ "Python method not callable.", error);
+ }
+
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ // TODO: make `const char *` when removing support for Python 2.
+ char *format = nullptr;
+ std::string format_buffer;
+
+ if (sizeof...(Args) > 0) {
+ FormatArgs(format_buffer, args...);
+ // TODO: make `const char *` when removing support for Python 2.
+ format = const_cast<char *>(format_buffer.c_str());
+ }
+
+ // TODO: make `const char *` when removing support for Python 2.
+ PythonObject py_return(
+ PyRefType::Owned,
+ PyObject_CallMethod(implementor.get(),
+ const_cast<char *>(method_name.data()), format,
+ args...));
+
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ PyErr_Clear();
+ return ErrorWithMessage<T>(caller_signature,
+ "Python method could not be called.", error);
+ }
+
+ if (!py_return.IsAllocated())
+ return ErrorWithMessage<T>(caller_signature, "Returned object is null.",
+ error);
+
+ return ExtractValueFromPythonObject<T>(py_return, error);
+ }
+
+ Status GetStatusFromMethod(llvm::StringRef method_name);
+
+ template <typename T, typename... Args>
+ void FormatArgs(std::string &fmt, T arg, Args... args) const {
+ FormatArgs(fmt, arg);
+ FormatArgs(fmt, args...);
+ }
+
+ template <typename T> void FormatArgs(std::string &fmt, T arg) const {
+ fmt += GetPythonValueFormatString(arg);
+ }
+
+ void FormatArgs(std::string &fmt) const {}
+
+ // The lifetime is managed by the ScriptInterpreter
+ ScriptInterpreterPythonImpl &m_interpreter;
+};
+
+template <>
+StructuredData::DictionarySP
+ScriptedPythonInterface::ExtractValueFromPythonObject<
+ StructuredData::DictionarySP>(python::PythonObject &p, Status &error);
+
+template <>
+Status ScriptedPythonInterface::ExtractValueFromPythonObject<Status>(
+ python::PythonObject &p, Status &error);
+
+template <>
+lldb::DataExtractorSP
+ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::DataExtractorSP>(
+ python::PythonObject &p, Status &error);
+
+template <>
+llvm::Optional<MemoryRegionInfo>
+ScriptedPythonInterface::ExtractValueFromPythonObject<
+ llvm::Optional<MemoryRegionInfo>>(python::PythonObject &p, Status &error);
+
+} // namespace lldb_private
+
+#endif // LLDB_ENABLE_PYTHON
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPYTHONINTERFACE_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
new file mode 100644
index 000000000000..d2c28bc426ee
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
@@ -0,0 +1,140 @@
+//===-- ScriptedThreadPythonInterface.cpp ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/Config.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Logging.h"
+#include "lldb/lldb-enumerations.h"
+
+#if LLDB_ENABLE_PYTHON
+
+// LLDB Python header must be included first
+#include "lldb-python.h"
+
+#include "SWIGPythonBridge.h"
+#include "ScriptInterpreterPythonImpl.h"
+#include "ScriptedThreadPythonInterface.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::python;
+using Locker = ScriptInterpreterPythonImpl::Locker;
+
+ScriptedThreadPythonInterface::ScriptedThreadPythonInterface(
+ ScriptInterpreterPythonImpl &interpreter)
+ : ScriptedThreadInterface(), ScriptedPythonInterface(interpreter) {}
+
+StructuredData::GenericSP ScriptedThreadPythonInterface::CreatePluginObject(
+ const llvm::StringRef class_name, ExecutionContext &exe_ctx,
+ StructuredData::DictionarySP args_sp) {
+
+ if (class_name.empty())
+ return {};
+
+ ProcessSP process_sp = exe_ctx.GetProcessSP();
+ StructuredDataImpl *args_impl = nullptr;
+ if (args_sp) {
+ args_impl = new StructuredDataImpl();
+ args_impl->SetObjectSP(args_sp);
+ }
+ std::string error_string;
+
+ Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
+ Locker::FreeLock);
+
+ void *ret_val = LLDBSwigPythonCreateScriptedThread(
+ class_name.str().c_str(), m_interpreter.GetDictionaryName(), process_sp,
+ args_impl, error_string);
+
+ if (!ret_val)
+ return {};
+
+ m_object_instance_sp =
+ StructuredData::GenericSP(new StructuredPythonObject(ret_val));
+
+ return m_object_instance_sp;
+}
+
+lldb::tid_t ScriptedThreadPythonInterface::GetThreadID() {
+ Status error;
+ StructuredData::ObjectSP obj = Dispatch("get_thread_id", error);
+
+ if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
+ return LLDB_INVALID_THREAD_ID;
+
+ return obj->GetIntegerValue(LLDB_INVALID_THREAD_ID);
+}
+
+llvm::Optional<std::string> ScriptedThreadPythonInterface::GetName() {
+ Status error;
+ StructuredData::ObjectSP obj = Dispatch("get_name", error);
+
+ if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
+ return {};
+
+ return obj->GetStringValue().str();
+}
+
+lldb::StateType ScriptedThreadPythonInterface::GetState() {
+ Status error;
+ StructuredData::ObjectSP obj = Dispatch("get_state", error);
+
+ if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
+ return eStateInvalid;
+
+ return static_cast<StateType>(obj->GetIntegerValue(eStateInvalid));
+}
+
+llvm::Optional<std::string> ScriptedThreadPythonInterface::GetQueue() {
+ Status error;
+ StructuredData::ObjectSP obj = Dispatch("get_queue", error);
+
+ if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
+ return {};
+
+ return obj->GetStringValue().str();
+}
+
+StructuredData::DictionarySP ScriptedThreadPythonInterface::GetStopReason() {
+ Status error;
+ StructuredData::DictionarySP dict =
+ Dispatch<StructuredData::DictionarySP>("get_stop_reason", error);
+
+ if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
+ return {};
+
+ return dict;
+}
+
+StructuredData::ArraySP ScriptedThreadPythonInterface::GetStackFrames() {
+ return nullptr;
+}
+
+StructuredData::DictionarySP ScriptedThreadPythonInterface::GetRegisterInfo() {
+ Status error;
+ StructuredData::DictionarySP dict =
+ Dispatch<StructuredData::DictionarySP>("get_register_info", error);
+
+ if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
+ return {};
+
+ return dict;
+}
+
+llvm::Optional<std::string>
+ScriptedThreadPythonInterface::GetRegisterContext() {
+ Status error;
+ StructuredData::ObjectSP obj = Dispatch("get_register_context", error);
+
+ if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
+ return {};
+
+ return obj->GetAsString()->GetValue().str();
+}
+
+#endif
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h
new file mode 100644
index 000000000000..996b8d43136b
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h
@@ -0,0 +1,48 @@
+//===-- ScriptedThreadPythonInterface.h ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDTHREADPYTHONINTERFACE_H
+#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDTHREADPYTHONINTERFACE_H
+
+#include "lldb/Host/Config.h"
+
+#if LLDB_ENABLE_PYTHON
+
+#include "ScriptedPythonInterface.h"
+#include "lldb/Interpreter/ScriptedProcessInterface.h"
+
+namespace lldb_private {
+class ScriptedThreadPythonInterface : public ScriptedThreadInterface,
+ public ScriptedPythonInterface {
+public:
+ ScriptedThreadPythonInterface(ScriptInterpreterPythonImpl &interpreter);
+
+ StructuredData::GenericSP
+ CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx,
+ StructuredData::DictionarySP args_sp) override;
+
+ lldb::tid_t GetThreadID() override;
+
+ llvm::Optional<std::string> GetName() override;
+
+ lldb::StateType GetState() override;
+
+ llvm::Optional<std::string> GetQueue() override;
+
+ StructuredData::DictionarySP GetStopReason() override;
+
+ StructuredData::ArraySP GetStackFrames() override;
+
+ StructuredData::DictionarySP GetRegisterInfo() override;
+
+ llvm::Optional<std::string> GetRegisterContext() override;
+};
+} // namespace lldb_private
+
+#endif // LLDB_ENABLE_PYTHON
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPROCESSTHREADINTERFACE_H