LLDB mainline
ScriptedFrame.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "ScriptedFrame.h"
10
12
13using namespace lldb;
14using namespace lldb_private;
15
17 lldbassert(m_script_object_sp && "Invalid Script Object.");
18 lldbassert(GetInterface() && "Invalid Scripted Frame Interface.");
19}
20
21llvm::Expected<std::shared_ptr<ScriptedFrame>>
24 StructuredData::Generic *script_object) {
25 if (!thread.IsValid())
26 return llvm::createStringError("Invalid scripted thread.");
27
28 thread.CheckInterpreterAndScriptObject();
29
30 auto scripted_frame_interface =
31 thread.GetInterface()->CreateScriptedFrameInterface();
32 if (!scripted_frame_interface)
33 return llvm::createStringError("failed to create scripted frame interface");
34
35 llvm::StringRef frame_class_name;
36 if (!script_object) {
37 std::optional<std::string> class_name =
38 thread.GetInterface()->GetScriptedFramePluginName();
39 if (!class_name || class_name->empty())
40 return llvm::createStringError(
41 "failed to get scripted thread class name");
42 frame_class_name = *class_name;
43 }
44
45 ExecutionContext exe_ctx(thread);
46 auto obj_or_err = scripted_frame_interface->CreatePluginObject(
47 frame_class_name, exe_ctx, args_sp, script_object);
48
49 if (!obj_or_err)
50 return llvm::createStringError(
51 "failed to create script object: %s",
52 llvm::toString(obj_or_err.takeError()).c_str());
53
54 StructuredData::GenericSP owned_script_object_sp = *obj_or_err;
55
56 if (!owned_script_object_sp->IsValid())
57 return llvm::createStringError("created script object is invalid");
58
59 lldb::user_id_t frame_id = scripted_frame_interface->GetID();
60
61 lldb::addr_t pc = scripted_frame_interface->GetPC();
63 Address symbol_addr;
64 if (pc != LLDB_INVALID_ADDRESS) {
65 symbol_addr.SetLoadAddress(pc, &thread.GetProcess()->GetTarget());
66 symbol_addr.CalculateSymbolContext(&sc);
67 }
68
69 std::optional<SymbolContext> maybe_sym_ctx =
70 scripted_frame_interface->GetSymbolContext();
71 if (maybe_sym_ctx) {
72 sc = *maybe_sym_ctx;
73 }
74
76 scripted_frame_interface->GetRegisterInfo();
77
78 if (!reg_info)
79 return llvm::createStringError(
80 "failed to get scripted thread registers info");
81
82 std::shared_ptr<DynamicRegisterInfo> register_info_sp =
84 *reg_info, thread.GetProcess()->GetTarget().GetArchitecture());
85
86 lldb::RegisterContextSP reg_ctx_sp;
87
88 std::optional<std::string> reg_data =
89 scripted_frame_interface->GetRegisterContext();
90 if (reg_data) {
91 DataBufferSP data_sp(
92 std::make_shared<DataBufferHeap>(reg_data->c_str(), reg_data->size()));
93
94 if (!data_sp->GetByteSize())
95 return llvm::createStringError("failed to copy raw registers data");
96
97 std::shared_ptr<RegisterContextMemory> reg_ctx_memory =
98 std::make_shared<RegisterContextMemory>(
99 thread, frame_id, *register_info_sp, LLDB_INVALID_ADDRESS);
100 if (!reg_ctx_memory)
101 return llvm::createStringError("failed to create a register context.");
102
103 reg_ctx_memory->SetAllRegisterData(data_sp);
104 reg_ctx_sp = reg_ctx_memory;
105 }
106
107 return std::make_shared<ScriptedFrame>(
108 thread, scripted_frame_interface, frame_id, pc, sc, reg_ctx_sp,
109 register_info_sp, owned_script_object_sp);
110}
111
113 ScriptedFrameInterfaceSP interface_sp,
115 SymbolContext &sym_ctx,
116 lldb::RegisterContextSP reg_ctx_sp,
117 std::shared_ptr<DynamicRegisterInfo> reg_info_sp,
118 StructuredData::GenericSP script_object_sp)
119 : StackFrame(thread.shared_from_this(), /*frame_idx=*/id,
120 /*concrete_frame_idx=*/id, /*reg_context_sp=*/reg_ctx_sp,
121 /*cfa=*/0, /*pc=*/pc,
122 /*behaves_like_zeroth_frame=*/!id, /*symbol_ctx=*/&sym_ctx),
123 m_scripted_frame_interface_sp(interface_sp),
124 m_script_object_sp(script_object_sp), m_register_info_sp(reg_info_sp) {}
125
127
130 std::optional<std::string> function_name = GetInterface()->GetFunctionName();
131 if (!function_name)
132 return nullptr;
133 return ConstString(function_name->c_str()).AsCString();
134}
135
138 std::optional<std::string> function_name =
139 GetInterface()->GetDisplayFunctionName();
140 if (!function_name)
141 return nullptr;
142 return ConstString(function_name->c_str()).AsCString();
143}
144
145bool ScriptedFrame::IsInlined() { return GetInterface()->IsInlined(); }
146
148 return GetInterface()->IsArtificial();
149}
150
151bool ScriptedFrame::IsHidden() { return GetInterface()->IsHidden(); }
152
156
157std::shared_ptr<DynamicRegisterInfo> ScriptedFrame::GetDynamicRegisterInfo() {
159
160 if (!m_register_info_sp) {
161 StructuredData::DictionarySP reg_info = GetInterface()->GetRegisterInfo();
162
164 if (!reg_info)
166 std::shared_ptr<DynamicRegisterInfo>>(
167 LLVM_PRETTY_FUNCTION, "Failed to get scripted frame registers info.",
169
170 ThreadSP thread_sp = m_thread_wp.lock();
171 if (!thread_sp || !thread_sp->IsValid())
173 std::shared_ptr<DynamicRegisterInfo>>(
174 LLVM_PRETTY_FUNCTION,
175 "Failed to get scripted frame registers info: invalid thread.", error,
177
178 ProcessSP process_sp = thread_sp->GetProcess();
179 if (!process_sp || !process_sp->IsValid())
181 std::shared_ptr<DynamicRegisterInfo>>(
182 LLVM_PRETTY_FUNCTION,
183 "Failed to get scripted frame registers info: invalid process.",
185
187 *reg_info, process_sp->GetTarget().GetArchitecture());
188 }
189
190 return m_register_info_sp;
191}
static llvm::raw_ostream & error(Stream &strm)
#define lldbassert(x)
Definition LLDBAssert.h:16
A section + offset based address class.
Definition Address.h:62
bool SetLoadAddress(lldb::addr_t load_addr, Target *target, bool allow_section_end=false)
Set the address to represent load_addr.
Definition Address.cpp:1035
uint32_t CalculateSymbolContext(SymbolContext *sc, lldb::SymbolContextItem resolve_scope=lldb::eSymbolContextEverything) const
Reconstruct a symbol context from an address.
Definition Address.cpp:820
A uniqued constant string class.
Definition ConstString.h:40
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
static std::unique_ptr< DynamicRegisterInfo > Create(const StructuredData::Dictionary &dict, const ArchSpec &arch)
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
std::shared_ptr< DynamicRegisterInfo > m_register_info_sp
ScriptedFrame(ScriptedThread &thread, lldb::ScriptedFrameInterfaceSP interface_sp, lldb::user_id_t frame_idx, lldb::addr_t pc, SymbolContext &sym_ctx, lldb::RegisterContextSP reg_ctx_sp, std::shared_ptr< DynamicRegisterInfo > reg_info_sp, StructuredData::GenericSP script_object_sp=nullptr)
bool IsArtificial() const override
Query whether this frame is artificial (e.g a synthesized result of inferring missing tail call frame...
const char * GetFunctionName() override
Get the frame's demangled name.
lldb::ScriptedFrameInterfaceSP GetInterface() const
void CheckInterpreterAndScriptObject() const
lldb::ScriptedFrameInterfaceSP m_scripted_frame_interface_sp
static llvm::Expected< std::shared_ptr< ScriptedFrame > > Create(ScriptedThread &thread, StructuredData::DictionarySP args_sp, StructuredData::Generic *script_object=nullptr)
lldb_private::StructuredData::GenericSP m_script_object_sp
bool IsHidden() override
Query whether this frame should be hidden from backtraces.
bool IsInlined() override
Query whether this frame is a concrete frame on the call stack, or if it is an inlined frame derived ...
const char * GetDisplayFunctionName() override
Get the frame's demangled display name.
std::shared_ptr< DynamicRegisterInfo > GetDynamicRegisterInfo()
static Ret ErrorWithMessage(llvm::StringRef caller_name, llvm::StringRef error_msg, Status &error, LLDBLog log_category=LLDBLog::Process)
lldb::ThreadWP m_thread_wp
For StackFrame and derived classes only.
Definition StackFrame.h:548
StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, lldb::addr_t cfa, bool cfa_is_valid, lldb::addr_t pc, Kind frame_kind, bool artificial, bool behaves_like_zeroth_frame, const SymbolContext *sc_ptr)
Construct a StackFrame object without supplying a RegisterContextSP.
An error handling class.
Definition Status.h:118
std::shared_ptr< Generic > GenericSP
std::shared_ptr< Dictionary > DictionarySP
Defines a symbol context baton that can be handed other debug core functions.
#define LLDB_INVALID_ADDRESS
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::Process > ProcessSP
uint64_t user_id_t
Definition lldb-types.h:82
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
std::shared_ptr< lldb_private::ScriptedFrameInterface > ScriptedFrameInterfaceSP