diff options
Diffstat (limited to 'lldb/source/Plugins/ScriptInterpreter/Python')
10 files changed, 195 insertions, 76 deletions
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt index 6ba714e..ee5e48a 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt @@ -25,6 +25,7 @@ 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 38b6443..1fd3299 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp @@ -28,6 +28,7 @@ void ScriptInterpreterPythonInterfaces::Initialize() { OperatingSystemPythonInterface::Initialize(); ScriptedPlatformPythonInterface::Initialize(); ScriptedProcessPythonInterface::Initialize(); + ScriptedStopHookPythonInterface::Initialize(); ScriptedThreadPlanPythonInterface::Initialize(); } @@ -35,6 +36,7 @@ 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 36b5214..26c80b7 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h @@ -18,6 +18,7 @@ #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 a8e1d09..cf11c06 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp @@ -159,4 +159,23 @@ 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<lldb::SBExecutionContext *>( + 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 c715295..4b9f463 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h @@ -180,12 +180,35 @@ public: llvm::Expected<PythonObject> expected_return_object = create_error("Resulting object is not initialized."); - std::apply( - [&init, &expected_return_object](auto &&...args) { - llvm::consumeError(expected_return_object.takeError()); - expected_return_object = init(args...); - }, - transformed_args); + // 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); + } if (!expected_return_object) return expected_return_object.takeError(); @@ -405,6 +428,10 @@ protected: 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); } @@ -557,6 +584,11 @@ std::optional<MemoryRegionInfo> ScriptedPythonInterface::ExtractValueFromPythonObject< std::optional<MemoryRegionInfo>>(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 new file mode 100644 index 0000000..6cec7d6 --- /dev/null +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedStopHookPythonInterface.cpp @@ -0,0 +1,75 @@ +//===-- 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<StructuredData::GenericSP> +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<bool> +ScriptedStopHookPythonInterface::HandleStop(ExecutionContext &exe_ctx, + lldb::StreamSP output_sp) { + ExecutionContextRefSP exe_ctx_ref_sp = + std::make_shared<ExecutionContextRef>(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<llvm::StringRef> ci_usages = { + "target stop-hook add -P <script-name> [-k key -v value ...]"}; + const std::vector<llvm::StringRef> 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 new file mode 100644 index 0000000..8548d8d --- /dev/null +++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedStopHookPythonInterface.h @@ -0,0 +1,51 @@ +//===-- 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<StructuredData::GenericSP> + CreatePluginObject(llvm::StringRef class_name, lldb::TargetSP target_sp, + const StructuredDataImpl &args_sp) override; + + llvm::SmallVector<AbstractMethodRequirement> + GetAbstractMethodRequirements() const override { + return llvm::SmallVector<AbstractMethodRequirement>({{"handle_stop", 2}}); + } + + llvm::Expected<bool> 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 97a3837..8888a1e 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h @@ -157,16 +157,6 @@ public: 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); @@ -266,6 +256,7 @@ 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 63691d2..155efc0 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -1559,6 +1559,11 @@ ScriptInterpreterPythonImpl::CreateScriptedProcessInterface() { return std::make_unique<ScriptedProcessPythonInterface>(*this); } +ScriptedStopHookInterfaceSP +ScriptInterpreterPythonImpl::CreateScriptedStopHookInterface() { + return std::make_shared<ScriptedStopHookPythonInterface>(*this); +} + ScriptedThreadInterfaceSP ScriptInterpreterPythonImpl::CreateScriptedThreadInterface() { return std::make_shared<ScriptedThreadPythonInterface>(*this); @@ -1654,57 +1659,6 @@ 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 85d7995..d15e2fd 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h @@ -92,15 +92,6 @@ public: 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; lldb::ValueObjectListSP @@ -112,6 +103,8 @@ public: lldb::ScriptedProcessInterfaceUP CreateScriptedProcessInterface() override; + lldb::ScriptedStopHookInterfaceSP CreateScriptedStopHookInterface() override; + lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override; lldb::ScriptedThreadPlanInterfaceSP |