aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python')
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h36
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.cpp48
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h101
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp316
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.cpp108
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.h44
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp40
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp17
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h152
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp32
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h9
15 files changed, 514 insertions, 406 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 ae61736fbbb3..22918561692c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -20,7 +20,6 @@
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Stream.h"
-#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Errno.h"
@@ -923,7 +922,7 @@ const char *PythonException::toCString() const {
PythonException::PythonException(const char *caller) {
assert(PyErr_Occurred());
- m_exception_type = m_exception = m_traceback = m_repr_bytes = NULL;
+ m_exception_type = m_exception = m_traceback = m_repr_bytes = nullptr;
PyErr_Fetch(&m_exception_type, &m_exception, &m_traceback);
PyErr_NormalizeException(&m_exception_type, &m_exception, &m_traceback);
PyErr_Clear();
@@ -951,7 +950,7 @@ void PythonException::Restore() {
} else {
PyErr_SetString(PyExc_Exception, toCString());
}
- m_exception_type = m_exception = m_traceback = NULL;
+ m_exception_type = m_exception = m_traceback = nullptr;
}
PythonException::~PythonException() {
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 76ad47f2907e..365d499bead8 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
@@ -185,22 +185,34 @@ inline const char *py2_const_cast(const char *s) { return s; }
enum class PyInitialValue { Invalid, Empty };
+// DOC: https://docs.python.org/3/c-api/arg.html#building-values
template <typename T, typename Enable = void> struct PythonFormat;
-template <> struct PythonFormat<unsigned long long> {
- static constexpr char format = 'K';
- static auto get(unsigned long long value) { return value; }
+template <typename T, char F> struct PassthroughFormat {
+ static constexpr char format = F;
+ static constexpr T get(T t) { return t; }
};
-template <> struct PythonFormat<long long> {
- static constexpr char format = 'L';
- static auto get(long long value) { return value; }
-};
-
-template <> struct PythonFormat<PyObject *> {
- static constexpr char format = 'O';
- static auto get(PyObject *value) { return value; }
-};
+template <> struct PythonFormat<char *> : PassthroughFormat<char *, 's'> {};
+template <> struct PythonFormat<char> : PassthroughFormat<char, 'b'> {};
+template <>
+struct PythonFormat<unsigned char> : PassthroughFormat<unsigned char, 'B'> {};
+template <> struct PythonFormat<short> : PassthroughFormat<short, 'h'> {};
+template <>
+struct PythonFormat<unsigned short> : PassthroughFormat<unsigned short, 'H'> {};
+template <> struct PythonFormat<int> : PassthroughFormat<int, 'i'> {};
+template <>
+struct PythonFormat<unsigned int> : PassthroughFormat<unsigned int, 'I'> {};
+template <> struct PythonFormat<long> : PassthroughFormat<long, 'l'> {};
+template <>
+struct PythonFormat<unsigned long> : PassthroughFormat<unsigned long, 'k'> {};
+template <>
+struct PythonFormat<long long> : PassthroughFormat<long long, 'L'> {};
+template <>
+struct PythonFormat<unsigned long long>
+ : PassthroughFormat<unsigned long long, 'K'> {};
+template <>
+struct PythonFormat<PyObject *> : PassthroughFormat<PyObject *, 'O'> {};
template <typename T>
struct PythonFormat<
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp
index 2753847f39f8..3cbd3b5efecc 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp
@@ -40,7 +40,7 @@ static char *simple_readline(FILE *stdin, FILE *stdout, const char *prompt) {
char *line = readline(prompt);
if (!line) {
char *ret = (char *)PyMem_RawMalloc(1);
- if (ret != NULL)
+ if (ret != nullptr)
*ret = '\0';
return ret;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.cpp
deleted file mode 100644
index 7c7c5d73680a..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-//===-- SWIGPythonBridge.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/lldb-enumerations.h"
-
-#if LLDB_ENABLE_PYTHON
-
-// LLDB Python header must be included first
-#include "lldb-python.h"
-
-#include "SWIGPythonBridge.h"
-
-using namespace lldb;
-
-namespace lldb_private {
-
-template <typename T> const char *GetPythonValueFormatString(T t);
-template <> const char *GetPythonValueFormatString(char *) { return "s"; }
-template <> const char *GetPythonValueFormatString(char) { return "b"; }
-template <> const char *GetPythonValueFormatString(unsigned char) {
- return "B";
-}
-template <> const char *GetPythonValueFormatString(short) { return "h"; }
-template <> const char *GetPythonValueFormatString(unsigned short) {
- return "H";
-}
-template <> const char *GetPythonValueFormatString(int) { return "i"; }
-template <> const char *GetPythonValueFormatString(unsigned int) { return "I"; }
-template <> const char *GetPythonValueFormatString(long) { return "l"; }
-template <> const char *GetPythonValueFormatString(unsigned long) {
- return "k";
-}
-template <> const char *GetPythonValueFormatString(long long) { return "L"; }
-template <> const char *GetPythonValueFormatString(unsigned long long) {
- return "K";
-}
-template <> const char *GetPythonValueFormatString(float) { return "f"; }
-template <> const char *GetPythonValueFormatString(double) { return "d"; }
-
-} // namespace lldb_private
-
-#endif // LLDB_ENABLE_PYTHON
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 4df235356737..3dc2864f8d42 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
@@ -9,6 +9,7 @@
#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H
#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H
+#include <optional>
#include <string>
#include "lldb/Host/Config.h"
@@ -23,28 +24,68 @@
#include "lldb/lldb-types.h"
#include "llvm/Support/Error.h"
-namespace lldb_private {
+namespace lldb {
+class SBEvent;
+class SBCommandReturnObject;
+class SBValue;
+class SBStream;
+class SBStructuredData;
+} // namespace lldb
-// GetPythonValueFormatString provides a system independent type safe way to
-// convert a variable's type into a python value format. Python value formats
-// are defined in terms of builtin C types and could change from system to as
-// the underlying typedef for uint* types, size_t, off_t and other values
-// change.
-
-template <typename T> const char *GetPythonValueFormatString(T t);
-template <> const char *GetPythonValueFormatString(char *);
-template <> const char *GetPythonValueFormatString(char);
-template <> const char *GetPythonValueFormatString(unsigned char);
-template <> const char *GetPythonValueFormatString(short);
-template <> const char *GetPythonValueFormatString(unsigned short);
-template <> const char *GetPythonValueFormatString(int);
-template <> const char *GetPythonValueFormatString(unsigned int);
-template <> const char *GetPythonValueFormatString(long);
-template <> const char *GetPythonValueFormatString(unsigned long);
-template <> const char *GetPythonValueFormatString(long long);
-template <> const char *GetPythonValueFormatString(unsigned long long);
-template <> const char *GetPythonValueFormatString(float t);
-template <> const char *GetPythonValueFormatString(double t);
+namespace lldb_private {
+namespace python {
+
+typedef struct swig_type_info swig_type_info;
+
+python::PythonObject ToSWIGHelper(void *obj, swig_type_info *info);
+
+/// A class that automatically clears an SB object when it goes out of scope.
+/// Use for cases where the SB object points to a temporary/unowned entity.
+template <typename T> class ScopedPythonObject : PythonObject {
+public:
+ ScopedPythonObject(T *sb, swig_type_info *info)
+ : PythonObject(ToSWIGHelper(sb, info)), m_sb(sb) {}
+ ~ScopedPythonObject() {
+ if (m_sb)
+ *m_sb = T();
+ }
+ ScopedPythonObject(ScopedPythonObject &&rhs)
+ : PythonObject(std::move(rhs)), m_sb(std::exchange(rhs.m_sb, nullptr)) {}
+ ScopedPythonObject(const ScopedPythonObject &) = delete;
+ ScopedPythonObject &operator=(const ScopedPythonObject &) = delete;
+ ScopedPythonObject &operator=(ScopedPythonObject &&) = delete;
+
+ const PythonObject &obj() const { return *this; }
+
+private:
+ T *m_sb;
+};
+
+PythonObject ToSWIGWrapper(lldb::ValueObjectSP value_sp);
+PythonObject ToSWIGWrapper(lldb::TargetSP target_sp);
+PythonObject ToSWIGWrapper(lldb::ProcessSP process_sp);
+PythonObject ToSWIGWrapper(lldb::ThreadPlanSP thread_plan_sp);
+PythonObject ToSWIGWrapper(lldb::BreakpointSP breakpoint_sp);
+PythonObject ToSWIGWrapper(const Status &status);
+PythonObject ToSWIGWrapper(const StructuredDataImpl &data_impl);
+PythonObject ToSWIGWrapper(lldb::ThreadSP thread_sp);
+PythonObject ToSWIGWrapper(lldb::StackFrameSP frame_sp);
+PythonObject ToSWIGWrapper(lldb::DebuggerSP debugger_sp);
+PythonObject ToSWIGWrapper(lldb::WatchpointSP watchpoint_sp);
+PythonObject ToSWIGWrapper(lldb::BreakpointLocationSP bp_loc_sp);
+PythonObject ToSWIGWrapper(lldb::ExecutionContextRefSP ctx_sp);
+PythonObject ToSWIGWrapper(const TypeSummaryOptions &summary_options);
+PythonObject ToSWIGWrapper(const SymbolContext &sym_ctx);
+
+PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBValue> value_sb);
+PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBStream> stream_sb);
+PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb);
+
+python::ScopedPythonObject<lldb::SBCommandReturnObject>
+ToSWIGWrapper(CommandReturnObject &cmd_retobj);
+python::ScopedPythonObject<lldb::SBEvent> ToSWIGWrapper(Event *event);
+
+} // namespace python
void *LLDBSWIGPython_CastPyObjectToSBData(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data);
@@ -55,14 +96,10 @@ void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data);
// Although these are scripting-language specific, their definition depends on
// the public API.
-python::PythonObject LLDBSwigPythonCreateScriptedProcess(
+python::PythonObject LLDBSwigPythonCreateScriptedObject(
const char *python_class_name, const char *session_dictionary_name,
- const lldb::TargetSP &target_sp, const StructuredDataImpl &args_impl,
- std::string &error_string);
-
-python::PythonObject LLDBSwigPythonCreateScriptedThread(
- const char *python_class_name, const char *session_dictionary_name,
- const lldb::ProcessSP &process_sp, const StructuredDataImpl &args_impl,
+ lldb::ExecutionContextRefSP exe_ctx_sp,
+ const lldb_private::StructuredDataImpl &args_impl,
std::string &error_string);
llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction(
@@ -75,6 +112,10 @@ bool LLDBSwigPythonWatchpointCallbackFunction(
const char *python_function_name, const char *session_dictionary_name,
const lldb::StackFrameSP &sb_frame, const lldb::WatchpointSP &sb_wp);
+bool LLDBSwigPythonFormatterCallbackFunction(
+ const char *python_function_name, const char *session_dictionary_name,
+ lldb::TypeImplSP type_impl_sp);
+
bool LLDBSwigPythonCallTypeScript(const char *python_function_name,
const void *session_dictionary,
const lldb::ValueObjectSP &valobj_sp,
@@ -167,7 +208,7 @@ bool LLDBSWIGPythonRunScriptKeywordProcess(const char *python_function_name,
const lldb::ProcessSP &process,
std::string &output);
-llvm::Optional<std::string>
+std::optional<std::string>
LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name,
const char *session_dictionary_name,
lldb::ThreadSP thread);
@@ -177,7 +218,7 @@ bool LLDBSWIGPythonRunScriptKeywordTarget(const char *python_function_name,
const lldb::TargetSP &target,
std::string &output);
-llvm::Optional<std::string>
+std::optional<std::string>
LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name,
const char *session_dictionary_name,
lldb::StackFrameSP frame);
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 a21adcfbdbd6..7026815e120d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -18,6 +18,7 @@
#include "PythonReadline.h"
#include "SWIGPythonBridge.h"
#include "ScriptInterpreterPythonImpl.h"
+#include "ScriptedPlatformPythonInterface.h"
#include "ScriptedProcessPythonInterface.h"
#include "lldb/API/SBError.h"
@@ -25,9 +26,9 @@
#include "lldb/API/SBValue.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Breakpoint/WatchpointOptions.h"
-#include "lldb/Core/Communication.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/ThreadedCommunication.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/TypeSummary.h"
#include "lldb/Host/FileSystem.h"
@@ -50,6 +51,7 @@
#include <cstdlib>
#include <memory>
#include <mutex>
+#include <optional>
#include <string>
using namespace lldb;
@@ -96,7 +98,7 @@ public:
// Python's readline is incompatible with libedit being linked into lldb.
// Provide a patched version local to the embedded interpreter.
bool ReadlinePatched = false;
- for (auto *p = PyImport_Inittab; p->name != NULL; p++) {
+ for (auto *p = PyImport_Inittab; p->name != nullptr; p++) {
if (strcmp(p->name, "readline") == 0) {
p->initfunc = initlldb_readline;
break;
@@ -241,7 +243,7 @@ void ScriptInterpreterPython::ComputePythonDir(
llvm::sys::path::append(path, LLDB_PYTHON_RELATIVE_LIBDIR);
#if defined(_WIN32)
- // This will be injected directly through FileSpec.GetDirectory().SetString(),
+ // This will be injected directly through FileSpec.SetDirectory(),
// so we need to normalize manually.
std::replace(path.begin(), path.end(), '\\', '/');
#endif
@@ -260,7 +262,7 @@ FileSpec ScriptInterpreterPython::GetPythonDir() {
#else
ComputePythonDir(path);
#endif
- spec.GetDirectory().SetString(path);
+ spec.SetDirectory(path);
return spec;
}();
return g_spec;
@@ -412,6 +414,8 @@ ScriptInterpreterPythonImpl::ScriptInterpreterPythonImpl(Debugger &debugger)
m_command_thread_state(nullptr) {
m_scripted_process_interface_up =
std::make_unique<ScriptedProcessPythonInterface>(*this);
+ m_scripted_platform_interface_up =
+ std::make_unique<ScriptedPlatformPythonInterface>(*this);
m_dictionary_name.append("_dict");
StreamString run_string;
@@ -429,7 +433,7 @@ ScriptInterpreterPythonImpl::ScriptInterpreterPythonImpl(Debugger &debugger)
// Reloading modules requires a different syntax in Python 2 and Python 3.
// This provides a consistent syntax no matter what version of Python.
run_string.Clear();
- run_string.Printf("run_one_line (%s, 'from six.moves import reload_module')",
+ run_string.Printf("run_one_line (%s, 'from importlib import reload as reload_module')",
m_dictionary_name.c_str());
PyRun_SimpleString(run_string.GetData());
@@ -1259,8 +1263,6 @@ void ScriptInterpreterPythonImpl::SetWatchpointCommandCallback(
wp_options->SetCallback(
ScriptInterpreterPythonImpl::WatchpointCallbackFunction, baton_sp);
}
-
- return;
}
Status ScriptInterpreterPythonImpl::ExportFunctionDefinitionToInterpreter(
@@ -1371,7 +1373,7 @@ bool ScriptInterpreterPythonImpl::GenerateScriptAliasFunction(
std::string auto_generated_function_name(GenerateUniqueName(
"lldb_autogen_python_cmd_alias_func", num_created_functions));
- sstr.Printf("def %s (debugger, args, result, internal_dict):",
+ sstr.Printf("def %s (debugger, args, exe_ctx, result, internal_dict):",
auto_generated_function_name.c_str());
if (!GenerateFunction(sstr.GetData(), user_input).Success())
@@ -1503,50 +1505,29 @@ StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_RegisterInfo(
StructuredData::ObjectSP os_plugin_object_sp) {
Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
- static char callee_name[] = "get_register_info";
-
if (!os_plugin_object_sp)
- return StructuredData::DictionarySP();
+ return {};
StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
if (!generic)
- return nullptr;
+ return {};
PythonObject implementor(PyRefType::Borrowed,
(PyObject *)generic->GetValue());
if (!implementor.IsAllocated())
- return StructuredData::DictionarySP();
-
- PythonObject pmeth(PyRefType::Owned,
- PyObject_GetAttrString(implementor.get(), callee_name));
-
- if (PyErr_Occurred())
- PyErr_Clear();
-
- if (!pmeth.IsAllocated())
- return StructuredData::DictionarySP();
+ return {};
- if (PyCallable_Check(pmeth.get()) == 0) {
- if (PyErr_Occurred())
- PyErr_Clear();
+ llvm::Expected<PythonObject> expected_py_return =
+ implementor.CallMethod("get_register_info");
- return StructuredData::DictionarySP();
+ if (!expected_py_return) {
+ llvm::consumeError(expected_py_return.takeError());
+ return {};
}
- if (PyErr_Occurred())
- PyErr_Clear();
-
- // right now we know this function exists and is callable..
- PythonObject py_return(
- PyRefType::Owned,
- PyObject_CallMethod(implementor.get(), callee_name, nullptr));
+ PythonObject py_return = std::move(expected_py_return.get());
- // if it fails, print the error but otherwise go on
- if (PyErr_Occurred()) {
- PyErr_Print();
- PyErr_Clear();
- }
if (py_return.get()) {
PythonDictionary result_dict(PyRefType::Borrowed, py_return.get());
return result_dict.CreateStructuredDictionary();
@@ -1557,51 +1538,28 @@ StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_RegisterInfo(
StructuredData::ArraySP ScriptInterpreterPythonImpl::OSPlugin_ThreadsInfo(
StructuredData::ObjectSP os_plugin_object_sp) {
Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
-
- static char callee_name[] = "get_thread_info";
-
if (!os_plugin_object_sp)
- return StructuredData::ArraySP();
+ return {};
StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
if (!generic)
- return nullptr;
+ return {};
PythonObject implementor(PyRefType::Borrowed,
(PyObject *)generic->GetValue());
if (!implementor.IsAllocated())
- return StructuredData::ArraySP();
-
- PythonObject pmeth(PyRefType::Owned,
- PyObject_GetAttrString(implementor.get(), callee_name));
+ return {};
- if (PyErr_Occurred())
- PyErr_Clear();
+ llvm::Expected<PythonObject> expected_py_return =
+ implementor.CallMethod("get_thread_info");
- if (!pmeth.IsAllocated())
- return StructuredData::ArraySP();
-
- if (PyCallable_Check(pmeth.get()) == 0) {
- if (PyErr_Occurred())
- PyErr_Clear();
-
- return StructuredData::ArraySP();
+ if (!expected_py_return) {
+ llvm::consumeError(expected_py_return.takeError());
+ return {};
}
- if (PyErr_Occurred())
- PyErr_Clear();
-
- // right now we know this function exists and is callable..
- PythonObject py_return(
- PyRefType::Owned,
- PyObject_CallMethod(implementor.get(), callee_name, nullptr));
-
- // if it fails, print the error but otherwise go on
- if (PyErr_Occurred()) {
- PyErr_Print();
- PyErr_Clear();
- }
+ PythonObject py_return = std::move(expected_py_return.get());
if (py_return.get()) {
PythonList result_list(PyRefType::Borrowed, py_return.get());
@@ -1615,56 +1573,33 @@ ScriptInterpreterPythonImpl::OSPlugin_RegisterContextData(
StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid) {
Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
- static char callee_name[] = "get_register_data";
- static char *param_format =
- const_cast<char *>(GetPythonValueFormatString(tid));
-
if (!os_plugin_object_sp)
- return StructuredData::StringSP();
+ return {};
StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
if (!generic)
- return nullptr;
+ return {};
PythonObject implementor(PyRefType::Borrowed,
(PyObject *)generic->GetValue());
if (!implementor.IsAllocated())
- return StructuredData::StringSP();
-
- PythonObject pmeth(PyRefType::Owned,
- PyObject_GetAttrString(implementor.get(), callee_name));
-
- if (PyErr_Occurred())
- PyErr_Clear();
+ return {};
- if (!pmeth.IsAllocated())
- return StructuredData::StringSP();
+ llvm::Expected<PythonObject> expected_py_return =
+ implementor.CallMethod("get_register_data", tid);
- if (PyCallable_Check(pmeth.get()) == 0) {
- if (PyErr_Occurred())
- PyErr_Clear();
- return StructuredData::StringSP();
+ if (!expected_py_return) {
+ llvm::consumeError(expected_py_return.takeError());
+ return {};
}
- if (PyErr_Occurred())
- PyErr_Clear();
-
- // right now we know this function exists and is callable..
- PythonObject py_return(
- PyRefType::Owned,
- PyObject_CallMethod(implementor.get(), callee_name, param_format, tid));
-
- // if it fails, print the error but otherwise go on
- if (PyErr_Occurred()) {
- PyErr_Print();
- PyErr_Clear();
- }
+ PythonObject py_return = std::move(expected_py_return.get());
if (py_return.get()) {
PythonBytes result(PyRefType::Borrowed, py_return.get());
return result.CreateStructuredString();
}
- return StructuredData::StringSP();
+ return {};
}
StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_CreateThread(
@@ -1672,52 +1607,28 @@ StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_CreateThread(
lldb::addr_t context) {
Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
- static char callee_name[] = "create_thread";
- std::string param_format;
- param_format += GetPythonValueFormatString(tid);
- param_format += GetPythonValueFormatString(context);
-
if (!os_plugin_object_sp)
- return StructuredData::DictionarySP();
+ return {};
StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
if (!generic)
- return nullptr;
+ return {};
PythonObject implementor(PyRefType::Borrowed,
(PyObject *)generic->GetValue());
if (!implementor.IsAllocated())
- return StructuredData::DictionarySP();
-
- PythonObject pmeth(PyRefType::Owned,
- PyObject_GetAttrString(implementor.get(), callee_name));
-
- if (PyErr_Occurred())
- PyErr_Clear();
+ return {};
- if (!pmeth.IsAllocated())
- return StructuredData::DictionarySP();
+ llvm::Expected<PythonObject> expected_py_return =
+ implementor.CallMethod("create_thread", tid, context);
- if (PyCallable_Check(pmeth.get()) == 0) {
- if (PyErr_Occurred())
- PyErr_Clear();
- return StructuredData::DictionarySP();
+ if (!expected_py_return) {
+ llvm::consumeError(expected_py_return.takeError());
+ return {};
}
- if (PyErr_Occurred())
- PyErr_Clear();
-
- // right now we know this function exists and is callable..
- PythonObject py_return(PyRefType::Owned,
- PyObject_CallMethod(implementor.get(), callee_name,
- &param_format[0], tid, context));
-
- // if it fails, print the error but otherwise go on
- if (PyErr_Occurred()) {
- PyErr_Print();
- PyErr_Clear();
- }
+ PythonObject py_return = std::move(expected_py_return.get());
if (py_return.get()) {
PythonDictionary result_dict(PyRefType::Borrowed, py_return.get());
@@ -2156,6 +2067,14 @@ bool ScriptInterpreterPythonImpl::GetScriptedSummary(
return ret_val;
}
+bool ScriptInterpreterPythonImpl::FormatterCallbackFunction(
+ const char *python_function_name, TypeImplSP type_impl_sp) {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ return LLDBSwigPythonFormatterCallbackFunction(
+ python_function_name, m_dictionary_name.c_str(), type_impl_sp);
+}
+
bool ScriptInterpreterPythonImpl::BreakpointCallbackFunction(
void *baton, StoppointCallbackContext *context, user_id_t break_id,
user_id_t break_loc_id) {
@@ -2430,51 +2349,31 @@ ConstString ScriptInterpreterPythonImpl::GetSyntheticTypeName(
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- static char callee_name[] = "get_type_name";
-
- ConstString ret_val;
- bool got_string = false;
- std::string buffer;
-
if (!implementor_sp)
- return ret_val;
+ return {};
StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
if (!generic)
- return ret_val;
+ return {};
+
PythonObject implementor(PyRefType::Borrowed,
(PyObject *)generic->GetValue());
if (!implementor.IsAllocated())
- return ret_val;
-
- PythonObject pmeth(PyRefType::Owned,
- PyObject_GetAttrString(implementor.get(), callee_name));
+ return {};
- if (PyErr_Occurred())
- PyErr_Clear();
+ llvm::Expected<PythonObject> expected_py_return =
+ implementor.CallMethod("get_type_name");
- if (!pmeth.IsAllocated())
- return ret_val;
-
- if (PyCallable_Check(pmeth.get()) == 0) {
- if (PyErr_Occurred())
- PyErr_Clear();
- return ret_val;
+ if (!expected_py_return) {
+ llvm::consumeError(expected_py_return.takeError());
+ return {};
}
- if (PyErr_Occurred())
- PyErr_Clear();
+ PythonObject py_return = std::move(expected_py_return.get());
- // right now we know this function exists and is callable..
- PythonObject py_return(
- PyRefType::Owned,
- PyObject_CallMethod(implementor.get(), callee_name, nullptr));
-
- // if it fails, print the error but otherwise go on
- if (PyErr_Occurred()) {
- PyErr_Print();
- PyErr_Clear();
- }
+ ConstString ret_val;
+ bool got_string = false;
+ std::string buffer;
if (py_return.IsAllocated() && PythonString::Check(py_return.get())) {
PythonString py_string(PyRefType::Borrowed, py_return.get());
@@ -2530,7 +2429,7 @@ bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- if (llvm::Optional<std::string> result = LLDBSWIGPythonRunScriptKeywordThread(
+ if (std::optional<std::string> result = LLDBSWIGPythonRunScriptKeywordThread(
impl_function, m_dictionary_name.c_str(),
thread->shared_from_this())) {
output = std::move(*result);
@@ -2579,7 +2478,7 @@ bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- if (llvm::Optional<std::string> result = LLDBSWIGPythonRunScriptKeywordFrame(
+ if (std::optional<std::string> result = LLDBSWIGPythonRunScriptKeywordFrame(
impl_function, m_dictionary_name.c_str(),
frame->shared_from_this())) {
output = std::move(*result);
@@ -2888,9 +2787,10 @@ bool ScriptInterpreterPythonImpl::RunScriptBasedCommand(
if (!ret_val)
error.SetErrorString("unable to execute script function");
- else
- error.Clear();
+ else if (cmd_retobj.GetStatus() == eReturnStatusFailed)
+ return false;
+ error.Clear();
return ret_val;
}
@@ -2932,9 +2832,10 @@ bool ScriptInterpreterPythonImpl::RunScriptBasedCommand(
if (!ret_val)
error.SetErrorString("unable to execute script function");
- else
- error.Clear();
+ else if (cmd_retobj.GetStatus() == eReturnStatusFailed)
+ return false;
+ error.Clear();
return ret_val;
}
@@ -2978,8 +2879,6 @@ bool ScriptInterpreterPythonImpl::GetShortHelpForCommandObject(
Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
- static char callee_name[] = "get_short_help";
-
if (!cmd_obj_sp)
return false;
@@ -2989,34 +2888,15 @@ bool ScriptInterpreterPythonImpl::GetShortHelpForCommandObject(
if (!implementor.IsAllocated())
return false;
- PythonObject pmeth(PyRefType::Owned,
- PyObject_GetAttrString(implementor.get(), callee_name));
-
- if (PyErr_Occurred())
- PyErr_Clear();
-
- if (!pmeth.IsAllocated())
- return false;
+ llvm::Expected<PythonObject> expected_py_return =
+ implementor.CallMethod("get_short_help");
- if (PyCallable_Check(pmeth.get()) == 0) {
- if (PyErr_Occurred())
- PyErr_Clear();
+ if (!expected_py_return) {
+ llvm::consumeError(expected_py_return.takeError());
return false;
}
- if (PyErr_Occurred())
- PyErr_Clear();
-
- // Right now we know this function exists and is callable.
- PythonObject py_return(
- PyRefType::Owned,
- PyObject_CallMethod(implementor.get(), callee_name, nullptr));
-
- // If it fails, print the error but otherwise go on.
- if (PyErr_Occurred()) {
- PyErr_Print();
- PyErr_Clear();
- }
+ PythonObject py_return = std::move(expected_py_return.get());
if (py_return.IsAllocated() && PythonString::Check(py_return.get())) {
PythonString py_string(PyRefType::Borrowed, py_return.get());
@@ -3079,13 +2959,10 @@ uint32_t ScriptInterpreterPythonImpl::GetFlagsForCommandObject(
bool ScriptInterpreterPythonImpl::GetLongHelpForCommandObject(
StructuredData::GenericSP cmd_obj_sp, std::string &dest) {
- bool got_string = false;
dest.clear();
Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
- static char callee_name[] = "get_long_help";
-
if (!cmd_obj_sp)
return false;
@@ -3095,36 +2972,17 @@ bool ScriptInterpreterPythonImpl::GetLongHelpForCommandObject(
if (!implementor.IsAllocated())
return false;
- PythonObject pmeth(PyRefType::Owned,
- PyObject_GetAttrString(implementor.get(), callee_name));
-
- if (PyErr_Occurred())
- PyErr_Clear();
-
- if (!pmeth.IsAllocated())
- return false;
-
- if (PyCallable_Check(pmeth.get()) == 0) {
- if (PyErr_Occurred())
- PyErr_Clear();
+ llvm::Expected<PythonObject> expected_py_return =
+ implementor.CallMethod("get_long_help");
+ if (!expected_py_return) {
+ llvm::consumeError(expected_py_return.takeError());
return false;
}
- if (PyErr_Occurred())
- PyErr_Clear();
-
- // right now we know this function exists and is callable..
- PythonObject py_return(
- PyRefType::Owned,
- PyObject_CallMethod(implementor.get(), callee_name, nullptr));
-
- // if it fails, print the error but otherwise go on
- if (PyErr_Occurred()) {
- PyErr_Print();
- PyErr_Clear();
- }
+ PythonObject py_return = std::move(expected_py_return.get());
+ bool got_string = false;
if (py_return.IsAllocated() && PythonString::Check(py_return.get())) {
PythonString str(PyRefType::Borrowed, py_return.get());
llvm::StringRef str_data(str.GetString());
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 3b80c67d201a..f4875bfb8d18 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -202,6 +202,9 @@ public:
const TypeSummaryOptions &options,
std::string &retval) override;
+ bool FormatterCallbackFunction(const char *function_name,
+ lldb::TypeImplSP type_impl_sp) override;
+
bool GetDocumentationForItem(const char *item, std::string &dest) override;
bool GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.cpp
new file mode 100644
index 000000000000..9fbf50114694
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.cpp
@@ -0,0 +1,108 @@
+//===-- ScriptedPlatformPythonInterface.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/Status.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 "ScriptedPlatformPythonInterface.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::python;
+using Locker = ScriptInterpreterPythonImpl::Locker;
+
+ScriptedPlatformPythonInterface::ScriptedPlatformPythonInterface(
+ ScriptInterpreterPythonImpl &interpreter)
+ : ScriptedPlatformInterface(), ScriptedPythonInterface(interpreter) {}
+
+StructuredData::GenericSP ScriptedPlatformPythonInterface::CreatePluginObject(
+ llvm::StringRef class_name, ExecutionContext &exe_ctx,
+ StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) {
+ if (class_name.empty())
+ return {};
+
+ StructuredDataImpl args_impl(args_sp);
+ std::string error_string;
+
+ Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
+ Locker::FreeLock);
+
+ lldb::ExecutionContextRefSP exe_ctx_ref_sp =
+ std::make_shared<ExecutionContextRef>(exe_ctx);
+
+ PythonObject ret_val = LLDBSwigPythonCreateScriptedObject(
+ class_name.str().c_str(), m_interpreter.GetDictionaryName(),
+ exe_ctx_ref_sp, args_impl, error_string);
+
+ m_object_instance_sp =
+ StructuredData::GenericSP(new StructuredPythonObject(std::move(ret_val)));
+
+ return m_object_instance_sp;
+}
+
+StructuredData::DictionarySP ScriptedPlatformPythonInterface::ListProcesses() {
+ Status error;
+ StructuredData::DictionarySP dict_sp =
+ Dispatch<StructuredData::DictionarySP>("list_processes", error);
+
+ if (!dict_sp || !dict_sp->IsValid() || error.Fail()) {
+ return ScriptedInterface::ErrorWithMessage<StructuredData::DictionarySP>(
+ LLVM_PRETTY_FUNCTION,
+ llvm::Twine("Null or invalid object (" +
+ llvm::Twine(error.AsCString()) + llvm::Twine(")."))
+ .str(),
+ error);
+ }
+
+ return dict_sp;
+}
+
+StructuredData::DictionarySP
+ScriptedPlatformPythonInterface::GetProcessInfo(lldb::pid_t pid) {
+ Status error;
+ StructuredData::DictionarySP dict_sp =
+ Dispatch<StructuredData::DictionarySP>("get_process_info", error, pid);
+
+ if (!dict_sp || !dict_sp->IsValid() || error.Fail()) {
+ return ScriptedInterface::ErrorWithMessage<StructuredData::DictionarySP>(
+ LLVM_PRETTY_FUNCTION,
+ llvm::Twine("Null or invalid object (" +
+ llvm::Twine(error.AsCString()) + llvm::Twine(")."))
+ .str(),
+ error);
+ }
+
+ return dict_sp;
+}
+
+Status ScriptedPlatformPythonInterface::AttachToProcess(
+ ProcessAttachInfoSP attach_info) {
+ // FIXME: Pass `attach_info` to method call
+ return GetStatusFromMethod("attach_to_process");
+}
+
+Status ScriptedPlatformPythonInterface::LaunchProcess(
+ ProcessLaunchInfoSP launch_info) {
+ // FIXME: Pass `launch_info` to method call
+ return GetStatusFromMethod("launch_process");
+}
+
+Status ScriptedPlatformPythonInterface::KillProcess(lldb::pid_t pid) {
+ return GetStatusFromMethod("kill_process", pid);
+}
+
+#endif // LLDB_ENABLE_PYTHON
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.h
new file mode 100644
index 000000000000..1e3ad9962325
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.h
@@ -0,0 +1,44 @@
+//===-- ScriptedPlatformPythonInterface.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_SCRIPTEDPLATFORMPYTHONINTERFACE_H
+#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPLATFORMPYTHONINTERFACE_H
+
+#include "lldb/Host/Config.h"
+
+#if LLDB_ENABLE_PYTHON
+
+#include "ScriptedPythonInterface.h"
+#include "lldb/Interpreter/ScriptedPlatformInterface.h"
+
+namespace lldb_private {
+class ScriptedPlatformPythonInterface : public ScriptedPlatformInterface,
+ public ScriptedPythonInterface {
+public:
+ ScriptedPlatformPythonInterface(ScriptInterpreterPythonImpl &interpreter);
+
+ StructuredData::GenericSP
+ CreatePluginObject(const llvm::StringRef class_name,
+ ExecutionContext &exe_ctx,
+ StructuredData::DictionarySP args_sp,
+ StructuredData::Generic *script_obj = nullptr) override;
+
+ StructuredData::DictionarySP ListProcesses() override;
+
+ StructuredData::DictionarySP GetProcessInfo(lldb::pid_t) override;
+
+ Status AttachToProcess(lldb::ProcessAttachInfoSP attach_info) override;
+
+ Status LaunchProcess(lldb::ProcessLaunchInfoSP launch_info) override;
+
+ Status KillProcess(lldb::pid_t pid) override;
+};
+} // namespace lldb_private
+
+#endif // LLDB_ENABLE_PYTHON
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPLATFORMPYTHONINTERFACE_H
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 576bf69c9258..6f087e8390ce 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
@@ -8,6 +8,7 @@
#include "lldb/Host/Config.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Status.h"
#include "lldb/lldb-enumerations.h"
#if LLDB_ENABLE_PYTHON
@@ -19,6 +20,7 @@
#include "ScriptInterpreterPythonImpl.h"
#include "ScriptedProcessPythonInterface.h"
#include "ScriptedThreadPythonInterface.h"
+#include <optional>
using namespace lldb;
using namespace lldb_private;
@@ -35,16 +37,18 @@ StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject(
if (class_name.empty())
return {};
- TargetSP target_sp = exe_ctx.GetTargetSP();
StructuredDataImpl args_impl(args_sp);
std::string error_string;
Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
Locker::FreeLock);
- PythonObject ret_val = LLDBSwigPythonCreateScriptedProcess(
- class_name.str().c_str(), m_interpreter.GetDictionaryName(), target_sp,
- args_impl, error_string);
+ lldb::ExecutionContextRefSP exe_ctx_ref_sp =
+ std::make_shared<ExecutionContextRef>(exe_ctx);
+
+ PythonObject ret_val = LLDBSwigPythonCreateScriptedObject(
+ class_name.str().c_str(), m_interpreter.GetDictionaryName(),
+ exe_ctx_ref_sp, args_impl, error_string);
m_object_instance_sp =
StructuredData::GenericSP(new StructuredPythonObject(std::move(ret_val)));
@@ -74,10 +78,10 @@ Status ScriptedProcessPythonInterface::Stop() {
return GetStatusFromMethod("stop");
}
-llvm::Optional<MemoryRegionInfo>
+std::optional<MemoryRegionInfo>
ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress(
lldb::addr_t address, Status &error) {
- auto mem_region = Dispatch<llvm::Optional<MemoryRegionInfo>>(
+ auto mem_region = Dispatch<std::optional<MemoryRegionInfo>>(
"get_memory_region_containing_address", error, address);
if (error.Fail()) {
@@ -120,8 +124,15 @@ ScriptedProcessPythonInterface::GetRegistersForThread(lldb::tid_t tid) {
lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress(
lldb::addr_t address, size_t size, Status &error) {
- return Dispatch<lldb::DataExtractorSP>("read_memory_at_address", error,
- address, size);
+ Status py_error;
+ lldb::DataExtractorSP data_sp = Dispatch<lldb::DataExtractorSP>(
+ "read_memory_at_address", py_error, address, size, error);
+
+ // If there was an error on the python call, surface it to the user.
+ if (py_error.Fail())
+ error = py_error;
+
+ return data_sp;
}
StructuredData::ArraySP ScriptedProcessPythonInterface::GetLoadedImages() {
@@ -161,7 +172,7 @@ bool ScriptedProcessPythonInterface::IsAlive() {
return obj->GetBooleanValue();
}
-llvm::Optional<std::string>
+std::optional<std::string>
ScriptedProcessPythonInterface::GetScriptedThreadPluginName() {
Status error;
StructuredData::ObjectSP obj = Dispatch("get_scripted_thread_plugin", error);
@@ -177,4 +188,15 @@ ScriptedProcessPythonInterface::CreateScriptedThreadInterface() {
return std::make_shared<ScriptedThreadPythonInterface>(m_interpreter);
}
+StructuredData::DictionarySP ScriptedProcessPythonInterface::GetMetadata() {
+ Status error;
+ StructuredData::DictionarySP dict =
+ Dispatch<StructuredData::DictionarySP>("get_process_metadata", error);
+
+ if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
+ return {};
+
+ return dict;
+}
+
#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 7f458b1dd9bd..6b4ee3021cfa 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
@@ -15,6 +15,7 @@
#include "ScriptedPythonInterface.h"
#include "lldb/Interpreter/ScriptedProcessInterface.h"
+#include <optional>
namespace lldb_private {
class ScriptedProcessPythonInterface : public ScriptedProcessInterface,
@@ -36,7 +37,7 @@ public:
Status Stop() override;
- llvm::Optional<MemoryRegionInfo>
+ std::optional<MemoryRegionInfo>
GetMemoryRegionContainingAddress(lldb::addr_t address,
Status &error) override;
@@ -55,7 +56,9 @@ public:
bool IsAlive() override;
- llvm::Optional<std::string> GetScriptedThreadPluginName() override;
+ std::optional<std::string> GetScriptedThreadPluginName() override;
+
+ StructuredData::DictionarySP GetMetadata() override;
private:
lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override;
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp
index d5c527c61a5c..789b39abf587 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp
@@ -18,6 +18,7 @@
#include "SWIGPythonBridge.h"
#include "ScriptInterpreterPythonImpl.h"
#include "ScriptedPythonInterface.h"
+#include <optional>
using namespace lldb;
using namespace lldb_private;
@@ -26,14 +27,6 @@ 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::ArraySP
ScriptedPythonInterface::ExtractValueFromPythonObject<StructuredData::ArraySP>(
@@ -55,11 +48,11 @@ 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);
+ return m_interpreter.GetStatusFromSBError(*sb_error);
else
error.SetErrorString("Couldn't cast lldb::SBError to lldb::Status.");
- return error;
+ return {};
}
template <>
@@ -79,9 +72,9 @@ ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::DataExtractorSP>(
}
template <>
-llvm::Optional<MemoryRegionInfo>
+std::optional<MemoryRegionInfo>
ScriptedPythonInterface::ExtractValueFromPythonObject<
- llvm::Optional<MemoryRegionInfo>>(python::PythonObject &p, Status &error) {
+ std::optional<MemoryRegionInfo>>(python::PythonObject &p, Status &error) {
lldb::SBMemoryRegionInfo *sb_mem_reg_info =
reinterpret_cast<lldb::SBMemoryRegionInfo *>(
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
index 7c2fadc21d42..01dc07b49737 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
@@ -9,10 +9,15 @@
#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPYTHONINTERFACE_H
#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPYTHONINTERFACE_H
-#include "lldb/Host/Config.h"
-
#if LLDB_ENABLE_PYTHON
+#include <optional>
+#include <sstream>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+
+#include "lldb/Host/Config.h"
#include "lldb/Interpreter/ScriptedInterface.h"
#include "lldb/Utility/DataBufferHeap.h"
@@ -34,7 +39,7 @@ protected:
}
template <typename T = StructuredData::ObjectSP, typename... Args>
- T Dispatch(llvm::StringRef method_name, Status &error, Args... args) {
+ T Dispatch(llvm::StringRef method_name, Status &error, Args &&...args) {
using namespace python;
using Locker = ScriptInterpreterPythonImpl::Locker;
@@ -56,59 +61,112 @@ protected:
return ErrorWithMessage<T>(caller_signature,
"Python implementor not allocated.", error);
- PythonObject pmeth(
- PyRefType::Owned,
- PyObject_GetAttrString(implementor.get(), method_name.str().c_str()));
+ std::tuple<Args...> original_args = std::forward_as_tuple(args...);
+ auto transformed_args = TransformArgs(original_args);
+
+ llvm::Expected<PythonObject> expected_return_object =
+ llvm::make_error<llvm::StringError>("Not initialized.",
+ llvm::inconvertibleErrorCode());
+ std::apply(
+ [&implementor, &method_name, &expected_return_object](auto &&...args) {
+ llvm::consumeError(expected_return_object.takeError());
+ expected_return_object =
+ implementor.CallMethod(method_name.data(), args...);
+ },
+ transformed_args);
+
+ if (llvm::Error e = expected_return_object.takeError()) {
+ error.SetErrorString(llvm::toString(std::move(e)).c_str());
+ return ErrorWithMessage<T>(caller_signature,
+ "Python method could not be called.", error);
+ }
- if (PyErr_Occurred())
- PyErr_Clear();
+ PythonObject py_return = std::move(expected_return_object.get());
- if (!pmeth.IsAllocated())
- return ErrorWithMessage<T>(caller_signature,
- "Python method not allocated.", error);
+ if (!py_return.IsAllocated())
+ return ErrorWithMessage<T>(caller_signature, "Returned object is null.",
+ error);
- if (PyCallable_Check(pmeth.get()) == 0) {
- if (PyErr_Occurred())
- PyErr_Clear();
- return ErrorWithMessage<T>(caller_signature,
- "Python method not callable.", error);
- }
+ // Now that we called the python method with the transformed arguments,
+ // we need to interate again over both the original and transformed
+ // parameter pack, and transform back the parameter that were passed in
+ // the original parameter pack as references or pointers.
+ if (sizeof...(Args) > 0)
+ if (!ReassignPtrsOrRefsArgs(original_args, transformed_args))
+ return ErrorWithMessage<T>(
+ caller_signature,
+ "Couldn't re-assign reference and pointer arguments.", error);
- if (PyErr_Occurred())
- PyErr_Clear();
+ return ExtractValueFromPythonObject<T>(py_return, error);
+ }
- // TODO: make `const char *` when removing support for Python 2.
- char *format = nullptr;
- std::string format_buffer;
+ template <typename... Args>
+ Status GetStatusFromMethod(llvm::StringRef method_name, Args &&...args) {
+ Status error;
+ Dispatch<Status>(method_name, error, std::forward<Args>(args)...);
- 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());
- }
+ return error;
+ }
- // 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...));
+ template <typename T> T Transform(T object) {
+ // No Transformation for generic usage
+ return {object};
+ }
- if (PyErr_Occurred()) {
- PyErr_Print();
- PyErr_Clear();
- return ErrorWithMessage<T>(caller_signature,
- "Python method could not be called.", error);
- }
+ python::PythonObject Transform(Status arg) {
+ return python::ToSWIGWrapper(arg);
+ }
- if (!py_return.IsAllocated())
- return ErrorWithMessage<T>(caller_signature, "Returned object is null.",
- error);
+ template <typename T, typename U>
+ void ReverseTransform(T &original_arg, U transformed_arg, Status &error) {
+ // If U is not a PythonObject, don't touch it!
+ return;
+ }
- return ExtractValueFromPythonObject<T>(py_return, error);
+ template <typename T>
+ void ReverseTransform(T &original_arg, python::PythonObject transformed_arg,
+ Status &error) {
+ original_arg = ExtractValueFromPythonObject<T>(transformed_arg, error);
+ }
+
+ template <std::size_t... I, typename... Args>
+ auto TransformTuple(const std::tuple<Args...> &args,
+ std::index_sequence<I...>) {
+ return std::make_tuple(Transform(std::get<I>(args))...);
+ }
+
+ // This will iterate over the Dispatch parameter pack and replace in-place
+ // every `lldb_private` argument that has a SB counterpart.
+ template <typename... Args>
+ auto TransformArgs(const std::tuple<Args...> &args) {
+ return TransformTuple(args, std::make_index_sequence<sizeof...(Args)>());
+ }
+
+ template <typename T, typename U>
+ void TransformBack(T &original_arg, U transformed_arg, Status &error) {
+ ReverseTransform(original_arg, transformed_arg, error);
}
- Status GetStatusFromMethod(llvm::StringRef method_name);
+ template <std::size_t... I, typename... Ts, typename... Us>
+ bool ReassignPtrsOrRefsArgs(std::tuple<Ts...> &original_args,
+ std::tuple<Us...> &transformed_args,
+ std::index_sequence<I...>) {
+ Status error;
+ (TransformBack(std::get<I>(original_args), std::get<I>(transformed_args),
+ error),
+ ...);
+ return error.Success();
+ }
+
+ template <typename... Ts, typename... Us>
+ bool ReassignPtrsOrRefsArgs(std::tuple<Ts...> &original_args,
+ std::tuple<Us...> &transformed_args) {
+ if (sizeof...(Ts) != sizeof...(Us))
+ return false;
+
+ return ReassignPtrsOrRefsArgs(original_args, transformed_args,
+ std::make_index_sequence<sizeof...(Ts)>());
+ }
template <typename T, typename... Args>
void FormatArgs(std::string &fmt, T arg, Args... args) const {
@@ -117,7 +175,7 @@ protected:
}
template <typename T> void FormatArgs(std::string &fmt, T arg) const {
- fmt += GetPythonValueFormatString(arg);
+ fmt += python::PythonFormat<T>::format;
}
void FormatArgs(std::string &fmt) const {}
@@ -146,9 +204,9 @@ ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::DataExtractorSP>(
python::PythonObject &p, Status &error);
template <>
-llvm::Optional<MemoryRegionInfo>
+std::optional<MemoryRegionInfo>
ScriptedPythonInterface::ExtractValueFromPythonObject<
- llvm::Optional<MemoryRegionInfo>>(python::PythonObject &p, Status &error);
+ std::optional<MemoryRegionInfo>>(python::PythonObject &p, Status &error);
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
index 3ff592fb83cd..1b31ed2e5881 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
@@ -18,6 +18,7 @@
#include "SWIGPythonBridge.h"
#include "ScriptInterpreterPythonImpl.h"
#include "ScriptedThreadPythonInterface.h"
+#include <optional>
using namespace lldb;
using namespace lldb_private;
@@ -34,7 +35,6 @@ StructuredData::GenericSP ScriptedThreadPythonInterface::CreatePluginObject(
if (class_name.empty() && !script_obj)
return {};
- ProcessSP process_sp = exe_ctx.GetProcessSP();
StructuredDataImpl args_impl(args_sp);
std::string error_string;
@@ -43,11 +43,13 @@ StructuredData::GenericSP ScriptedThreadPythonInterface::CreatePluginObject(
PythonObject ret_val;
- if (!script_obj)
- ret_val = LLDBSwigPythonCreateScriptedThread(
- class_name.str().c_str(), m_interpreter.GetDictionaryName(), process_sp,
- args_impl, error_string);
- else
+ if (!script_obj) {
+ lldb::ExecutionContextRefSP exe_ctx_ref_sp =
+ std::make_shared<ExecutionContextRef>(exe_ctx);
+ ret_val = LLDBSwigPythonCreateScriptedObject(
+ class_name.str().c_str(), m_interpreter.GetDictionaryName(),
+ exe_ctx_ref_sp, args_impl, error_string);
+ } else
ret_val = PythonObject(PyRefType::Borrowed,
static_cast<PyObject *>(script_obj->GetValue()));
@@ -70,7 +72,7 @@ lldb::tid_t ScriptedThreadPythonInterface::GetThreadID() {
return obj->GetIntegerValue(LLDB_INVALID_THREAD_ID);
}
-llvm::Optional<std::string> ScriptedThreadPythonInterface::GetName() {
+std::optional<std::string> ScriptedThreadPythonInterface::GetName() {
Status error;
StructuredData::ObjectSP obj = Dispatch("get_name", error);
@@ -90,7 +92,7 @@ lldb::StateType ScriptedThreadPythonInterface::GetState() {
return static_cast<StateType>(obj->GetIntegerValue(eStateInvalid));
}
-llvm::Optional<std::string> ScriptedThreadPythonInterface::GetQueue() {
+std::optional<std::string> ScriptedThreadPythonInterface::GetQueue() {
Status error;
StructuredData::ObjectSP obj = Dispatch("get_queue", error);
@@ -133,8 +135,7 @@ StructuredData::DictionarySP ScriptedThreadPythonInterface::GetRegisterInfo() {
return dict;
}
-llvm::Optional<std::string>
-ScriptedThreadPythonInterface::GetRegisterContext() {
+std::optional<std::string> ScriptedThreadPythonInterface::GetRegisterContext() {
Status error;
StructuredData::ObjectSP obj = Dispatch("get_register_context", error);
@@ -144,4 +145,15 @@ ScriptedThreadPythonInterface::GetRegisterContext() {
return obj->GetAsString()->GetValue().str();
}
+StructuredData::ArraySP ScriptedThreadPythonInterface::GetExtendedInfo() {
+ Status error;
+ StructuredData::ArraySP arr =
+ Dispatch<StructuredData::ArraySP>("get_extended_info", error);
+
+ if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, arr, error))
+ return {};
+
+ return arr;
+}
+
#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
index 59bb182ae3f3..eac4941f8814 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h
@@ -15,6 +15,7 @@
#include "ScriptedPythonInterface.h"
#include "lldb/Interpreter/ScriptedProcessInterface.h"
+#include <optional>
namespace lldb_private {
class ScriptedThreadPythonInterface : public ScriptedThreadInterface,
@@ -29,11 +30,11 @@ public:
lldb::tid_t GetThreadID() override;
- llvm::Optional<std::string> GetName() override;
+ std::optional<std::string> GetName() override;
lldb::StateType GetState() override;
- llvm::Optional<std::string> GetQueue() override;
+ std::optional<std::string> GetQueue() override;
StructuredData::DictionarySP GetStopReason() override;
@@ -41,7 +42,9 @@ public:
StructuredData::DictionarySP GetRegisterInfo() override;
- llvm::Optional<std::string> GetRegisterContext() override;
+ std::optional<std::string> GetRegisterContext() override;
+
+ StructuredData::ArraySP GetExtendedInfo() override;
};
} // namespace lldb_private