//===----------------------------------------------------------------------===// // // 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/Thread.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 "ScriptedFrameProviderPythonInterface.h" #include using namespace lldb; using namespace lldb_private; using namespace lldb_private::python; using Locker = ScriptInterpreterPythonImpl::Locker; ScriptedFrameProviderPythonInterface::ScriptedFrameProviderPythonInterface( ScriptInterpreterPythonImpl &interpreter) : ScriptedFrameProviderInterface(), ScriptedPythonInterface(interpreter) {} bool ScriptedFrameProviderPythonInterface::AppliesToThread( llvm::StringRef class_name, lldb::ThreadSP thread_sp) { // If there is any issue with this method, we will just assume it also applies // to this thread which is the default behavior. constexpr bool fail_value = true; Status error; StructuredData::ObjectSP obj = CallStaticMethod(class_name, "applies_to_thread", error, thread_sp); if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return fail_value; return obj->GetBooleanValue(fail_value); } llvm::Expected ScriptedFrameProviderPythonInterface::CreatePluginObject( const llvm::StringRef class_name, lldb::StackFrameListSP input_frames, StructuredData::DictionarySP args_sp) { if (!input_frames) return llvm::createStringError("invalid frame list"); StructuredDataImpl sd_impl(args_sp); return ScriptedPythonInterface::CreatePluginObject(class_name, nullptr, input_frames, sd_impl); } std::string ScriptedFrameProviderPythonInterface::GetDescription( llvm::StringRef class_name) { Status error; StructuredData::ObjectSP obj = CallStaticMethod(class_name, "get_description", error); if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return {}; return obj->GetStringValue().str(); } StructuredData::ObjectSP ScriptedFrameProviderPythonInterface::GetFrameAtIndex(uint32_t index) { Status error; StructuredData::ObjectSP obj = Dispatch("get_frame_at_index", error, index); if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return {}; return obj; } bool ScriptedFrameProviderPythonInterface::CreateInstance( lldb::ScriptLanguage language, ScriptedInterfaceUsages usages) { if (language != eScriptLanguagePython) return false; return true; } void ScriptedFrameProviderPythonInterface::Initialize() { const std::vector ci_usages = { "target frame-provider register -C [-k key -v value ...]", "target frame-provider list", "target frame-provider remove ", "target frame-provider clear"}; const std::vector api_usages = { "SBTarget.RegisterScriptedFrameProvider", "SBTarget.RemoveScriptedFrameProvider", "SBTarget.ClearScriptedFrameProvider"}; PluginManager::RegisterPlugin( GetPluginNameStatic(), llvm::StringRef("Provide scripted stack frames for threads"), CreateInstance, eScriptLanguagePython, {ci_usages, api_usages}); } void ScriptedFrameProviderPythonInterface::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } #endif