[lldb] Make use of Scripted{Python,}Interface for ScriptedThreadPlan (#70392) (#96868)

This patch makes ScriptedThreadPlan conforming to the ScriptedInterface
& ScriptedPythonInterface facilities by introducing 2
ScriptedThreadPlanInterface & ScriptedThreadPlanPythonInterface classes.

This allows us to get rid of every ScriptedThreadPlan-specific SWIG
method and re-use the same affordances as other scripting offordances,
like Scripted{Process,Thread,Platform} & OperatingSystem.

To do so, this adds new transformer methods for `ThreadPlan`, `Stream` &
`Event`, to allow the bijection between C++ objects and their python
counterparts.

This just re-lands #70392 after fixing test failures.

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
This commit is contained in:
Med Ismail Bennani
2024-06-27 01:45:30 -07:00
committed by GitHub
parent bf536cc7db
commit 9a9ec228cd
25 changed files with 471 additions and 431 deletions

View File

@@ -37,10 +37,6 @@ PythonObject SWIGBridge::ToSWIGWrapper(const Status& status) {
return ToSWIGHelper(new lldb::SBError(status), SWIGTYPE_p_lldb__SBError);
}
PythonObject SWIGBridge::ToSWIGWrapper(std::unique_ptr<lldb::SBStream> stream_sb) {
return ToSWIGHelper(stream_sb.release(), SWIGTYPE_p_lldb__SBStream);
}
PythonObject SWIGBridge::ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb) {
return ToSWIGHelper(data_sb.release(), SWIGTYPE_p_lldb__SBStructuredData);
}
@@ -115,9 +111,16 @@ SWIGBridge::ToSWIGWrapper(CommandReturnObject &cmd_retobj) {
SWIGTYPE_p_lldb__SBCommandReturnObject);
}
ScopedPythonObject<lldb::SBEvent> SWIGBridge::ToSWIGWrapper(Event *event) {
return ScopedPythonObject<lldb::SBEvent>(new lldb::SBEvent(event),
SWIGTYPE_p_lldb__SBEvent);
PythonObject SWIGBridge::ToSWIGWrapper(const Stream *s) {
return ToSWIGHelper(new lldb::SBStream(), SWIGTYPE_p_lldb__SBStream);
}
PythonObject SWIGBridge::ToSWIGWrapper(std::shared_ptr<lldb::SBStream> stream_sb) {
return ToSWIGHelper(stream_sb.get(), SWIGTYPE_p_lldb__SBStream);
}
PythonObject SWIGBridge::ToSWIGWrapper(Event *event) {
return ToSWIGHelper(new lldb::SBEvent(event), SWIGTYPE_p_lldb__SBEvent);
}
PythonObject SWIGBridge::ToSWIGWrapper(

View File

@@ -229,133 +229,6 @@ PythonObject lldb_private::python::SWIGBridge::LLDBSwigPythonCreateCommandObject
return pfunc(SWIGBridge::ToSWIGWrapper(std::move(debugger_sp)), dict);
}
PythonObject lldb_private::python::SWIGBridge::LLDBSwigPythonCreateScriptedThreadPlan(
const char *python_class_name, const char *session_dictionary_name,
const lldb_private::StructuredDataImpl &args_impl,
std::string &error_string, const lldb::ThreadPlanSP &thread_plan_sp) {
if (python_class_name == NULL || python_class_name[0] == '\0' ||
!session_dictionary_name)
return PythonObject();
PyErr_Cleaner py_err_cleaner(true);
auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
session_dictionary_name);
auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
python_class_name, dict);
if (!pfunc.IsAllocated()) {
error_string.append("could not find script class: ");
error_string.append(python_class_name);
return PythonObject();
}
PythonObject tp_arg = SWIGBridge::ToSWIGWrapper(thread_plan_sp);
llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
if (!arg_info) {
llvm::handleAllErrors(
arg_info.takeError(),
[&](PythonException &E) { error_string.append(E.ReadBacktrace()); },
[&](const llvm::ErrorInfoBase &E) {
error_string.append(E.message());
});
return PythonObject();
}
PythonObject result = {};
auto args_sb = std::unique_ptr<lldb::SBStructuredData>(new lldb::SBStructuredData(args_impl));
if (arg_info.get().max_positional_args == 2) {
if (args_sb->IsValid()) {
error_string.assign(
"args passed, but __init__ does not take an args dictionary");
return PythonObject();
}
result = pfunc(tp_arg, dict);
} else if (arg_info.get().max_positional_args >= 3) {
result = pfunc(tp_arg, SWIGBridge::ToSWIGWrapper(std::move(args_sb)), dict);
} else {
error_string.assign("wrong number of arguments in __init__, should be 2 or "
"3 (not including self)");
return PythonObject();
}
// FIXME: At this point we should check that the class we found supports all
// the methods that we need.
return result;
}
bool lldb_private::python::SWIGBridge::LLDBSWIGPythonCallThreadPlan(
void *implementer, const char *method_name, lldb_private::Event *event,
bool &got_error) {
got_error = false;
PyErr_Cleaner py_err_cleaner(false);
PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementer));
auto pfunc = self.ResolveName<PythonCallable>(method_name);
if (!pfunc.IsAllocated())
return false;
PythonObject result;
if (event != nullptr) {
ScopedPythonObject<SBEvent> event_arg = SWIGBridge::ToSWIGWrapper(event);
result = pfunc(event_arg.obj());
} else
result = pfunc();
if (PyErr_Occurred()) {
got_error = true;
printf("Return value was neither false nor true for call to %s.\n",
method_name);
PyErr_Print();
return false;
}
if (result.get() == Py_True)
return true;
else if (result.get() == Py_False)
return false;
// Somebody returned the wrong thing...
got_error = true;
printf("Wrong return value type for call to %s.\n", method_name);
return false;
}
bool lldb_private::python::SWIGBridge::LLDBSWIGPythonCallThreadPlan(
void *implementer, const char *method_name, lldb_private::Stream *stream,
bool &got_error) {
got_error = false;
PyErr_Cleaner py_err_cleaner(false);
PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementer));
auto pfunc = self.ResolveName<PythonCallable>(method_name);
if (!pfunc.IsAllocated())
return false;
auto *sb_stream = new lldb::SBStream();
PythonObject sb_stream_arg =
SWIGBridge::ToSWIGWrapper(std::unique_ptr<lldb::SBStream>(sb_stream));
PythonObject result;
result = pfunc(sb_stream_arg);
if (PyErr_Occurred()) {
printf("Error occured for call to %s.\n",
method_name);
PyErr_Print();
got_error = true;
return false;
}
if (stream)
stream->PutCString(sb_stream->GetData());
return true;
}
PythonObject lldb_private::python::SWIGBridge::LLDBSwigPythonCreateScriptedBreakpointResolver(
const char *python_class_name, const char *session_dictionary_name,
const StructuredDataImpl &args_impl,
@@ -500,9 +373,8 @@ bool lldb_private::python::SWIGBridge::LLDBSwigPythonStopHookCallHandleStop(
if (!pfunc.IsAllocated())
return true;
auto *sb_stream = new lldb::SBStream();
PythonObject sb_stream_arg =
SWIGBridge::ToSWIGWrapper(std::unique_ptr<lldb::SBStream>(sb_stream));
std::shared_ptr<lldb::SBStream> sb_stream = std::make_shared<lldb::SBStream>();
PythonObject sb_stream_arg = SWIGBridge::ToSWIGWrapper(sb_stream);
PythonObject result =
pfunc(SWIGBridge::ToSWIGWrapper(std::move(exc_ctx_sp)), sb_stream_arg);
@@ -517,6 +389,7 @@ bool lldb_private::python::SWIGBridge::LLDBSwigPythonStopHookCallHandleStop(
// makes an internally help StreamString which I can't interpose, so I
// have to copy it over here.
stream->PutCString(sb_stream->GetData());
sb_stream_arg.release();
if (result.get() == Py_False)
return false;
@@ -753,6 +626,30 @@ void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBError(PyObject * data
return sb_ptr;
}
void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBEvent(PyObject * data) {
lldb::SBEvent *sb_ptr = nullptr;
int valid_cast =
SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBEvent, 0);
if (valid_cast == -1)
return NULL;
return sb_ptr;
}
void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBStream(PyObject * data) {
lldb::SBStream *sb_ptr = nullptr;
int valid_cast =
SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBStream, 0);
if (valid_cast == -1)
return NULL;
return sb_ptr;
}
void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBValue(PyObject * data) {
lldb::SBValue *sb_ptr = NULL;

View File

@@ -15,6 +15,7 @@
#include <vector>
namespace lldb_private {
class ScriptInterpreter;
namespace python {
class SWIGBridge;
}
@@ -73,11 +74,12 @@ protected:
friend class SBThread;
friend class SBWatchpoint;
friend class lldb_private::ScriptInterpreter;
friend class lldb_private::python::SWIGBridge;
SBEvent(lldb::EventSP &event_sp);
SBEvent(lldb_private::Event *event_sp);
SBEvent(lldb_private::Event *event);
lldb::EventSP &GetSP() const;

View File

@@ -13,6 +13,10 @@
#include "lldb/API/SBDefines.h"
namespace lldb_private {
class ScriptInterpreter;
} // namespace lldb_private
namespace lldb {
class LLDB_API SBStream {
@@ -103,6 +107,8 @@ protected:
friend class SBValue;
friend class SBWatchpoint;
friend class lldb_private::ScriptInterpreter;
lldb_private::Stream *operator->();
lldb_private::Stream *get();

View File

@@ -10,7 +10,6 @@
#define LLDB_INTERPRETER_INTERFACES_SCRIPTEDINTERFACE_H
#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/UnimplementedError.h"
@@ -52,7 +51,8 @@ public:
}
template <typename T = StructuredData::ObjectSP>
bool CheckStructuredDataObject(llvm::StringRef caller, T obj, Status &error) {
static bool CheckStructuredDataObject(llvm::StringRef caller, T obj,
Status &error) {
if (!obj)
return ErrorWithMessage<bool>(caller, "Null Structured Data object",
error);

View File

@@ -0,0 +1,38 @@
//===-- ScriptedThreadPlanInterface.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_INTERPRETER_INTERFACES_SCRIPTEDTHREADPLANINTERFACE_H
#define LLDB_INTERPRETER_INTERFACES_SCRIPTEDTHREADPLANINTERFACE_H
#include "lldb/lldb-private.h"
#include "ScriptedInterface.h"
namespace lldb_private {
class ScriptedThreadPlanInterface : public ScriptedInterface {
public:
virtual llvm::Expected<StructuredData::GenericSP>
CreatePluginObject(llvm::StringRef class_name,
lldb::ThreadPlanSP thread_plan_sp,
const StructuredDataImpl &args_sp) = 0;
virtual llvm::Expected<bool> ExplainsStop(Event *event) { return true; }
virtual llvm::Expected<bool> ShouldStop(Event *event) { return true; }
virtual llvm::Expected<bool> IsStale() { return true; };
virtual lldb::StateType GetRunState() { return lldb::eStateStepping; }
virtual llvm::Expected<bool> GetStopDescription(lldb_private::Stream *s) {
return true;
}
};
} // namespace lldb_private
#endif // LLDB_INTERPRETER_INTERFACES_SCRIPTEDTHREADPLANINTERFACE_H

View File

@@ -13,8 +13,10 @@
#include "lldb/API/SBBreakpoint.h"
#include "lldb/API/SBData.h"
#include "lldb/API/SBError.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBLaunchInfo.h"
#include "lldb/API/SBMemoryRegionInfo.h"
#include "lldb/API/SBStream.h"
#include "lldb/Breakpoint/BreakpointOptions.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/SearchFilter.h"
@@ -250,50 +252,6 @@ public:
return lldb::ValueObjectListSP();
}
virtual StructuredData::ObjectSP
CreateScriptedThreadPlan(const char *class_name,
const StructuredDataImpl &args_data,
std::string &error_str,
lldb::ThreadPlanSP thread_plan_sp) {
return StructuredData::ObjectSP();
}
virtual bool
ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp,
Event *event, bool &script_error) {
script_error = true;
return true;
}
virtual bool
ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp,
Event *event, bool &script_error) {
script_error = true;
return true;
}
virtual bool
ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp,
bool &script_error) {
script_error = true;
return true;
}
virtual lldb::StateType
ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp,
bool &script_error) {
script_error = true;
return lldb::eStateStepping;
}
virtual bool
ScriptedThreadPlanGetStopDescription(StructuredData::ObjectSP implementor_sp,
lldb_private::Stream *stream,
bool &script_error) {
script_error = true;
return false;
}
virtual StructuredData::GenericSP
CreateScriptedBreakpointResolver(const char *class_name,
const StructuredDataImpl &args_data,
@@ -592,6 +550,11 @@ public:
return {};
}
virtual lldb::ScriptedThreadPlanInterfaceSP
CreateScriptedThreadPlanInterface() {
return {};
}
virtual lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() {
return {};
}
@@ -610,6 +573,10 @@ public:
Status GetStatusFromSBError(const lldb::SBError &error) const;
Event *GetOpaqueTypeFromSBEvent(const lldb::SBEvent &event) const;
Stream *GetOpaqueTypeFromSBStream(const lldb::SBStream &stream) const;
lldb::BreakpointSP
GetOpaqueTypeFromSBBreakpoint(const lldb::SBBreakpoint &breakpoint) const;

View File

@@ -13,6 +13,7 @@
#include <string>
#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
@@ -70,6 +71,7 @@ private:
StreamString m_stop_description; // Cache the stop description here
bool m_did_push;
bool m_stop_others;
lldb::ScriptedThreadPlanInterfaceSP m_interface;
ThreadPlanPython(const ThreadPlanPython &) = delete;
const ThreadPlanPython &operator=(const ThreadPlanPython &) = delete;

View File

@@ -189,6 +189,7 @@ class ScriptedMetadata;
class ScriptedPlatformInterface;
class ScriptedProcessInterface;
class ScriptedThreadInterface;
class ScriptedThreadPlanInterface;
class ScriptedSyntheticChildren;
class SearchFilter;
class Section;
@@ -406,6 +407,8 @@ typedef std::unique_ptr<lldb_private::ScriptedProcessInterface>
ScriptedProcessInterfaceUP;
typedef std::shared_ptr<lldb_private::ScriptedThreadInterface>
ScriptedThreadInterfaceSP;
typedef std::shared_ptr<lldb_private::ScriptedThreadPlanInterface>
ScriptedThreadPlanInterfaceSP;
typedef std::shared_ptr<lldb_private::Section> SectionSP;
typedef std::unique_ptr<lldb_private::SectionList> SectionListUP;
typedef std::weak_ptr<lldb_private::Section> SectionWP;

View File

@@ -101,6 +101,19 @@ ScriptInterpreter::GetStatusFromSBError(const lldb::SBError &error) const {
return Status();
}
Event *
ScriptInterpreter::GetOpaqueTypeFromSBEvent(const lldb::SBEvent &event) const {
return event.m_opaque_ptr;
}
Stream *ScriptInterpreter::GetOpaqueTypeFromSBStream(
const lldb::SBStream &stream) const {
if (stream.m_opaque_up)
return const_cast<lldb::SBStream &>(stream).m_opaque_up.get();
return nullptr;
}
std::optional<MemoryRegionInfo>
ScriptInterpreter::GetOpaqueTypeFromSBMemoryRegionInfo(
const lldb::SBMemoryRegionInfo &mem_region) const {

View File

@@ -24,6 +24,7 @@ add_lldb_library(lldbPluginScriptInterpreterPythonInterfaces
ScriptedPythonInterface.cpp
ScriptedProcessPythonInterface.cpp
ScriptedThreadPythonInterface.cpp
ScriptedThreadPlanPythonInterface.cpp
ScriptedPlatformPythonInterface.cpp
LINK_LIBS

View File

@@ -20,6 +20,8 @@
#include "../ScriptInterpreterPythonImpl.h"
#include "ScriptedPlatformPythonInterface.h"
#include "lldb/Target/ExecutionContext.h"
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::python;

View File

@@ -49,7 +49,8 @@ StructuredData::DictionarySP ScriptedProcessPythonInterface::GetCapabilities() {
StructuredData::DictionarySP dict =
Dispatch<StructuredData::DictionarySP>("get_capabilities", error);
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict,
error))
return {};
return dict;
@@ -90,7 +91,8 @@ StructuredData::DictionarySP ScriptedProcessPythonInterface::GetThreadsInfo() {
StructuredData::DictionarySP dict =
Dispatch<StructuredData::DictionarySP>("get_threads_info", error);
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict,
error))
return {};
return dict;
@@ -106,7 +108,8 @@ bool ScriptedProcessPythonInterface::CreateBreakpoint(lldb::addr_t addr,
if (py_error.Fail())
error = py_error;
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
error))
return {};
return obj->GetBooleanValue();
@@ -131,7 +134,8 @@ lldb::offset_t ScriptedProcessPythonInterface::WriteMemoryAtAddress(
StructuredData::ObjectSP obj =
Dispatch("write_memory_at_address", py_error, addr, data_sp, error);
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
error))
return LLDB_INVALID_OFFSET;
// If there was an error on the python call, surface it to the user.
@@ -146,7 +150,8 @@ StructuredData::ArraySP ScriptedProcessPythonInterface::GetLoadedImages() {
StructuredData::ArraySP array =
Dispatch<StructuredData::ArraySP>("get_loaded_images", error);
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, array, error))
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, array,
error))
return {};
return array;
@@ -156,7 +161,8 @@ lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() {
Status error;
StructuredData::ObjectSP obj = Dispatch("get_process_id", error);
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
error))
return LLDB_INVALID_PROCESS_ID;
return obj->GetUnsignedIntegerValue(LLDB_INVALID_PROCESS_ID);
@@ -166,7 +172,8 @@ bool ScriptedProcessPythonInterface::IsAlive() {
Status error;
StructuredData::ObjectSP obj = Dispatch("is_alive", error);
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
error))
return {};
return obj->GetBooleanValue();
@@ -177,7 +184,8 @@ ScriptedProcessPythonInterface::GetScriptedThreadPluginName() {
Status error;
StructuredData::ObjectSP obj = Dispatch("get_scripted_thread_plugin", error);
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
error))
return {};
return obj->GetStringValue().str();
@@ -193,7 +201,8 @@ StructuredData::DictionarySP ScriptedProcessPythonInterface::GetMetadata() {
StructuredData::DictionarySP dict =
Dispatch<StructuredData::DictionarySP>("get_process_metadata", error);
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict,
error))
return {};
return dict;

View File

@@ -26,6 +26,15 @@ ScriptedPythonInterface::ScriptedPythonInterface(
ScriptInterpreterPythonImpl &interpreter)
: ScriptedInterface(), m_interpreter(interpreter) {}
template <>
void ScriptedPythonInterface::ReverseTransform(
lldb_private::Stream *&original_arg, python::PythonObject transformed_arg,
Status &error) {
Stream *s = ExtractValueFromPythonObject<Stream *>(transformed_arg, error);
*original_arg = *s;
original_arg->PutCString(static_cast<StreamString *>(s)->GetData());
}
template <>
StructuredData::ArraySP
ScriptedPythonInterface::ExtractValueFromPythonObject<StructuredData::ArraySP>(
@@ -48,12 +57,33 @@ Status ScriptedPythonInterface::ExtractValueFromPythonObject<Status>(
if (lldb::SBError *sb_error = reinterpret_cast<lldb::SBError *>(
python::LLDBSWIGPython_CastPyObjectToSBError(p.get())))
return m_interpreter.GetStatusFromSBError(*sb_error);
else
error.SetErrorString("Couldn't cast lldb::SBError to lldb::Status.");
error.SetErrorString("Couldn't cast lldb::SBError to lldb::Status.");
return {};
}
template <>
Event *ScriptedPythonInterface::ExtractValueFromPythonObject<Event *>(
python::PythonObject &p, Status &error) {
if (lldb::SBEvent *sb_event = reinterpret_cast<lldb::SBEvent *>(
python::LLDBSWIGPython_CastPyObjectToSBEvent(p.get())))
return m_interpreter.GetOpaqueTypeFromSBEvent(*sb_event);
error.SetErrorString("Couldn't cast lldb::SBEvent to lldb_private::Event.");
return nullptr;
}
template <>
Stream *ScriptedPythonInterface::ExtractValueFromPythonObject<Stream *>(
python::PythonObject &p, Status &error) {
if (lldb::SBStream *sb_stream = reinterpret_cast<lldb::SBStream *>(
python::LLDBSWIGPython_CastPyObjectToSBStream(p.get())))
return m_interpreter.GetOpaqueTypeFromSBStream(*sb_stream);
error.SetErrorString("Couldn't cast lldb::SBStream to lldb_private::Stream.");
return nullptr;
}
template <>
lldb::DataExtractorSP
ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::DataExtractorSP>(

View File

@@ -115,7 +115,7 @@ public:
PythonObject::ResolveNameWithDictionary<python::PythonCallable>(
class_name, dict);
if (!init.IsAllocated())
return create_error(llvm::formatv("Could not find script class: %s",
return create_error(llvm::formatv("Could not find script class: {0}",
class_name.data()));
std::tuple<Args...> original_args = std::forward_as_tuple(args...);
@@ -248,8 +248,11 @@ protected:
(PyObject *)m_object_instance_sp->GetValue());
if (!implementor.IsAllocated())
return ErrorWithMessage<T>(caller_signature,
"Python implementor not allocated.", error);
return llvm::is_contained(GetAbstractMethods(), method_name)
? ErrorWithMessage<T>(caller_signature,
"Python implementor not allocated.",
error)
: T{};
std::tuple<Args...> original_args = std::forward_as_tuple(args...);
auto transformed_args = TransformArgs(original_args);
@@ -322,6 +325,10 @@ protected:
return python::SWIGBridge::ToSWIGWrapper(arg);
}
python::PythonObject Transform(lldb::ThreadPlanSP arg) {
return python::SWIGBridge::ToSWIGWrapper(arg);
}
python::PythonObject Transform(lldb::ProcessAttachInfoSP arg) {
return python::SWIGBridge::ToSWIGWrapper(arg);
}
@@ -330,6 +337,14 @@ protected:
return python::SWIGBridge::ToSWIGWrapper(arg);
}
python::PythonObject Transform(Event *arg) {
return python::SWIGBridge::ToSWIGWrapper(arg);
}
python::PythonObject Transform(Stream *arg) {
return python::SWIGBridge::ToSWIGWrapper(arg);
}
python::PythonObject Transform(lldb::DataExtractorSP arg) {
return python::SWIGBridge::ToSWIGWrapper(arg);
}
@@ -427,6 +442,14 @@ template <>
Status ScriptedPythonInterface::ExtractValueFromPythonObject<Status>(
python::PythonObject &p, Status &error);
template <>
Event *ScriptedPythonInterface::ExtractValueFromPythonObject<Event *>(
python::PythonObject &p, Status &error);
template <>
Stream *ScriptedPythonInterface::ExtractValueFromPythonObject<Stream *>(
python::PythonObject &p, Status &error);
template <>
lldb::BreakpointSP
ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::BreakpointSP>(

View File

@@ -0,0 +1,105 @@
//===-- ScriptedThreadPlanPythonInterface.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/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 "ScriptedThreadPlanPythonInterface.h"
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::python;
ScriptedThreadPlanPythonInterface::ScriptedThreadPlanPythonInterface(
ScriptInterpreterPythonImpl &interpreter)
: ScriptedThreadPlanInterface(), ScriptedPythonInterface(interpreter) {}
llvm::Expected<StructuredData::GenericSP>
ScriptedThreadPlanPythonInterface::CreatePluginObject(
const llvm::StringRef class_name, lldb::ThreadPlanSP thread_plan_sp,
const StructuredDataImpl &args_sp) {
return ScriptedPythonInterface::CreatePluginObject(class_name, nullptr,
thread_plan_sp, args_sp);
}
llvm::Expected<bool>
ScriptedThreadPlanPythonInterface::ExplainsStop(Event *event) {
Status error;
StructuredData::ObjectSP obj = Dispatch("explains_stop", error, event);
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
error)) {
if (!obj)
return false;
return error.ToError();
}
return obj->GetBooleanValue();
}
llvm::Expected<bool>
ScriptedThreadPlanPythonInterface::ShouldStop(Event *event) {
Status error;
StructuredData::ObjectSP obj = Dispatch("should_stop", error, event);
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
error)) {
if (!obj)
return false;
return error.ToError();
}
return obj->GetBooleanValue();
}
llvm::Expected<bool> ScriptedThreadPlanPythonInterface::IsStale() {
Status error;
StructuredData::ObjectSP obj = Dispatch("is_stale", error);
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
error)) {
if (!obj)
return false;
return error.ToError();
}
return obj->GetBooleanValue();
}
lldb::StateType ScriptedThreadPlanPythonInterface::GetRunState() {
Status error;
StructuredData::ObjectSP obj = Dispatch("should_step", error);
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
error))
return lldb::eStateStepping;
return static_cast<lldb::StateType>(obj->GetUnsignedIntegerValue(
static_cast<uint32_t>(lldb::eStateStepping)));
}
llvm::Expected<bool>
ScriptedThreadPlanPythonInterface::GetStopDescription(lldb_private::Stream *s) {
Status error;
Dispatch("stop_description", error, s);
if (error.Fail())
return error.ToError();
return true;
}
#endif

View File

@@ -0,0 +1,48 @@
//===-- ScriptedThreadPlanPythonInterface.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_INTERFACES_SCRIPTEDTHREADPLANPYTHONINTERFACE_H
#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDTHREADPLANPYTHONINTERFACE_H
#include "lldb/Host/Config.h"
#if LLDB_ENABLE_PYTHON
#include "ScriptedPythonInterface.h"
#include "lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h"
#include <optional>
namespace lldb_private {
class ScriptedThreadPlanPythonInterface : public ScriptedThreadPlanInterface,
public ScriptedPythonInterface {
public:
ScriptedThreadPlanPythonInterface(ScriptInterpreterPythonImpl &interpreter);
llvm::Expected<StructuredData::GenericSP>
CreatePluginObject(const llvm::StringRef class_name,
lldb::ThreadPlanSP thread_plan_sp,
const StructuredDataImpl &args_sp) override;
llvm::SmallVector<llvm::StringLiteral> GetAbstractMethods() const override {
return {};
}
llvm::Expected<bool> ExplainsStop(Event *event) override;
llvm::Expected<bool> ShouldStop(Event *event) override;
llvm::Expected<bool> IsStale() override;
lldb::StateType GetRunState() override;
llvm::Expected<bool> GetStopDescription(lldb_private::Stream *s) override;
};
} // namespace lldb_private
#endif // LLDB_ENABLE_PYTHON
#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDTHREADPLANPYTHONINTERFACE_H

View File

@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/Config.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Utility/Log.h"
#include "lldb/lldb-enumerations.h"
@@ -44,7 +45,8 @@ lldb::tid_t ScriptedThreadPythonInterface::GetThreadID() {
Status error;
StructuredData::ObjectSP obj = Dispatch("get_thread_id", error);
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
error))
return LLDB_INVALID_THREAD_ID;
return obj->GetUnsignedIntegerValue(LLDB_INVALID_THREAD_ID);
@@ -54,7 +56,8 @@ std::optional<std::string> ScriptedThreadPythonInterface::GetName() {
Status error;
StructuredData::ObjectSP obj = Dispatch("get_name", error);
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
error))
return {};
return obj->GetStringValue().str();
@@ -64,7 +67,8 @@ lldb::StateType ScriptedThreadPythonInterface::GetState() {
Status error;
StructuredData::ObjectSP obj = Dispatch("get_state", error);
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
error))
return eStateInvalid;
return static_cast<StateType>(obj->GetUnsignedIntegerValue(eStateInvalid));
@@ -74,7 +78,8 @@ std::optional<std::string> ScriptedThreadPythonInterface::GetQueue() {
Status error;
StructuredData::ObjectSP obj = Dispatch("get_queue", error);
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
error))
return {};
return obj->GetStringValue().str();
@@ -85,7 +90,8 @@ StructuredData::DictionarySP ScriptedThreadPythonInterface::GetStopReason() {
StructuredData::DictionarySP dict =
Dispatch<StructuredData::DictionarySP>("get_stop_reason", error);
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict,
error))
return {};
return dict;
@@ -96,7 +102,8 @@ StructuredData::ArraySP ScriptedThreadPythonInterface::GetStackFrames() {
StructuredData::ArraySP arr =
Dispatch<StructuredData::ArraySP>("get_stackframes", error);
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, arr, error))
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, arr,
error))
return {};
return arr;
@@ -107,7 +114,8 @@ StructuredData::DictionarySP ScriptedThreadPythonInterface::GetRegisterInfo() {
StructuredData::DictionarySP dict =
Dispatch<StructuredData::DictionarySP>("get_register_info", error);
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict,
error))
return {};
return dict;
@@ -117,7 +125,8 @@ std::optional<std::string> ScriptedThreadPythonInterface::GetRegisterContext() {
Status error;
StructuredData::ObjectSP obj = Dispatch("get_register_context", error);
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
error))
return {};
return obj->GetAsString()->GetValue().str();
@@ -128,7 +137,8 @@ StructuredData::ArraySP ScriptedThreadPythonInterface::GetExtendedInfo() {
StructuredData::ArraySP arr =
Dispatch<StructuredData::ArraySP>("get_extended_info", error);
if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, arr, error))
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, arr,
error))
return {};
return arr;

View File

@@ -97,12 +97,14 @@ public:
static PythonObject ToSWIGWrapper(lldb::ExecutionContextRefSP ctx_sp);
static PythonObject ToSWIGWrapper(const TypeSummaryOptions &summary_options);
static PythonObject ToSWIGWrapper(const SymbolContext &sym_ctx);
static PythonObject ToSWIGWrapper(const Stream *stream);
static PythonObject ToSWIGWrapper(std::shared_ptr<lldb::SBStream> stream_sb);
static PythonObject ToSWIGWrapper(Event *event);
static PythonObject ToSWIGWrapper(lldb::ProcessAttachInfoSP attach_info_sp);
static PythonObject ToSWIGWrapper(lldb::ProcessLaunchInfoSP launch_info_sp);
static PythonObject ToSWIGWrapper(lldb::DataExtractorSP data_extractor_sp);
static PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBStream> stream_sb);
static PythonObject
ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb);
static PythonObject
@@ -112,7 +114,6 @@ public:
static python::ScopedPythonObject<lldb::SBCommandReturnObject>
ToSWIGWrapper(CommandReturnObject &cmd_retobj);
static python::ScopedPythonObject<lldb::SBEvent> ToSWIGWrapper(Event *event);
// These prototypes are the Pythonic implementations of the required
// callbacks. Although these are scripting-language specific, their definition
// depends on the public API.
@@ -147,21 +148,6 @@ public:
const char *session_dictionary_name,
lldb::DebuggerSP debugger_sp);
static python::PythonObject LLDBSwigPythonCreateScriptedThreadPlan(
const char *python_class_name, const char *session_dictionary_name,
const StructuredDataImpl &args_data, std::string &error_string,
const lldb::ThreadPlanSP &thread_plan_sp);
static bool LLDBSWIGPythonCallThreadPlan(void *implementor,
const char *method_name,
lldb_private::Event *event_sp,
bool &got_error);
static bool LLDBSWIGPythonCallThreadPlan(void *implementor,
const char *method_name,
lldb_private::Stream *stream,
bool &got_error);
static python::PythonObject LLDBSwigPythonCreateScriptedBreakpointResolver(
const char *python_class_name, const char *session_dictionary_name,
const StructuredDataImpl &args, const lldb::BreakpointSP &bkpt_sp);
@@ -269,6 +255,8 @@ void *LLDBSWIGPython_CastPyObjectToSBBreakpoint(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBAttachInfo(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBLaunchInfo(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBEvent(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBStream(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data);
} // namespace python

View File

@@ -17,6 +17,7 @@
#include "Interfaces/OperatingSystemPythonInterface.h"
#include "Interfaces/ScriptedPlatformPythonInterface.h"
#include "Interfaces/ScriptedProcessPythonInterface.h"
#include "Interfaces/ScriptedThreadPlanPythonInterface.h"
#include "Interfaces/ScriptedThreadPythonInterface.h"
#include "PythonDataObjects.h"
#include "PythonReadline.h"
@@ -1537,6 +1538,11 @@ ScriptInterpreterPythonImpl::CreateScriptedThreadInterface() {
return std::make_shared<ScriptedThreadPythonInterface>(*this);
}
ScriptedThreadPlanInterfaceSP
ScriptInterpreterPythonImpl::CreateScriptedThreadPlanInterface() {
return std::make_shared<ScriptedThreadPlanPythonInterface>(*this);
}
OperatingSystemInterfaceSP
ScriptInterpreterPythonImpl::CreateOperatingSystemInterface() {
return std::make_shared<OperatingSystemPythonInterface>(*this);
@@ -1553,122 +1559,6 @@ ScriptInterpreterPythonImpl::CreateStructuredDataFromScriptObject(
return py_obj.CreateStructuredObject();
}
StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan(
const char *class_name, const StructuredDataImpl &args_data,
std::string &error_str, lldb::ThreadPlanSP thread_plan_sp) {
if (class_name == nullptr || class_name[0] == '\0')
return StructuredData::ObjectSP();
if (!thread_plan_sp.get())
return {};
Debugger &debugger = thread_plan_sp->GetTarget().GetDebugger();
ScriptInterpreterPythonImpl *python_interpreter =
GetPythonInterpreter(debugger);
if (!python_interpreter)
return {};
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
PythonObject ret_val = SWIGBridge::LLDBSwigPythonCreateScriptedThreadPlan(
class_name, python_interpreter->m_dictionary_name.c_str(), args_data,
error_str, thread_plan_sp);
if (!ret_val)
return {};
return StructuredData::ObjectSP(
new StructuredPythonObject(std::move(ret_val)));
}
bool ScriptInterpreterPythonImpl::ScriptedThreadPlanExplainsStop(
StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) {
bool explains_stop = true;
StructuredData::Generic *generic = nullptr;
if (implementor_sp)
generic = implementor_sp->GetAsGeneric();
if (generic) {
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
explains_stop = SWIGBridge::LLDBSWIGPythonCallThreadPlan(
generic->GetValue(), "explains_stop", event, script_error);
if (script_error)
return true;
}
return explains_stop;
}
bool ScriptInterpreterPythonImpl::ScriptedThreadPlanShouldStop(
StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) {
bool should_stop = true;
StructuredData::Generic *generic = nullptr;
if (implementor_sp)
generic = implementor_sp->GetAsGeneric();
if (generic) {
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
should_stop = SWIGBridge::LLDBSWIGPythonCallThreadPlan(
generic->GetValue(), "should_stop", event, script_error);
if (script_error)
return true;
}
return should_stop;
}
bool ScriptInterpreterPythonImpl::ScriptedThreadPlanIsStale(
StructuredData::ObjectSP implementor_sp, bool &script_error) {
bool is_stale = true;
StructuredData::Generic *generic = nullptr;
if (implementor_sp)
generic = implementor_sp->GetAsGeneric();
if (generic) {
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
is_stale = SWIGBridge::LLDBSWIGPythonCallThreadPlan(
generic->GetValue(), "is_stale", (Event *)nullptr, script_error);
if (script_error)
return true;
}
return is_stale;
}
lldb::StateType ScriptInterpreterPythonImpl::ScriptedThreadPlanGetRunState(
StructuredData::ObjectSP implementor_sp, bool &script_error) {
bool should_step = false;
StructuredData::Generic *generic = nullptr;
if (implementor_sp)
generic = implementor_sp->GetAsGeneric();
if (generic) {
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
should_step = SWIGBridge::LLDBSWIGPythonCallThreadPlan(
generic->GetValue(), "should_step", (Event *)nullptr, script_error);
if (script_error)
should_step = true;
}
if (should_step)
return lldb::eStateStepping;
return lldb::eStateRunning;
}
bool
ScriptInterpreterPythonImpl::ScriptedThreadPlanGetStopDescription(
StructuredData::ObjectSP implementor_sp, lldb_private::Stream *stream,
bool &script_error) {
StructuredData::Generic *generic = nullptr;
if (implementor_sp)
generic = implementor_sp->GetAsGeneric();
if (!generic) {
script_error = true;
return false;
}
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
return SWIGBridge::LLDBSWIGPythonCallThreadPlan(
generic->GetValue(), "stop_description", stream, script_error);
}
StructuredData::GenericSP
ScriptInterpreterPythonImpl::CreateScriptedBreakpointResolver(
const char *class_name, const StructuredDataImpl &args_data,

View File

@@ -77,34 +77,9 @@ public:
StructuredData::GenericSP
CreateScriptCommandObject(const char *class_name) override;
StructuredData::ObjectSP
CreateScriptedThreadPlan(const char *class_name,
const StructuredDataImpl &args_data,
std::string &error_str,
lldb::ThreadPlanSP thread_plan) override;
StructuredData::ObjectSP
CreateStructuredDataFromScriptObject(ScriptObject obj) override;
bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp,
Event *event,
bool &script_error) override;
bool ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp,
Event *event, bool &script_error) override;
bool ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp,
bool &script_error) override;
lldb::StateType
ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp,
bool &script_error) override;
bool
ScriptedThreadPlanGetStopDescription(StructuredData::ObjectSP implementor_sp,
lldb_private::Stream *s,
bool &script_error) override;
StructuredData::GenericSP
CreateScriptedBreakpointResolver(const char *class_name,
const StructuredDataImpl &args_data,
@@ -136,6 +111,9 @@ public:
lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override;
lldb::ScriptedThreadPlanInterfaceSP
CreateScriptedThreadPlanInterface() override;
lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() override;
StructuredData::ObjectSP

View File

@@ -10,6 +10,7 @@
#include "lldb/Core/Debugger.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
@@ -32,6 +33,26 @@ ThreadPlanPython::ThreadPlanPython(Thread &thread, const char *class_name,
eVoteNoOpinion, eVoteNoOpinion),
m_class_name(class_name), m_args_data(args_data), m_did_push(false),
m_stop_others(false) {
ScriptInterpreter *interpreter = GetScriptInterpreter();
if (!interpreter) {
SetPlanComplete(false);
// FIXME: error handling
// error.SetErrorStringWithFormat(
// "ThreadPlanPython::%s () - ERROR: %s", __FUNCTION__,
// "Couldn't get script interpreter");
return;
}
m_interface = interpreter->CreateScriptedThreadPlanInterface();
if (!m_interface) {
SetPlanComplete(false);
// FIXME: error handling
// error.SetErrorStringWithFormat(
// "ThreadPlanPython::%s () - ERROR: %s", __FUNCTION__,
// "Script interpreter couldn't create Scripted Thread Plan Interface");
return;
}
SetIsControllingPlan(true);
SetOkayToDiscard(true);
SetPrivate(false);
@@ -60,13 +81,14 @@ void ThreadPlanPython::DidPush() {
// We set up the script side in DidPush, so that it can push other plans in
// the constructor, and doesn't have to care about the details of DidPush.
m_did_push = true;
if (!m_class_name.empty()) {
ScriptInterpreter *script_interp = GetScriptInterpreter();
if (script_interp) {
m_implementation_sp = script_interp->CreateScriptedThreadPlan(
m_class_name.c_str(), m_args_data, m_error_str,
this->shared_from_this());
}
if (m_interface) {
auto obj_or_err = m_interface->CreatePluginObject(
m_class_name, this->shared_from_this(), m_args_data);
if (!obj_or_err) {
m_error_str = llvm::toString(obj_or_err.takeError());
SetPlanComplete(false);
} else
m_implementation_sp = *obj_or_err;
}
}
@@ -77,14 +99,13 @@ bool ThreadPlanPython::ShouldStop(Event *event_ptr) {
bool should_stop = true;
if (m_implementation_sp) {
ScriptInterpreter *script_interp = GetScriptInterpreter();
if (script_interp) {
bool script_error;
should_stop = script_interp->ScriptedThreadPlanShouldStop(
m_implementation_sp, event_ptr, script_error);
if (script_error)
SetPlanComplete(false);
}
auto should_stop_or_err = m_interface->ShouldStop(event_ptr);
if (!should_stop_or_err) {
LLDB_LOG_ERROR(GetLog(LLDBLog::Thread), should_stop_or_err.takeError(),
"Can't call ScriptedThreadPlan::ShouldStop.");
SetPlanComplete(false);
} else
should_stop = *should_stop_or_err;
}
return should_stop;
}
@@ -96,14 +117,13 @@ bool ThreadPlanPython::IsPlanStale() {
bool is_stale = true;
if (m_implementation_sp) {
ScriptInterpreter *script_interp = GetScriptInterpreter();
if (script_interp) {
bool script_error;
is_stale = script_interp->ScriptedThreadPlanIsStale(m_implementation_sp,
script_error);
if (script_error)
SetPlanComplete(false);
}
auto is_stale_or_err = m_interface->IsStale();
if (!is_stale_or_err) {
LLDB_LOG_ERROR(GetLog(LLDBLog::Thread), is_stale_or_err.takeError(),
"Can't call ScriptedThreadPlan::IsStale.");
SetPlanComplete(false);
} else
is_stale = *is_stale_or_err;
}
return is_stale;
}
@@ -115,14 +135,14 @@ bool ThreadPlanPython::DoPlanExplainsStop(Event *event_ptr) {
bool explains_stop = true;
if (m_implementation_sp) {
ScriptInterpreter *script_interp = GetScriptInterpreter();
if (script_interp) {
bool script_error;
explains_stop = script_interp->ScriptedThreadPlanExplainsStop(
m_implementation_sp, event_ptr, script_error);
if (script_error)
SetPlanComplete(false);
}
auto explains_stop_or_error = m_interface->ExplainsStop(event_ptr);
if (!explains_stop_or_error) {
LLDB_LOG_ERROR(GetLog(LLDBLog::Thread),
explains_stop_or_error.takeError(),
"Can't call ScriptedThreadPlan::ExplainsStop.");
SetPlanComplete(false);
} else
explains_stop = *explains_stop_or_error;
}
return explains_stop;
}
@@ -150,14 +170,8 @@ lldb::StateType ThreadPlanPython::GetPlanRunState() {
LLDB_LOGF(log, "%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
m_class_name.c_str());
lldb::StateType run_state = eStateRunning;
if (m_implementation_sp) {
ScriptInterpreter *script_interp = GetScriptInterpreter();
if (script_interp) {
bool script_error;
run_state = script_interp->ScriptedThreadPlanGetRunState(
m_implementation_sp, script_error);
}
}
if (m_implementation_sp)
run_state = m_interface->GetRunState();
return run_state;
}
@@ -168,12 +182,13 @@ void ThreadPlanPython::GetDescription(Stream *s, lldb::DescriptionLevel level) {
if (m_implementation_sp) {
ScriptInterpreter *script_interp = GetScriptInterpreter();
if (script_interp) {
bool script_error;
bool added_desc = script_interp->ScriptedThreadPlanGetStopDescription(
m_implementation_sp, s, script_error);
if (script_error || !added_desc)
auto desc_or_err = m_interface->GetStopDescription(s);
if (!desc_or_err || !*desc_or_err) {
LLDB_LOG_ERROR(GetLog(LLDBLog::Thread), desc_or_err.takeError(),
"Can't call ScriptedThreadPlan::GetStopDescription.");
s->Printf("Python thread plan implemented by class %s.",
m_class_name.c_str());
}
}
return;
}

View File

@@ -47,7 +47,7 @@ class StepScripted(StepWithChild):
# This plan does a step-over until a variable changes value.
class StepUntil(StepWithChild):
def __init__(self, thread_plan, args_data, dict):
def __init__(self, thread_plan, args_data):
self.thread_plan = thread_plan
self.frame = thread_plan.GetThread().frames[0]
self.target = thread_plan.GetThread().GetProcess().GetTarget()
@@ -99,7 +99,7 @@ class StepUntil(StepWithChild):
class StepReportsStopOthers:
stop_mode_dict = {}
def __init__(self, thread_plan, args_data, dict):
def __init__(self, thread_plan, args_data):
self.thread_plan = thread_plan
self.key = str(args_data.GetValueForKey("token").GetUnsignedIntegerValue(1000))

View File

@@ -2,7 +2,7 @@ import lldb
class WrapStepOver:
def __init__(self, thread_plan, args_data, dict):
def __init__(self, thread_plan, args_data):
self.plan = thread_plan
thread = thread_plan.GetThread()
target = thread.GetProcess().GetTarget()

View File

@@ -80,26 +80,6 @@ lldb_private::python::SWIGBridge::LLDBSwigPythonCreateCommandObject(
return python::PythonObject();
}
python::PythonObject
lldb_private::python::SWIGBridge::LLDBSwigPythonCreateScriptedThreadPlan(
const char *python_class_name, const char *session_dictionary_name,
const StructuredDataImpl &args_data, std::string &error_string,
const lldb::ThreadPlanSP &thread_plan_sp) {
return python::PythonObject();
}
bool lldb_private::python::SWIGBridge::LLDBSWIGPythonCallThreadPlan(
void *implementor, const char *method_name, Event *event_sp,
bool &got_error) {
return false;
}
bool lldb_private::python::SWIGBridge::LLDBSWIGPythonCallThreadPlan(
void *implementor, const char *method_name, Stream *event_sp,
bool &got_error) {
return false;
}
python::PythonObject lldb_private::python::SWIGBridge::
LLDBSwigPythonCreateScriptedBreakpointResolver(
const char *python_class_name, const char *session_dictionary_name,
@@ -154,6 +134,16 @@ lldb_private::python::LLDBSWIGPython_CastPyObjectToSBError(PyObject *data) {
return nullptr;
}
void *
lldb_private::python::LLDBSWIGPython_CastPyObjectToSBEvent(PyObject *data) {
return nullptr;
}
void *
lldb_private::python::LLDBSWIGPython_CastPyObjectToSBStream(PyObject *data) {
return nullptr;
}
void *
lldb_private::python::LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data) {
return nullptr;
@@ -311,6 +301,11 @@ lldb_private::python::SWIGBridge::ToSWIGWrapper(lldb::ExecutionContextRefSP) {
return python::PythonObject();
}
python::PythonObject
lldb_private::python::SWIGBridge::ToSWIGWrapper(lldb::ThreadPlanSP) {
return python::PythonObject();
}
python::PythonObject
lldb_private::python::SWIGBridge::ToSWIGWrapper(lldb::ProcessSP) {
return python::PythonObject();
@@ -320,3 +315,18 @@ python::PythonObject lldb_private::python::SWIGBridge::ToSWIGWrapper(
const lldb_private::StructuredDataImpl &) {
return python::PythonObject();
}
python::PythonObject
lldb_private::python::SWIGBridge::ToSWIGWrapper(Event *event) {
return python::PythonObject();
}
python::PythonObject
lldb_private::python::SWIGBridge::ToSWIGWrapper(const Stream *stream) {
return python::PythonObject();
}
python::PythonObject lldb_private::python::SWIGBridge::ToSWIGWrapper(
std::shared_ptr<lldb::SBStream> stream_sb) {
return python::PythonObject();
}