diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig index 961fb2d1a76178..810673aaec5d19 100644 --- a/lldb/bindings/python/python-wrapper.swig +++ b/lldb/bindings/python/python-wrapper.swig @@ -301,6 +301,104 @@ unsigned int lldb_private::python::SWIGBridge::LLDBSwigPythonCallBreakpointResol return ret_val; } +PythonObject lldb_private::python::SWIGBridge::LLDBSwigPythonCreateScriptedStopHook( + lldb::TargetSP target_sp, const char *python_class_name, + const char *session_dictionary_name, const StructuredDataImpl &args_impl, + Status &error) { + if (python_class_name == NULL || python_class_name[0] == '\0') { + error = Status::FromErrorString("Empty class name."); + return PythonObject(); + } + if (!session_dictionary_name) { + error = Status::FromErrorString("No session dictionary"); + 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 = Status::FromErrorStringWithFormat("Could not find class: %s.", + python_class_name); + return PythonObject(); + } + + PythonObject result = + pfunc(SWIGBridge::ToSWIGWrapper(target_sp), SWIGBridge::ToSWIGWrapper(args_impl), dict); + + if (result.IsAllocated()) { + // Check that the handle_stop callback is defined: + auto callback_func = result.ResolveName("handle_stop"); + if (callback_func.IsAllocated()) { + if (auto args_info = callback_func.GetArgInfo()) { + size_t num_args = (*args_info).max_positional_args; + if (num_args != 2) { + error = Status::FromErrorStringWithFormat( + "Wrong number of args for " + "handle_stop callback, should be 2 (excluding self), got: %zu", + num_args); + return PythonObject(); + } else + return result; + } else { + error = Status::FromErrorString( + "Couldn't get num arguments for handle_stop " + "callback."); + return PythonObject(); + } + return result; + } else { + error = Status::FromErrorStringWithFormat( + "Class \"%s\" is missing the required " + "handle_stop callback.", + python_class_name); + } + } + return PythonObject(); +} + +bool lldb_private::python::SWIGBridge::LLDBSwigPythonStopHookCallHandleStop( + void *implementor, lldb::ExecutionContextRefSP exc_ctx_sp, + lldb::StreamSP stream) { + // handle_stop will return a bool with the meaning "should_stop"... + // If you return nothing we'll assume we are going to stop. + // Also any errors should return true, since we should stop on error. + + PyErr_Cleaner py_err_cleaner(false); + PythonObject self(PyRefType::Borrowed, static_cast(implementor)); + auto pfunc = self.ResolveName("handle_stop"); + + if (!pfunc.IsAllocated()) + return true; + + std::shared_ptr sb_stream = std::make_shared(); + PythonObject sb_stream_arg = SWIGBridge::ToSWIGWrapper(sb_stream); + PythonObject result = + pfunc(SWIGBridge::ToSWIGWrapper(std::move(exc_ctx_sp)), sb_stream_arg); + + if (PyErr_Occurred()) { + stream->PutCString("Python error occurred handling stop-hook."); + PyErr_Print(); + PyErr_Clear(); + return true; + } + + // Now add the result to the output stream. SBStream only + // 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; + else + return true; +} + // wrapper that calls an optional instance member of an object taking no // arguments static PyObject *LLDBSwigPython_CallOptionalMember( @@ -579,19 +677,6 @@ void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyOb return sb_ptr; } -void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBExecutionContext(PyObject * - data) { - lldb::SBExecutionContext *sb_ptr = NULL; - - int valid_cast = SWIG_ConvertPtr(data, (void **)&sb_ptr, - SWIGTYPE_p_lldb__SBExecutionContext, 0); - - if (valid_cast == -1) - return NULL; - - return sb_ptr; -} - bool lldb_private::python::SWIGBridge::LLDBSwigPythonCallCommand( const char *python_function_name, const char *session_dictionary_name, lldb::DebuggerSP debugger, const char *args, diff --git a/lldb/include/lldb/API/SBExecutionContext.h b/lldb/include/lldb/API/SBExecutionContext.h index e1e08fe3f4aae4..e8de2ebe58785e 100644 --- a/lldb/include/lldb/API/SBExecutionContext.h +++ b/lldb/include/lldb/API/SBExecutionContext.h @@ -16,7 +16,6 @@ #include namespace lldb_private { -class ScriptInterpreter; namespace python { class SWIGBridge; } @@ -56,7 +55,6 @@ class LLDB_API SBExecutionContext { protected: friend class lldb_private::python::SWIGBridge; - friend class lldb_private::ScriptInterpreter; lldb_private::ExecutionContextRef *get() const; diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedStopHookInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedStopHookInterface.h deleted file mode 100644 index 125e7f2077b543..00000000000000 --- a/lldb/include/lldb/Interpreter/Interfaces/ScriptedStopHookInterface.h +++ /dev/null @@ -1,33 +0,0 @@ -//===-- ScriptedStopHookInterface.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_SCRIPTEDSTOPHOOKINTERFACE_H -#define LLDB_INTERPRETER_INTERFACES_SCRIPTEDSTOPHOOKINTERFACE_H - -#include "lldb/lldb-private.h" - -#include "ScriptedInterface.h" - -namespace lldb_private { -class ScriptedStopHookInterface : public ScriptedInterface { -public: - virtual llvm::Expected - CreatePluginObject(llvm::StringRef class_name, lldb::TargetSP target_sp, - const StructuredDataImpl &args_sp) = 0; - - /// "handle_stop" will return a bool with the meaning "should_stop"... - /// If nothing is returned, we'll assume we are going to stop. - /// Also any errors should return true, since we should stop on error. - virtual llvm::Expected HandleStop(ExecutionContext &exe_ctx, - lldb::StreamSP output_sp) { - return true; - } -}; -} // namespace lldb_private - -#endif // LLDB_INTERPRETER_INTERFACES_SCRIPTEDSTOPHOOKINTERFACE_H diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h index 901ecf3012d51d..addb1394ab5652 100644 --- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h +++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -14,7 +14,6 @@ #include "lldb/API/SBData.h" #include "lldb/API/SBError.h" #include "lldb/API/SBEvent.h" -#include "lldb/API/SBExecutionContext.h" #include "lldb/API/SBLaunchInfo.h" #include "lldb/API/SBMemoryRegionInfo.h" #include "lldb/API/SBStream.h" @@ -272,6 +271,24 @@ class ScriptInterpreter : public PluginInterface { return lldb::eSearchDepthModule; } + virtual StructuredData::GenericSP + CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name, + const StructuredDataImpl &args_data, Status &error) { + error = + Status::FromErrorString("Creating scripted stop-hooks with the current " + "script interpreter is not supported."); + return StructuredData::GenericSP(); + } + + // This dispatches to the handle_stop method of the stop-hook class. It + // returns a "should_stop" bool. + virtual bool + ScriptedStopHookHandleStop(StructuredData::GenericSP implementor_sp, + ExecutionContext &exc_ctx, + lldb::StreamSP stream_sp) { + return true; + } + virtual StructuredData::ObjectSP LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error) { return StructuredData::ObjectSP(); @@ -544,10 +561,6 @@ class ScriptInterpreter : public PluginInterface { return {}; } - virtual lldb::ScriptedStopHookInterfaceSP CreateScriptedStopHookInterface() { - return {}; - } - virtual StructuredData::ObjectSP CreateStructuredDataFromScriptObject(ScriptObject obj) { return {}; @@ -574,9 +587,6 @@ class ScriptInterpreter : public PluginInterface { std::optional GetOpaqueTypeFromSBMemoryRegionInfo( const lldb::SBMemoryRegionInfo &mem_region) const; - lldb::ExecutionContextRefSP GetOpaqueTypeFromSBExecutionContext( - const lldb::SBExecutionContext &exe_ctx) const; - protected: Debugger &m_debugger; lldb::ScriptLanguage m_script_lang; diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index e4848f19e64d62..50df01aac74004 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -1391,7 +1391,8 @@ class Target : public std::enable_shared_from_this, /// This holds the dictionary of keys & values that can be used to /// parametrize any given callback's behavior. StructuredDataImpl m_extra_args; - lldb::ScriptedStopHookInterfaceSP m_interface_sp; + /// This holds the python callback object. + StructuredData::GenericSP m_implementation_sp; /// Use CreateStopHook to make a new empty stop hook. The GetCommandPointer /// and fill it with commands, and SetSpecifier to set the specifier shared diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index d09edeeccaff1a..5fb288ad43af48 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -190,7 +190,6 @@ class ScriptInterpreterLocker; class ScriptedMetadata; class ScriptedPlatformInterface; class ScriptedProcessInterface; -class ScriptedStopHookInterface; class ScriptedThreadInterface; class ScriptedThreadPlanInterface; class ScriptedSyntheticChildren; @@ -409,8 +408,6 @@ typedef std::unique_ptr ScriptedPlatformInterfaceUP; typedef std::unique_ptr ScriptedProcessInterfaceUP; -typedef std::shared_ptr - ScriptedStopHookInterfaceSP; typedef std::shared_ptr ScriptedThreadInterfaceSP; typedef std::shared_ptr diff --git a/lldb/source/Interpreter/ScriptInterpreter.cpp b/lldb/source/Interpreter/ScriptInterpreter.cpp index 559b8301c10106..8b55221da6e761 100644 --- a/lldb/source/Interpreter/ScriptInterpreter.cpp +++ b/lldb/source/Interpreter/ScriptInterpreter.cpp @@ -125,12 +125,6 @@ ScriptInterpreter::GetOpaqueTypeFromSBMemoryRegionInfo( return *mem_region.m_opaque_up.get(); } -lldb::ExecutionContextRefSP -ScriptInterpreter::GetOpaqueTypeFromSBExecutionContext( - const lldb::SBExecutionContext &exe_ctx) const { - return exe_ctx.m_exe_ctx_sp; -} - lldb::ScriptLanguage ScriptInterpreter::StringToLanguage(const llvm::StringRef &language) { if (language.equals_insensitive(LanguageToString(eScriptLanguageNone))) diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt index ee5e48ad5cdc37..6ba714ed1c263e 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt @@ -25,7 +25,6 @@ add_lldb_library(lldbPluginScriptInterpreterPythonInterfaces PLUGIN ScriptedPlatformPythonInterface.cpp ScriptedProcessPythonInterface.cpp ScriptedPythonInterface.cpp - ScriptedStopHookPythonInterface.cpp ScriptedThreadPlanPythonInterface.cpp ScriptedThreadPythonInterface.cpp diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp index 1fd32993e385eb..38b644366080e4 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp @@ -28,7 +28,6 @@ void ScriptInterpreterPythonInterfaces::Initialize() { OperatingSystemPythonInterface::Initialize(); ScriptedPlatformPythonInterface::Initialize(); ScriptedProcessPythonInterface::Initialize(); - ScriptedStopHookPythonInterface::Initialize(); ScriptedThreadPlanPythonInterface::Initialize(); } @@ -36,7 +35,6 @@ void ScriptInterpreterPythonInterfaces::Terminate() { OperatingSystemPythonInterface::Terminate(); ScriptedPlatformPythonInterface::Terminate(); ScriptedProcessPythonInterface::Terminate(); - ScriptedStopHookPythonInterface::Terminate(); ScriptedThreadPlanPythonInterface::Terminate(); } diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h index 26c80b75686918..36b521480cc85c 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h @@ -18,7 +18,6 @@ #include "OperatingSystemPythonInterface.h" #include "ScriptedPlatformPythonInterface.h" #include "ScriptedProcessPythonInterface.h" -#include "ScriptedStopHookPythonInterface.h" #include "ScriptedThreadPlanPythonInterface.h" namespace lldb_private { diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp index cf11c06e8a95d4..a8e1d09da0bf12 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp @@ -159,23 +159,4 @@ ScriptedPythonInterface::ExtractValueFromPythonObject< return m_interpreter.GetOpaqueTypeFromSBMemoryRegionInfo(*sb_mem_reg_info); } -template <> -lldb::ExecutionContextRefSP -ScriptedPythonInterface::ExtractValueFromPythonObject< - lldb::ExecutionContextRefSP>(python::PythonObject &p, Status &error) { - - lldb::SBExecutionContext *sb_exe_ctx = - reinterpret_cast( - python::LLDBSWIGPython_CastPyObjectToSBExecutionContext(p.get())); - - if (!sb_exe_ctx) { - error = Status::FromErrorStringWithFormat( - "Couldn't cast lldb::SBExecutionContext to " - "lldb::ExecutionContextRefSP."); - return {}; - } - - return m_interpreter.GetOpaqueTypeFromSBExecutionContext(*sb_exe_ctx); -} - #endif diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h index 4b9f463ef5605d..c715295eb9ff02 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h @@ -180,35 +180,12 @@ class ScriptedPythonInterface : virtual public ScriptedInterface { llvm::Expected expected_return_object = create_error("Resulting object is not initialized."); - // This relax the requirement on the number of argument for - // initializing scripting extension if the size of the interface - // parameter pack contains 1 less element than the extension maximum - // number of positional arguments for this initializer. - // - // This addresses the cases where the embedded interpreter session - // dictionary is passed to the extension initializer which is not used - // most of the time. - size_t num_args = sizeof...(Args); - if (num_args != arg_info->max_positional_args) { - if (num_args != arg_info->max_positional_args - 1) - return create_error("Passed arguments ({0}) doesn't match the number " - "of expected arguments ({1}).", - num_args, arg_info->max_positional_args); - - std::apply( - [&init, &expected_return_object](auto &&...args) { - llvm::consumeError(expected_return_object.takeError()); - expected_return_object = init(args...); - }, - std::tuple_cat(transformed_args, std::make_tuple(dict))); - } else { - std::apply( - [&init, &expected_return_object](auto &&...args) { - llvm::consumeError(expected_return_object.takeError()); - expected_return_object = init(args...); - }, - transformed_args); - } + std::apply( + [&init, &expected_return_object](auto &&...args) { + llvm::consumeError(expected_return_object.takeError()); + expected_return_object = init(args...); + }, + transformed_args); if (!expected_return_object) return expected_return_object.takeError(); @@ -428,10 +405,6 @@ class ScriptedPythonInterface : virtual public ScriptedInterface { return python::SWIGBridge::ToSWIGWrapper(arg); } - python::PythonObject Transform(lldb::TargetSP arg) { - return python::SWIGBridge::ToSWIGWrapper(arg); - } - python::PythonObject Transform(lldb::ProcessSP arg) { return python::SWIGBridge::ToSWIGWrapper(arg); } @@ -584,11 +557,6 @@ std::optional ScriptedPythonInterface::ExtractValueFromPythonObject< std::optional>(python::PythonObject &p, Status &error); -template <> -lldb::ExecutionContextRefSP -ScriptedPythonInterface::ExtractValueFromPythonObject< - lldb::ExecutionContextRefSP>(python::PythonObject &p, Status &error); - } // namespace lldb_private #endif // LLDB_ENABLE_PYTHON diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedStopHookPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedStopHookPythonInterface.cpp deleted file mode 100644 index 6cec7d6e7553d4..00000000000000 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedStopHookPythonInterface.cpp +++ /dev/null @@ -1,75 +0,0 @@ -//===-- ScriptedStopHookPythonInterface.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/Core/PluginManager.h" -#include "lldb/Host/Config.h" -#include "lldb/Target/ExecutionContext.h" -#include "lldb/Utility/Log.h" -#include "lldb/lldb-enumerations.h" - -#if LLDB_ENABLE_PYTHON - -// clang-format off -// LLDB Python header must be included first -#include "../lldb-python.h" -//clang-format on - -#include "../SWIGPythonBridge.h" -#include "../ScriptInterpreterPythonImpl.h" -#include "ScriptedStopHookPythonInterface.h" - -using namespace lldb; -using namespace lldb_private; -using namespace lldb_private::python; - -ScriptedStopHookPythonInterface::ScriptedStopHookPythonInterface( - ScriptInterpreterPythonImpl &interpreter) - : ScriptedStopHookInterface(), ScriptedPythonInterface(interpreter) {} - -llvm::Expected -ScriptedStopHookPythonInterface::CreatePluginObject(llvm::StringRef class_name, - lldb::TargetSP target_sp, - const StructuredDataImpl &args_sp) { - return ScriptedPythonInterface::CreatePluginObject(class_name, nullptr, - target_sp, args_sp); -} - -llvm::Expected -ScriptedStopHookPythonInterface::HandleStop(ExecutionContext &exe_ctx, - lldb::StreamSP output_sp) { - ExecutionContextRefSP exe_ctx_ref_sp = - std::make_shared(exe_ctx); - Status error; - StructuredData::ObjectSP obj = Dispatch("handle_stop", error, exe_ctx_ref_sp, output_sp); - - if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, - error)) { - if (!obj) - return true; - return error.ToError(); - } - - return obj->GetBooleanValue(); -} - - -void ScriptedStopHookPythonInterface::Initialize() { - const std::vector ci_usages = { - "target stop-hook add -P [-k key -v value ...]"}; - const std::vector api_usages = {}; - PluginManager::RegisterPlugin( - GetPluginNameStatic(), - llvm::StringRef("Perform actions whenever the process stops, before control is returned to the user."), - CreateInstance, eScriptLanguagePython, {ci_usages, api_usages}); -} - -void ScriptedStopHookPythonInterface::Terminate() { - PluginManager::UnregisterPlugin(CreateInstance); -} - -#endif diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedStopHookPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedStopHookPythonInterface.h deleted file mode 100644 index 8548d8d7fcce0f..00000000000000 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedStopHookPythonInterface.h +++ /dev/null @@ -1,51 +0,0 @@ -//===-- ScriptedStopHookPythonInterface.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_SCRIPTEDSTOPHOOKPYTHONINTERFACE_H -#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDSTOPHOOKPYTHONINTERFACE_H - -#include "lldb/Host/Config.h" -#include "lldb/Interpreter/Interfaces/ScriptedStopHookInterface.h" - -#if LLDB_ENABLE_PYTHON - -#include "ScriptedPythonInterface.h" - -namespace lldb_private { -class ScriptedStopHookPythonInterface : public ScriptedStopHookInterface, - public ScriptedPythonInterface, - public PluginInterface { -public: - ScriptedStopHookPythonInterface(ScriptInterpreterPythonImpl &interpreter); - - llvm::Expected - CreatePluginObject(llvm::StringRef class_name, lldb::TargetSP target_sp, - const StructuredDataImpl &args_sp) override; - - llvm::SmallVector - GetAbstractMethodRequirements() const override { - return llvm::SmallVector({{"handle_stop", 2}}); - } - - llvm::Expected HandleStop(ExecutionContext &exe_ctx, - lldb::StreamSP output_sp) override; - - static void Initialize(); - - static void Terminate(); - - static llvm::StringRef GetPluginNameStatic() { - return "ScriptedStopHookPythonInterface"; - } - - llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } -}; -} // namespace lldb_private - -#endif // LLDB_ENABLE_PYTHON -#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDSTOPHOOKPYTHONINTERFACE_H diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h index 8888a1e415deba..97a3837fd7aa62 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h @@ -157,6 +157,16 @@ class SWIGBridge { const char *method_name, lldb_private::SymbolContext *sym_ctx); + static python::PythonObject LLDBSwigPythonCreateScriptedStopHook( + lldb::TargetSP target_sp, const char *python_class_name, + const char *session_dictionary_name, const StructuredDataImpl &args, + lldb_private::Status &error); + + static bool + LLDBSwigPythonStopHookCallHandleStop(void *implementor, + lldb::ExecutionContextRefSP exc_ctx, + lldb::StreamSP stream); + static size_t LLDBSwigPython_CalculateNumChildren(PyObject *implementor, uint32_t max); @@ -256,7 +266,6 @@ void *LLDBSWIGPython_CastPyObjectToSBEvent(PyObject *data); void *LLDBSWIGPython_CastPyObjectToSBStream(PyObject *data); void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data); void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data); -void *LLDBSWIGPython_CastPyObjectToSBExecutionContext(PyObject *data); } // namespace python } // namespace lldb_private diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp index 155efc06eaf41a..63691d24f0dadb 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -1559,11 +1559,6 @@ ScriptInterpreterPythonImpl::CreateScriptedProcessInterface() { return std::make_unique(*this); } -ScriptedStopHookInterfaceSP -ScriptInterpreterPythonImpl::CreateScriptedStopHookInterface() { - return std::make_shared(*this); -} - ScriptedThreadInterfaceSP ScriptInterpreterPythonImpl::CreateScriptedThreadInterface() { return std::make_shared(*this); @@ -1659,6 +1654,57 @@ ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchDepth( return lldb::eSearchDepthModule; } +StructuredData::GenericSP ScriptInterpreterPythonImpl::CreateScriptedStopHook( + TargetSP target_sp, const char *class_name, + const StructuredDataImpl &args_data, Status &error) { + + if (!target_sp) { + error = Status::FromErrorString("No target for scripted stop-hook."); + return StructuredData::GenericSP(); + } + + if (class_name == nullptr || class_name[0] == '\0') { + error = Status::FromErrorString("No class name for scripted stop-hook."); + return StructuredData::GenericSP(); + } + + ScriptInterpreterPythonImpl *python_interpreter = + GetPythonInterpreter(m_debugger); + + if (!python_interpreter) { + error = Status::FromErrorString( + "No script interpreter for scripted stop-hook."); + return StructuredData::GenericSP(); + } + + Locker py_lock(this, + Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + + PythonObject ret_val = SWIGBridge::LLDBSwigPythonCreateScriptedStopHook( + target_sp, class_name, python_interpreter->m_dictionary_name.c_str(), + args_data, error); + + return StructuredData::GenericSP( + new StructuredPythonObject(std::move(ret_val))); +} + +bool ScriptInterpreterPythonImpl::ScriptedStopHookHandleStop( + StructuredData::GenericSP implementor_sp, ExecutionContext &exc_ctx, + lldb::StreamSP stream_sp) { + assert(implementor_sp && + "can't call a stop hook with an invalid implementor"); + assert(stream_sp && "can't call a stop hook with an invalid stream"); + + Locker py_lock(this, + Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + + lldb::ExecutionContextRefSP exc_ctx_ref_sp(new ExecutionContextRef(exc_ctx)); + + bool ret_val = SWIGBridge::LLDBSwigPythonStopHookCallHandleStop( + implementor_sp->GetValue(), exc_ctx_ref_sp, stream_sp); + return ret_val; +} + StructuredData::ObjectSP ScriptInterpreterPythonImpl::LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error) { diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h index d15e2fd76f683b..85d79955e45efc 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h @@ -91,6 +91,15 @@ class ScriptInterpreterPythonImpl : public ScriptInterpreterPython { lldb::SearchDepth ScriptedBreakpointResolverSearchDepth( StructuredData::GenericSP implementor_sp) override; + StructuredData::GenericSP + CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name, + const StructuredDataImpl &args_data, + Status &error) override; + + bool ScriptedStopHookHandleStop(StructuredData::GenericSP implementor_sp, + ExecutionContext &exc_ctx, + lldb::StreamSP stream_sp) override; + StructuredData::GenericSP CreateFrameRecognizer(const char *class_name) override; @@ -103,8 +112,6 @@ class ScriptInterpreterPythonImpl : public ScriptInterpreterPython { lldb::ScriptedProcessInterfaceUP CreateScriptedProcessInterface() override; - lldb::ScriptedStopHookInterfaceSP CreateScriptedStopHookInterface() override; - lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override; lldb::ScriptedThreadPlanInterfaceSP diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 14c7702e2f5fbc..f1659aae0800db 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -36,7 +36,6 @@ #include "lldb/Host/StreamFile.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" -#include "lldb/Interpreter/Interfaces/ScriptedStopHookInterface.h" #include "lldb/Interpreter/OptionGroupWatchpoint.h" #include "lldb/Interpreter/OptionValues.h" #include "lldb/Interpreter/Property.h" @@ -3869,32 +3868,13 @@ Status Target::StopHookScripted::SetScriptCallback( return error; } - m_interface_sp = script_interp->CreateScriptedStopHookInterface(); - if (!m_interface_sp) { - error = Status::FromErrorStringWithFormat( - "ScriptedStopHook::%s () - ERROR: %s", __FUNCTION__, - "Script interpreter couldn't create Scripted Stop Hook Interface"); - return error; - } - m_class_name = class_name; m_extra_args.SetObjectSP(extra_args_sp); - auto obj_or_err = m_interface_sp->CreatePluginObject( - m_class_name, GetTarget(), m_extra_args); - if (!obj_or_err) { - return Status::FromError(obj_or_err.takeError()); - } - - StructuredData::ObjectSP object_sp = *obj_or_err; - if (!object_sp || !object_sp->IsValid()) { - error = Status::FromErrorStringWithFormat( - "ScriptedStopHook::%s () - ERROR: %s", __FUNCTION__, - "Failed to create valid script object"); - return error; - } + m_implementation_sp = script_interp->CreateScriptedStopHook( + GetTarget(), m_class_name.c_str(), m_extra_args, error); - return {}; + return error; } Target::StopHook::StopHookResult @@ -3903,15 +3883,16 @@ Target::StopHookScripted::HandleStop(ExecutionContext &exc_ctx, assert(exc_ctx.GetTargetPtr() && "Can't call HandleStop on a context " "with no target"); - if (!m_interface_sp) + ScriptInterpreter *script_interp = + GetTarget()->GetDebugger().GetScriptInterpreter(); + if (!script_interp) return StopHookResult::KeepStopped; - auto should_stop_or_err = m_interface_sp->HandleStop(exc_ctx, output_sp); - if (!should_stop_or_err) - return StopHookResult::KeepStopped; + bool should_stop = script_interp->ScriptedStopHookHandleStop( + m_implementation_sp, exc_ctx, output_sp); - return *should_stop_or_err ? StopHookResult::KeepStopped - : StopHookResult::RequestContinue; + return should_stop ? StopHookResult::KeepStopped + : StopHookResult::RequestContinue; } void Target::StopHookScripted::GetSubclassDescription( diff --git a/lldb/test/API/commands/target/stop-hooks/TestStopHookScripted.py b/lldb/test/API/commands/target/stop-hooks/TestStopHookScripted.py index 7c10669442b1c2..b865fd0c0a44f3 100644 --- a/lldb/test/API/commands/target/stop-hooks/TestStopHookScripted.py +++ b/lldb/test/API/commands/target/stop-hooks/TestStopHookScripted.py @@ -32,7 +32,7 @@ def test_bad_handler(self): self.interp.HandleCommand(command, result) self.assertFalse(result.Succeeded(), "Set the target stop hook") self.assertIn( - "has unexpected argument count", + "Wrong number of args", result.GetError(), "Got the wrong number of args error", ) @@ -43,7 +43,7 @@ def test_bad_handler(self): self.interp.HandleCommand(command, result) self.assertFalse(result.Succeeded(), "Set the target stop hook") self.assertIn( - "Abstract method no_handle_stop.handle_stop not implemented", + 'Class "stop_hook.no_handle_stop" is missing the required handle_stop callback', result.GetError(), "Got the right error", ) diff --git a/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py b/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py index 2721d961bcb9d5..cb07bf32c5080e 100644 --- a/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py +++ b/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py @@ -8,7 +8,7 @@ class DummyStopHook: - def __init__(self, target, args): + def __init__(self, target, args, internal_dict): self.target = target self.args = args diff --git a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp index a9e908ec4792c5..f2746c3e2516fd 100644 --- a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp +++ b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp @@ -154,11 +154,6 @@ void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo( return nullptr; } -void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBExecutionContext( - PyObject *data) { - return nullptr; -} - lldb::ValueObjectSP lldb_private::python::SWIGBridge::LLDBSWIGPython_GetValueObjectSPFromSBValue( void *data) { @@ -273,6 +268,20 @@ void *lldb_private::python::SWIGBridge::LLDBSWIGPython_GetDynamicSetting( return nullptr; } +python::PythonObject +lldb_private::python::SWIGBridge::LLDBSwigPythonCreateScriptedStopHook( + lldb::TargetSP target_sp, const char *python_class_name, + const char *session_dictionary_name, const StructuredDataImpl &args_impl, + Status &error) { + return python::PythonObject(); +} + +bool lldb_private::python::SWIGBridge::LLDBSwigPythonStopHookCallHandleStop( + void *implementor, lldb::ExecutionContextRefSP exc_ctx_sp, + lldb::StreamSP stream) { + return false; +} + python::PythonObject lldb_private::python::SWIGBridge::ToSWIGWrapper(Status status) { return python::PythonObject();