From 484038416d0601dcee16f692d93659bcc0e24e9a Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani Date: Mon, 30 Oct 2023 16:35:09 -0700 Subject: [PATCH] [lldb] Make use of Scripted{Python,}Interface for ScriptedThreadPlan 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. Signed-off-by: Med Ismail Bennani --- lldb/bindings/python/python-swigsafecast.swig | 13 +- lldb/bindings/python/python-wrapper.swig | 153 +++--------------- lldb/include/lldb/API/SBEvent.h | 4 +- lldb/include/lldb/API/SBStream.h | 9 ++ .../Interfaces/ScriptedInterface.h | 4 +- .../Interfaces/ScriptedThreadPlanInterface.h | 40 +++++ .../lldb/Interpreter/ScriptInterpreter.h | 56 ++----- lldb/include/lldb/Target/ThreadPlanPython.h | 2 + lldb/include/lldb/lldb-forward.h | 3 + lldb/source/Interpreter/ScriptInterpreter.cpp | 13 ++ .../Python/Interfaces/CMakeLists.txt | 1 + .../ScriptedPlatformPythonInterface.cpp | 2 + .../Interfaces/ScriptedPythonInterface.cpp | 34 +++- .../Interfaces/ScriptedPythonInterface.h | 20 +++ .../ScriptedThreadPlanPythonInterface.cpp | 92 +++++++++++ .../ScriptedThreadPlanPythonInterface.h | 44 +++++ .../ScriptedThreadPythonInterface.cpp | 1 + .../Python/SWIGPythonBridge.h | 21 +-- .../Python/ScriptInterpreterPython.cpp | 122 +------------- .../Python/ScriptInterpreterPythonImpl.h | 28 +--- lldb/source/Target/ThreadPlanPython.cpp | 97 ++++++----- .../functionalities/step_scripted/Steps.py | 4 +- .../Python/PythonTestSuite.cpp | 45 +++--- 23 files changed, 401 insertions(+), 407 deletions(-) create mode 100644 lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h create mode 100644 lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.cpp create mode 100644 lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.h diff --git a/lldb/bindings/python/python-swigsafecast.swig b/lldb/bindings/python/python-swigsafecast.swig index d5ea5148727134..fba3a77d8f2df4 100644 --- a/lldb/bindings/python/python-swigsafecast.swig +++ b/lldb/bindings/python/python-swigsafecast.swig @@ -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 stream_sb) { - return ToSWIGHelper(stream_sb.release(), SWIGTYPE_p_lldb__SBStream); -} - PythonObject SWIGBridge::ToSWIGWrapper(std::unique_ptr data_sb) { return ToSWIGHelper(data_sb.release(), SWIGTYPE_p_lldb__SBStructuredData); } @@ -115,9 +111,12 @@ SWIGBridge::ToSWIGWrapper(CommandReturnObject &cmd_retobj) { SWIGTYPE_p_lldb__SBCommandReturnObject); } -ScopedPythonObject SWIGBridge::ToSWIGWrapper(Event *event) { - return ScopedPythonObject(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(Event *event) { + return ToSWIGHelper(new lldb::SBEvent(event), SWIGTYPE_p_lldb__SBEvent); } PythonObject SWIGBridge::ToSWIGWrapper( diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig index 17bc7b1f219870..5c28d652824073 100644 --- a/lldb/bindings/python/python-wrapper.swig +++ b/lldb/bindings/python/python-wrapper.swig @@ -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( - session_dictionary_name); - auto pfunc = PythonObject::ResolveNameWithDictionary( - 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 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(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 *implementor, 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(implementor)); - auto pfunc = self.ResolveName(method_name); - - if (!pfunc.IsAllocated()) - return false; - - PythonObject result; - if (event != nullptr) { - ScopedPythonObject 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 *implementor, 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(implementor)); - auto pfunc = self.ResolveName(method_name); - - if (!pfunc.IsAllocated()) - return false; - - auto *sb_stream = new lldb::SBStream(); - PythonObject sb_stream_arg = - SWIGBridge::ToSWIGWrapper(std::unique_ptr(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, @@ -502,7 +375,7 @@ bool lldb_private::python::SWIGBridge::LLDBSwigPythonStopHookCallHandleStop( auto *sb_stream = new lldb::SBStream(); PythonObject sb_stream_arg = - SWIGBridge::ToSWIGWrapper(std::unique_ptr(sb_stream)); + SWIGBridge::ToSWIGWrapper(stream.get()); PythonObject result = pfunc(SWIGBridge::ToSWIGWrapper(std::move(exc_ctx_sp)), sb_stream_arg); @@ -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; diff --git a/lldb/include/lldb/API/SBEvent.h b/lldb/include/lldb/API/SBEvent.h index cc116766e85f4a..85b401ca8cc100 100644 --- a/lldb/include/lldb/API/SBEvent.h +++ b/lldb/include/lldb/API/SBEvent.h @@ -15,6 +15,7 @@ #include namespace lldb_private { +class ScriptInterpreter; namespace python { class SWIGBridge; } @@ -73,11 +74,12 @@ class LLDB_API SBEvent { 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; diff --git a/lldb/include/lldb/API/SBStream.h b/lldb/include/lldb/API/SBStream.h index 0e33f05b69916f..ee329737d594b5 100644 --- a/lldb/include/lldb/API/SBStream.h +++ b/lldb/include/lldb/API/SBStream.h @@ -13,6 +13,13 @@ #include "lldb/API/SBDefines.h" +namespace lldb_private { +class ScriptInterpreter; +namespace python { +class SWIGBridge; +} +} // namespace lldb_private + namespace lldb { class LLDB_API SBStream { @@ -101,6 +108,8 @@ class LLDB_API SBStream { friend class SBValue; friend class SBWatchpoint; + friend class lldb_private::ScriptInterpreter; + lldb_private::Stream *operator->(); lldb_private::Stream *get(); diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h index e4816352daa5db..fc0e488da69829 100644 --- a/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h +++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h @@ -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" @@ -50,7 +49,8 @@ class ScriptedInterface { } template - bool CheckStructuredDataObject(llvm::StringRef caller, T obj, Status &error) { + static bool CheckStructuredDataObject(llvm::StringRef caller, T obj, + Status &error) { if (!obj) return ErrorWithMessage(caller, "Null Structured Data object", error); diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h new file mode 100644 index 00000000000000..4dadda4d978985 --- /dev/null +++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h @@ -0,0 +1,40 @@ +//===-- 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 + CreatePluginObject(llvm::StringRef class_name, + lldb::ThreadPlanSP thread_plan_sp, + const StructuredDataImpl &args_sp) { + llvm_unreachable("unimplemented!"); + } + + virtual llvm::Expected ExplainsStop(Event *event) { return true; } + + virtual llvm::Expected ShouldStop(Event *event) { return true; } + + virtual llvm::Expected IsStale() { return true; }; + + virtual lldb::StateType GetRunState() { return lldb::eStateStepping; } + + virtual llvm::Expected GetStopDescription(lldb_private::Stream *s) { + return true; + } +}; +} // namespace lldb_private + +#endif // LLDB_INTERPRETER_INTERFACES_SCRIPTEDTHREADPLANINTERFACE_H diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h index 0146eeb8626200..7e2a7286e20422 100644 --- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h +++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -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" @@ -25,6 +27,7 @@ #include "lldb/Interpreter/Interfaces/ScriptedPlatformInterface.h" #include "lldb/Interpreter/Interfaces/ScriptedProcessInterface.h" #include "lldb/Interpreter/Interfaces/ScriptedThreadInterface.h" +#include "lldb/Interpreter/Interfaces/ScriptedThreadPlanInterface.h" #include "lldb/Interpreter/ScriptObject.h" #include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/Status.h" @@ -253,50 +256,6 @@ class ScriptInterpreter : public PluginInterface { 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, @@ -566,6 +525,11 @@ class ScriptInterpreter : public PluginInterface { return std::make_shared(); } + virtual lldb::ScriptedThreadPlanInterfaceSP + CreateScriptedThreadPlanInterface() { + return std::make_shared(); + } + virtual lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() { return std::make_shared(); } @@ -584,6 +548,10 @@ class ScriptInterpreter : public PluginInterface { 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; diff --git a/lldb/include/lldb/Target/ThreadPlanPython.h b/lldb/include/lldb/Target/ThreadPlanPython.h index 64854d66b8f258..da106faf951db1 100644 --- a/lldb/include/lldb/Target/ThreadPlanPython.h +++ b/lldb/include/lldb/Target/ThreadPlanPython.h @@ -13,6 +13,7 @@ #include #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 @@ class ThreadPlanPython : public ThreadPlan { 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; diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index aa099d4abc3b09..6138e6fe5a60b4 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -185,6 +185,7 @@ class ScriptedMetadata; class ScriptedPlatformInterface; class ScriptedProcessInterface; class ScriptedThreadInterface; +class ScriptedThreadPlanInterface; class ScriptedSyntheticChildren; class SearchFilter; class Section; @@ -393,6 +394,8 @@ typedef std::unique_ptr ScriptedProcessInterfaceUP; typedef std::shared_ptr ScriptedThreadInterfaceSP; +typedef std::shared_ptr + ScriptedThreadPlanInterfaceSP; typedef std::shared_ptr SectionSP; typedef std::unique_ptr SectionListUP; typedef std::weak_ptr SectionWP; diff --git a/lldb/source/Interpreter/ScriptInterpreter.cpp b/lldb/source/Interpreter/ScriptInterpreter.cpp index fb3fa74d0b9780..aee2ec94d7979a 100644 --- a/lldb/source/Interpreter/ScriptInterpreter.cpp +++ b/lldb/source/Interpreter/ScriptInterpreter.cpp @@ -104,6 +104,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(stream).m_opaque_up.get(); + + return nullptr; +} + std::optional ScriptInterpreter::GetOpaqueTypeFromSBMemoryRegionInfo( const lldb::SBMemoryRegionInfo &mem_region) const { diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt index b22abc49c92a9a..c60e4bb503a371 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt @@ -24,6 +24,7 @@ add_lldb_library(lldbPluginScriptInterpreterPythonInterfaces ScriptedPythonInterface.cpp ScriptedProcessPythonInterface.cpp ScriptedThreadPythonInterface.cpp + ScriptedThreadPlanPythonInterface.cpp ScriptedPlatformPythonInterface.cpp LINK_LIBS diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.cpp index 9ba4731032bd35..6e93bec80056ee 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPlatformPythonInterface.cpp @@ -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; diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp index 6f22503b279ca6..7d072212676e13 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp @@ -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(transformed_arg, error); + *original_arg = *s; + original_arg->PutCString(static_cast(s)->GetData()); +} + template <> StructuredData::ArraySP ScriptedPythonInterface::ExtractValueFromPythonObject( @@ -48,12 +57,33 @@ Status ScriptedPythonInterface::ExtractValueFromPythonObject( if (lldb::SBError *sb_error = reinterpret_cast( 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( + python::PythonObject &p, Status &error) { + if (lldb::SBEvent *sb_event = reinterpret_cast( + 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( + python::PythonObject &p, Status &error) { + if (lldb::SBStream *sb_stream = reinterpret_cast( + 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( diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h index 7af98163970999..cc760938c89959 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h @@ -224,6 +224,10 @@ class ScriptedPythonInterface : virtual public ScriptedInterface { 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); } @@ -232,6 +236,14 @@ class ScriptedPythonInterface : virtual public ScriptedInterface { 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); } @@ -329,6 +341,14 @@ template <> Status ScriptedPythonInterface::ExtractValueFromPythonObject( python::PythonObject &p, Status &error); +template <> +Event *ScriptedPythonInterface::ExtractValueFromPythonObject( + python::PythonObject &p, Status &error); + +template <> +Stream *ScriptedPythonInterface::ExtractValueFromPythonObject( + python::PythonObject &p, Status &error); + template <> lldb::BreakpointSP ScriptedPythonInterface::ExtractValueFromPythonObject( diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.cpp new file mode 100644 index 00000000000000..df9f7db6f62b02 --- /dev/null +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.cpp @@ -0,0 +1,92 @@ +//===-- 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 +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 +ScriptedThreadPlanPythonInterface::ExplainsStop(Event *event) { + Status error; + StructuredData::ObjectSP obj = Dispatch("explains_stop", error, event); + + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) + return error.ToError(); + + return obj->GetBooleanValue(); +} + +llvm::Expected +ScriptedThreadPlanPythonInterface::ShouldStop(Event *event) { + Status error; + StructuredData::ObjectSP obj = Dispatch("should_stop", error, event); + + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) + return error.ToError(); + + return obj->GetBooleanValue(); +} + +llvm::Expected ScriptedThreadPlanPythonInterface::IsStale() { + Status error; + StructuredData::ObjectSP obj = Dispatch("is_stale", error); + + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) + return error.ToError(); + + return obj->GetBooleanValue(); +} + +lldb::StateType ScriptedThreadPlanPythonInterface::GetRunState() { + Status error; + StructuredData::ObjectSP obj = Dispatch("should_step", error); + + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) + return lldb::eStateStepping; + + return static_cast(obj->GetUnsignedIntegerValue( + static_cast(lldb::eStateStepping))); +} + +llvm::Expected +ScriptedThreadPlanPythonInterface::GetStopDescription(lldb_private::Stream *s) { + Status error; + Dispatch("stop_description", error, s); + + if (error.Fail()) + return error.ToError(); + + return true; +} + +#endif diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.h new file mode 100644 index 00000000000000..2eb986e0282f0f --- /dev/null +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.h @@ -0,0 +1,44 @@ +//===-- 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 + +namespace lldb_private { +class ScriptedThreadPlanPythonInterface : public ScriptedThreadPlanInterface, + public ScriptedPythonInterface { +public: + ScriptedThreadPlanPythonInterface(ScriptInterpreterPythonImpl &interpreter); + + llvm::Expected + CreatePluginObject(const llvm::StringRef class_name, + lldb::ThreadPlanSP thread_plan_sp, + const StructuredDataImpl &args_sp) override; + + llvm::Expected ExplainsStop(Event *event) override; + + llvm::Expected ShouldStop(Event *event) override; + + llvm::Expected IsStale() override; + + lldb::StateType GetRunState() override; + + llvm::Expected GetStopDescription(lldb_private::Stream *s) override; +}; +} // namespace lldb_private + +#endif // LLDB_ENABLE_PYTHON +#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDTHREADPLANPYTHONINTERFACE_H diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.cpp index 18e268527eb2fb..ba2ec0e78e9f53 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPythonInterface.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "lldb/Host/Config.h" +#include "lldb/Target/ExecutionContext.h" #include "lldb/Utility/Log.h" #include "lldb/lldb-enumerations.h" diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h index 7cdd5577919ba8..41f3a80a02b13b 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h @@ -96,12 +96,13 @@ class SWIGBridge { 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(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 stream_sb); static PythonObject ToSWIGWrapper(std::unique_ptr data_sb); static PythonObject @@ -111,7 +112,6 @@ class SWIGBridge { static python::ScopedPythonObject ToSWIGWrapper(CommandReturnObject &cmd_retobj); - static python::ScopedPythonObject 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. @@ -146,21 +146,6 @@ class SWIGBridge { 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); @@ -262,6 +247,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 diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp index 953f8b3aba18f7..b71f856efda2ea 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -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" @@ -1535,6 +1536,11 @@ ScriptInterpreterPythonImpl::CreateScriptedThreadInterface() { return std::make_shared(*this); } +ScriptedThreadPlanInterfaceSP +ScriptInterpreterPythonImpl::CreateScriptedThreadPlanInterface() { + return std::make_shared(*this); +} + OperatingSystemInterfaceSP ScriptInterpreterPythonImpl::CreateOperatingSystemInterface() { return std::make_shared(*this); @@ -1551,122 +1557,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, diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h index a33499816d8d38..da8e3a63d08470 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h @@ -77,34 +77,9 @@ class ScriptInterpreterPythonImpl : public ScriptInterpreterPython { 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 @@ class ScriptInterpreterPythonImpl : public ScriptInterpreterPython { lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override; + lldb::ScriptedThreadPlanInterfaceSP + CreateScriptedThreadPlanInterface() override; + lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() override; StructuredData::ObjectSP diff --git a/lldb/source/Target/ThreadPlanPython.cpp b/lldb/source/Target/ThreadPlanPython.cpp index d6de6b3c3cf049..48b3e3a1bcab61 100644 --- a/lldb/source/Target/ThreadPlanPython.cpp +++ b/lldb/source/Target/ThreadPlanPython.cpp @@ -32,6 +32,23 @@ 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 + 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 +77,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 +95,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 +113,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 +131,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 +166,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 +178,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; } diff --git a/lldb/test/API/functionalities/step_scripted/Steps.py b/lldb/test/API/functionalities/step_scripted/Steps.py index 7527607be847a5..3325dba7536571 100644 --- a/lldb/test/API/functionalities/step_scripted/Steps.py +++ b/lldb/test/API/functionalities/step_scripted/Steps.py @@ -47,7 +47,7 @@ def queue_child_thread_plan(self): # 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 @@ def stop_description(self, stream): 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)) diff --git a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp index 7f3359f6bf26b2..72dcf45a867e50 100644 --- a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp +++ b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp @@ -96,26 +96,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, @@ -170,6 +150,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; @@ -319,6 +309,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(); @@ -328,3 +323,13 @@ 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(); +}