diff options
Diffstat (limited to 'lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp')
| -rw-r--r-- | lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp | 230 |
1 files changed, 153 insertions, 77 deletions
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp b/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp index 6519df9..70ce101 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp @@ -7,42 +7,77 @@ //===----------------------------------------------------------------------===// #include "ScriptedFrame.h" - +#include "Plugins/Process/Utility/RegisterContextMemory.h" + +#include "lldb/Core/Address.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleList.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Interpreter/Interfaces/ScriptedFrameInterface.h" +#include "lldb/Interpreter/Interfaces/ScriptedThreadInterface.h" +#include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/Symbol/CompileUnit.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/SymbolFile.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/StructuredData.h" using namespace lldb; using namespace lldb_private; +char ScriptedFrame::ID; + void ScriptedFrame::CheckInterpreterAndScriptObject() const { lldbassert(m_script_object_sp && "Invalid Script Object."); lldbassert(GetInterface() && "Invalid Scripted Frame Interface."); } llvm::Expected<std::shared_ptr<ScriptedFrame>> -ScriptedFrame::Create(ScriptedThread &thread, +ScriptedFrame::Create(ThreadSP thread_sp, + ScriptedThreadInterfaceSP scripted_thread_interface_sp, StructuredData::DictionarySP args_sp, StructuredData::Generic *script_object) { - if (!thread.IsValid()) - return llvm::createStringError("Invalid scripted thread."); + if (!thread_sp || !thread_sp->IsValid()) + return llvm::createStringError("invalid thread"); + + ProcessSP process_sp = thread_sp->GetProcess(); + if (!process_sp || !process_sp->IsValid()) + return llvm::createStringError("invalid process"); - thread.CheckInterpreterAndScriptObject(); + ScriptInterpreter *script_interp = + process_sp->GetTarget().GetDebugger().GetScriptInterpreter(); + if (!script_interp) + return llvm::createStringError("no script interpreter"); - auto scripted_frame_interface = - thread.GetInterface()->CreateScriptedFrameInterface(); + auto scripted_frame_interface = script_interp->CreateScriptedFrameInterface(); if (!scripted_frame_interface) return llvm::createStringError("failed to create scripted frame interface"); llvm::StringRef frame_class_name; if (!script_object) { - std::optional<std::string> class_name = - thread.GetInterface()->GetScriptedFramePluginName(); - if (!class_name || class_name->empty()) + // If no script object is provided and we have a scripted thread interface, + // try to get the frame class name from it. + if (scripted_thread_interface_sp) { + std::optional<std::string> class_name = + scripted_thread_interface_sp->GetScriptedFramePluginName(); + if (!class_name || class_name->empty()) + return llvm::createStringError( + "failed to get scripted frame class name"); + frame_class_name = *class_name; + } else { return llvm::createStringError( - "failed to get scripted thread class name"); - frame_class_name = *class_name; + "no script object provided and no scripted thread interface"); + } } - ExecutionContext exe_ctx(thread); + ExecutionContext exe_ctx(thread_sp); auto obj_or_err = scripted_frame_interface->CreatePluginObject( frame_class_name, exe_ctx, args_sp, script_object); @@ -62,66 +97,43 @@ ScriptedFrame::Create(ScriptedThread &thread, SymbolContext sc; Address symbol_addr; if (pc != LLDB_INVALID_ADDRESS) { - symbol_addr.SetLoadAddress(pc, &thread.GetProcess()->GetTarget()); + symbol_addr.SetLoadAddress(pc, &process_sp->GetTarget()); symbol_addr.CalculateSymbolContext(&sc); } std::optional<SymbolContext> maybe_sym_ctx = scripted_frame_interface->GetSymbolContext(); - if (maybe_sym_ctx) { + if (maybe_sym_ctx) sc = *maybe_sym_ctx; - } - - StructuredData::DictionarySP reg_info = - scripted_frame_interface->GetRegisterInfo(); - - if (!reg_info) - return llvm::createStringError( - "failed to get scripted thread registers info"); - - std::shared_ptr<DynamicRegisterInfo> register_info_sp = - DynamicRegisterInfo::Create( - *reg_info, thread.GetProcess()->GetTarget().GetArchitecture()); lldb::RegisterContextSP reg_ctx_sp; - - std::optional<std::string> reg_data = - scripted_frame_interface->GetRegisterContext(); - if (reg_data) { - DataBufferSP data_sp( - std::make_shared<DataBufferHeap>(reg_data->c_str(), reg_data->size())); - - if (!data_sp->GetByteSize()) - return llvm::createStringError("failed to copy raw registers data"); - - std::shared_ptr<RegisterContextMemory> reg_ctx_memory = - std::make_shared<RegisterContextMemory>( - thread, frame_id, *register_info_sp, LLDB_INVALID_ADDRESS); - if (!reg_ctx_memory) - return llvm::createStringError("failed to create a register context."); - - reg_ctx_memory->SetAllRegisterData(data_sp); - reg_ctx_sp = reg_ctx_memory; - } - - return std::make_shared<ScriptedFrame>( - thread, scripted_frame_interface, frame_id, pc, sc, reg_ctx_sp, - register_info_sp, owned_script_object_sp); + auto regs_or_err = + CreateRegisterContext(*scripted_frame_interface, *thread_sp, frame_id); + if (!regs_or_err) + LLDB_LOG_ERROR(GetLog(LLDBLog::Thread), regs_or_err.takeError(), "{0}"); + else + reg_ctx_sp = *regs_or_err; + + return std::make_shared<ScriptedFrame>(thread_sp, scripted_frame_interface, + frame_id, pc, sc, reg_ctx_sp, + owned_script_object_sp); } -ScriptedFrame::ScriptedFrame(ScriptedThread &thread, +ScriptedFrame::ScriptedFrame(ThreadSP thread_sp, ScriptedFrameInterfaceSP interface_sp, lldb::user_id_t id, lldb::addr_t pc, SymbolContext &sym_ctx, lldb::RegisterContextSP reg_ctx_sp, - std::shared_ptr<DynamicRegisterInfo> reg_info_sp, StructuredData::GenericSP script_object_sp) - : StackFrame(thread.shared_from_this(), /*frame_idx=*/id, + : StackFrame(thread_sp, /*frame_idx=*/id, /*concrete_frame_idx=*/id, /*reg_context_sp=*/reg_ctx_sp, /*cfa=*/0, /*pc=*/pc, /*behaves_like_zeroth_frame=*/!id, /*symbol_ctx=*/&sym_ctx), m_scripted_frame_interface_sp(interface_sp), - m_script_object_sp(script_object_sp), m_register_info_sp(reg_info_sp) {} + m_script_object_sp(script_object_sp) { + // FIXME: This should be part of the base class constructor. + m_stack_frame_kind = StackFrame::Kind::Synthetic; +} ScriptedFrame::~ScriptedFrame() {} @@ -129,7 +141,7 @@ const char *ScriptedFrame::GetFunctionName() { CheckInterpreterAndScriptObject(); std::optional<std::string> function_name = GetInterface()->GetFunctionName(); if (!function_name) - return nullptr; + return StackFrame::GetFunctionName(); return ConstString(function_name->c_str()).AsCString(); } @@ -138,7 +150,7 @@ const char *ScriptedFrame::GetDisplayFunctionName() { std::optional<std::string> function_name = GetInterface()->GetDisplayFunctionName(); if (!function_name) - return nullptr; + return StackFrame::GetDisplayFunctionName(); return ConstString(function_name->c_str()).AsCString(); } @@ -157,35 +169,99 @@ lldb::ScriptedFrameInterfaceSP ScriptedFrame::GetInterface() const { std::shared_ptr<DynamicRegisterInfo> ScriptedFrame::GetDynamicRegisterInfo() { CheckInterpreterAndScriptObject(); - if (!m_register_info_sp) { - StructuredData::DictionarySP reg_info = GetInterface()->GetRegisterInfo(); + StructuredData::DictionarySP reg_info = GetInterface()->GetRegisterInfo(); + + Status error; + if (!reg_info) + return ScriptedInterface::ErrorWithMessage< + std::shared_ptr<DynamicRegisterInfo>>( + LLVM_PRETTY_FUNCTION, "failed to get scripted frame registers info", + error, LLDBLog::Thread); + + ThreadSP thread_sp = m_thread_wp.lock(); + if (!thread_sp || !thread_sp->IsValid()) + return ScriptedInterface::ErrorWithMessage< + std::shared_ptr<DynamicRegisterInfo>>( + LLVM_PRETTY_FUNCTION, + "failed to get scripted frame registers info: invalid thread", error, + LLDBLog::Thread); + + ProcessSP process_sp = thread_sp->GetProcess(); + if (!process_sp || !process_sp->IsValid()) + return ScriptedInterface::ErrorWithMessage< + std::shared_ptr<DynamicRegisterInfo>>( + LLVM_PRETTY_FUNCTION, + "failed to get scripted frame registers info: invalid process", error, + LLDBLog::Thread); + + return DynamicRegisterInfo::Create(*reg_info, + process_sp->GetTarget().GetArchitecture()); +} + +llvm::Expected<lldb::RegisterContextSP> +ScriptedFrame::CreateRegisterContext(ScriptedFrameInterface &interface, + Thread &thread, lldb::user_id_t frame_id) { + StructuredData::DictionarySP reg_info = interface.GetRegisterInfo(); + if (!reg_info) + return llvm::createStringError( + "failed to get scripted frame registers info"); + + std::shared_ptr<DynamicRegisterInfo> register_info_sp = + DynamicRegisterInfo::Create( + *reg_info, thread.GetProcess()->GetTarget().GetArchitecture()); + + lldb::RegisterContextSP reg_ctx_sp; + + std::optional<std::string> reg_data = interface.GetRegisterContext(); + if (!reg_data) + return llvm::createStringError( + "failed to get scripted frame registers data"); + + DataBufferSP data_sp( + std::make_shared<DataBufferHeap>(reg_data->c_str(), reg_data->size())); + + if (!data_sp->GetByteSize()) + return llvm::createStringError("failed to copy raw registers data"); + + std::shared_ptr<RegisterContextMemory> reg_ctx_memory = + std::make_shared<RegisterContextMemory>( + thread, frame_id, *register_info_sp, LLDB_INVALID_ADDRESS); + + reg_ctx_memory->SetAllRegisterData(data_sp); + reg_ctx_sp = reg_ctx_memory; + + return reg_ctx_sp; +} + +lldb::RegisterContextSP ScriptedFrame::GetRegisterContext() { + if (!m_reg_context_sp) { Status error; - if (!reg_info) - return ScriptedInterface::ErrorWithMessage< - std::shared_ptr<DynamicRegisterInfo>>( - LLVM_PRETTY_FUNCTION, "Failed to get scripted frame registers info.", + if (!m_scripted_frame_interface_sp) + return ScriptedInterface::ErrorWithMessage<RegisterContextSP>( + LLVM_PRETTY_FUNCTION, + "failed to get scripted frame registers context: invalid interface", error, LLDBLog::Thread); - ThreadSP thread_sp = m_thread_wp.lock(); - if (!thread_sp || !thread_sp->IsValid()) - return ScriptedInterface::ErrorWithMessage< - std::shared_ptr<DynamicRegisterInfo>>( + ThreadSP thread_sp = GetThread(); + if (!thread_sp) + return ScriptedInterface::ErrorWithMessage<RegisterContextSP>( LLVM_PRETTY_FUNCTION, - "Failed to get scripted frame registers info: invalid thread.", error, - LLDBLog::Thread); + "failed to get scripted frame registers context: invalid thread", + error, LLDBLog::Thread); - ProcessSP process_sp = thread_sp->GetProcess(); - if (!process_sp || !process_sp->IsValid()) - return ScriptedInterface::ErrorWithMessage< - std::shared_ptr<DynamicRegisterInfo>>( + auto regs_or_err = CreateRegisterContext(*m_scripted_frame_interface_sp, + *thread_sp, GetFrameIndex()); + if (!regs_or_err) { + error = Status::FromError(regs_or_err.takeError()); + return ScriptedInterface::ErrorWithMessage<RegisterContextSP>( LLVM_PRETTY_FUNCTION, - "Failed to get scripted frame registers info: invalid process.", - error, LLDBLog::Thread); + "failed to get scripted frame registers context", error, + LLDBLog::Thread); + } - m_register_info_sp = DynamicRegisterInfo::Create( - *reg_info, process_sp->GetTarget().GetArchitecture()); + m_reg_context_sp = *regs_or_err; } - return m_register_info_sp; + return m_reg_context_sp; } |
