xref: /src/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
1c0981da4SDimitry Andric //===-- ScriptedThread.cpp ------------------------------------------------===//
2c0981da4SDimitry Andric //
3c0981da4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c0981da4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5c0981da4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c0981da4SDimitry Andric //
7c0981da4SDimitry Andric //===----------------------------------------------------------------------===//
8c0981da4SDimitry Andric 
9c0981da4SDimitry Andric #include "ScriptedThread.h"
10c0981da4SDimitry Andric 
11c0981da4SDimitry Andric #include "Plugins/Process/Utility/RegisterContextThreadMemory.h"
12e3b55780SDimitry Andric #include "Plugins/Process/Utility/StopInfoMachException.h"
13c0981da4SDimitry Andric #include "lldb/Target/OperatingSystem.h"
14c0981da4SDimitry Andric #include "lldb/Target/Process.h"
15c0981da4SDimitry Andric #include "lldb/Target/RegisterContext.h"
16c0981da4SDimitry Andric #include "lldb/Target/StopInfo.h"
17c0981da4SDimitry Andric #include "lldb/Target/Unwind.h"
18c0981da4SDimitry Andric #include "lldb/Utility/DataBufferHeap.h"
19145449b1SDimitry Andric #include "lldb/Utility/LLDBLog.h"
20c0981da4SDimitry Andric #include <memory>
21e3b55780SDimitry Andric #include <optional>
22c0981da4SDimitry Andric 
23c0981da4SDimitry Andric using namespace lldb;
24c0981da4SDimitry Andric using namespace lldb_private;
25c0981da4SDimitry Andric 
CheckInterpreterAndScriptObject() const26c0981da4SDimitry Andric void ScriptedThread::CheckInterpreterAndScriptObject() const {
27c0981da4SDimitry Andric   lldbassert(m_script_object_sp && "Invalid Script Object.");
28c0981da4SDimitry Andric   lldbassert(GetInterface() && "Invalid Scripted Thread Interface.");
29c0981da4SDimitry Andric }
30c0981da4SDimitry Andric 
316f8fc217SDimitry Andric llvm::Expected<std::shared_ptr<ScriptedThread>>
Create(ScriptedProcess & process,StructuredData::Generic * script_object)326f8fc217SDimitry Andric ScriptedThread::Create(ScriptedProcess &process,
336f8fc217SDimitry Andric                        StructuredData::Generic *script_object) {
346f8fc217SDimitry Andric   if (!process.IsValid())
356f8fc217SDimitry Andric     return llvm::createStringError(llvm::inconvertibleErrorCode(),
366f8fc217SDimitry Andric                                    "Invalid scripted process.");
37c0981da4SDimitry Andric 
387fa27ce4SDimitry Andric   process.CheckScriptedInterface();
39c0981da4SDimitry Andric 
406f8fc217SDimitry Andric   auto scripted_thread_interface =
416f8fc217SDimitry Andric       process.GetInterface().CreateScriptedThreadInterface();
426f8fc217SDimitry Andric   if (!scripted_thread_interface)
436f8fc217SDimitry Andric     return llvm::createStringError(
446f8fc217SDimitry Andric         llvm::inconvertibleErrorCode(),
456f8fc217SDimitry Andric         "Failed to create scripted thread interface.");
46c0981da4SDimitry Andric 
476f8fc217SDimitry Andric   llvm::StringRef thread_class_name;
486f8fc217SDimitry Andric   if (!script_object) {
49e3b55780SDimitry Andric     std::optional<std::string> class_name =
50c0981da4SDimitry Andric         process.GetInterface().GetScriptedThreadPluginName();
516f8fc217SDimitry Andric     if (!class_name || class_name->empty())
526f8fc217SDimitry Andric       return llvm::createStringError(
536f8fc217SDimitry Andric           llvm::inconvertibleErrorCode(),
546f8fc217SDimitry Andric           "Failed to get scripted thread class name.");
556f8fc217SDimitry Andric     thread_class_name = *class_name;
56c0981da4SDimitry Andric   }
57c0981da4SDimitry Andric 
58c0981da4SDimitry Andric   ExecutionContext exe_ctx(process);
59b1c73532SDimitry Andric   auto obj_or_err = scripted_thread_interface->CreatePluginObject(
60e3b55780SDimitry Andric       thread_class_name, exe_ctx, process.m_scripted_metadata.GetArgsSP(),
61e3b55780SDimitry Andric       script_object);
626f8fc217SDimitry Andric 
63b1c73532SDimitry Andric   if (!obj_or_err) {
64b1c73532SDimitry Andric     llvm::consumeError(obj_or_err.takeError());
656f8fc217SDimitry Andric     return llvm::createStringError(llvm::inconvertibleErrorCode(),
666f8fc217SDimitry Andric                                    "Failed to create script object.");
67b1c73532SDimitry Andric   }
68b1c73532SDimitry Andric 
69b1c73532SDimitry Andric   StructuredData::GenericSP owned_script_object_sp = *obj_or_err;
70b1c73532SDimitry Andric 
716f8fc217SDimitry Andric   if (!owned_script_object_sp->IsValid())
726f8fc217SDimitry Andric     return llvm::createStringError(llvm::inconvertibleErrorCode(),
736f8fc217SDimitry Andric                                    "Created script object is invalid.");
746f8fc217SDimitry Andric 
756f8fc217SDimitry Andric   lldb::tid_t tid = scripted_thread_interface->GetThreadID();
766f8fc217SDimitry Andric 
776f8fc217SDimitry Andric   return std::make_shared<ScriptedThread>(process, scripted_thread_interface,
786f8fc217SDimitry Andric                                           tid, owned_script_object_sp);
79c0981da4SDimitry Andric }
80c0981da4SDimitry Andric 
ScriptedThread(ScriptedProcess & process,ScriptedThreadInterfaceSP interface_sp,lldb::tid_t tid,StructuredData::GenericSP script_object_sp)816f8fc217SDimitry Andric ScriptedThread::ScriptedThread(ScriptedProcess &process,
826f8fc217SDimitry Andric                                ScriptedThreadInterfaceSP interface_sp,
836f8fc217SDimitry Andric                                lldb::tid_t tid,
846f8fc217SDimitry Andric                                StructuredData::GenericSP script_object_sp)
856f8fc217SDimitry Andric     : Thread(process, tid), m_scripted_process(process),
866f8fc217SDimitry Andric       m_scripted_thread_interface_sp(interface_sp),
876f8fc217SDimitry Andric       m_script_object_sp(script_object_sp) {}
88c0981da4SDimitry Andric 
~ScriptedThread()89c0981da4SDimitry Andric ScriptedThread::~ScriptedThread() { DestroyThread(); }
90c0981da4SDimitry Andric 
GetName()91c0981da4SDimitry Andric const char *ScriptedThread::GetName() {
92c0981da4SDimitry Andric   CheckInterpreterAndScriptObject();
93e3b55780SDimitry Andric   std::optional<std::string> thread_name = GetInterface()->GetName();
94c0981da4SDimitry Andric   if (!thread_name)
95c0981da4SDimitry Andric     return nullptr;
96c0981da4SDimitry Andric   return ConstString(thread_name->c_str()).AsCString();
97c0981da4SDimitry Andric }
98c0981da4SDimitry Andric 
GetQueueName()99c0981da4SDimitry Andric const char *ScriptedThread::GetQueueName() {
100c0981da4SDimitry Andric   CheckInterpreterAndScriptObject();
101e3b55780SDimitry Andric   std::optional<std::string> queue_name = GetInterface()->GetQueue();
102c0981da4SDimitry Andric   if (!queue_name)
103c0981da4SDimitry Andric     return nullptr;
104c0981da4SDimitry Andric   return ConstString(queue_name->c_str()).AsCString();
105c0981da4SDimitry Andric }
106c0981da4SDimitry Andric 
WillResume(StateType resume_state)107c0981da4SDimitry Andric void ScriptedThread::WillResume(StateType resume_state) {}
108c0981da4SDimitry Andric 
ClearStackFrames()109c0981da4SDimitry Andric void ScriptedThread::ClearStackFrames() { Thread::ClearStackFrames(); }
110c0981da4SDimitry Andric 
GetRegisterContext()111c0981da4SDimitry Andric RegisterContextSP ScriptedThread::GetRegisterContext() {
112c0981da4SDimitry Andric   if (!m_reg_context_sp)
113c0981da4SDimitry Andric     m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
114c0981da4SDimitry Andric   return m_reg_context_sp;
115c0981da4SDimitry Andric }
116c0981da4SDimitry Andric 
117c0981da4SDimitry Andric RegisterContextSP
CreateRegisterContextForFrame(StackFrame * frame)118c0981da4SDimitry Andric ScriptedThread::CreateRegisterContextForFrame(StackFrame *frame) {
119c0981da4SDimitry Andric   const uint32_t concrete_frame_idx =
120c0981da4SDimitry Andric       frame ? frame->GetConcreteFrameIndex() : 0;
121c0981da4SDimitry Andric 
122c0981da4SDimitry Andric   if (concrete_frame_idx)
123c0981da4SDimitry Andric     return GetUnwinder().CreateRegisterContextForFrame(frame);
124c0981da4SDimitry Andric 
125c0981da4SDimitry Andric   lldb::RegisterContextSP reg_ctx_sp;
126c0981da4SDimitry Andric   Status error;
127c0981da4SDimitry Andric 
128e3b55780SDimitry Andric   std::optional<std::string> reg_data = GetInterface()->GetRegisterContext();
129c0981da4SDimitry Andric   if (!reg_data)
130145449b1SDimitry Andric     return ScriptedInterface::ErrorWithMessage<lldb::RegisterContextSP>(
131c0981da4SDimitry Andric         LLVM_PRETTY_FUNCTION, "Failed to get scripted thread registers data.",
132145449b1SDimitry Andric         error, LLDBLog::Thread);
133c0981da4SDimitry Andric 
134c0981da4SDimitry Andric   DataBufferSP data_sp(
135c0981da4SDimitry Andric       std::make_shared<DataBufferHeap>(reg_data->c_str(), reg_data->size()));
136c0981da4SDimitry Andric 
137c0981da4SDimitry Andric   if (!data_sp->GetByteSize())
138145449b1SDimitry Andric     return ScriptedInterface::ErrorWithMessage<lldb::RegisterContextSP>(
139c0981da4SDimitry Andric         LLVM_PRETTY_FUNCTION, "Failed to copy raw registers data.", error,
140145449b1SDimitry Andric         LLDBLog::Thread);
141c0981da4SDimitry Andric 
142c0981da4SDimitry Andric   std::shared_ptr<RegisterContextMemory> reg_ctx_memory =
143c0981da4SDimitry Andric       std::make_shared<RegisterContextMemory>(
144c0981da4SDimitry Andric           *this, 0, *GetDynamicRegisterInfo(), LLDB_INVALID_ADDRESS);
145c0981da4SDimitry Andric   if (!reg_ctx_memory)
146145449b1SDimitry Andric     return ScriptedInterface::ErrorWithMessage<lldb::RegisterContextSP>(
147c0981da4SDimitry Andric         LLVM_PRETTY_FUNCTION, "Failed to create a register context.", error,
148145449b1SDimitry Andric         LLDBLog::Thread);
149c0981da4SDimitry Andric 
150c0981da4SDimitry Andric   reg_ctx_memory->SetAllRegisterData(data_sp);
151c0981da4SDimitry Andric   m_reg_context_sp = reg_ctx_memory;
152c0981da4SDimitry Andric 
153c0981da4SDimitry Andric   return m_reg_context_sp;
154c0981da4SDimitry Andric }
155c0981da4SDimitry Andric 
LoadArtificialStackFrames()156145449b1SDimitry Andric bool ScriptedThread::LoadArtificialStackFrames() {
157145449b1SDimitry Andric   StructuredData::ArraySP arr_sp = GetInterface()->GetStackFrames();
158145449b1SDimitry Andric 
159145449b1SDimitry Andric   Status error;
160145449b1SDimitry Andric   if (!arr_sp)
161145449b1SDimitry Andric     return ScriptedInterface::ErrorWithMessage<bool>(
162145449b1SDimitry Andric         LLVM_PRETTY_FUNCTION, "Failed to get scripted thread stackframes.",
163145449b1SDimitry Andric         error, LLDBLog::Thread);
164145449b1SDimitry Andric 
165145449b1SDimitry Andric   size_t arr_size = arr_sp->GetSize();
166145449b1SDimitry Andric   if (arr_size > std::numeric_limits<uint32_t>::max())
167145449b1SDimitry Andric     return ScriptedInterface::ErrorWithMessage<bool>(
168145449b1SDimitry Andric         LLVM_PRETTY_FUNCTION,
169145449b1SDimitry Andric         llvm::Twine(
170145449b1SDimitry Andric             "StackFrame array size (" + llvm::Twine(arr_size) +
171145449b1SDimitry Andric             llvm::Twine(
172e3b55780SDimitry Andric                 ") is greater than maximum authorized for a StackFrameList."))
173145449b1SDimitry Andric             .str(),
174145449b1SDimitry Andric         error, LLDBLog::Thread);
175145449b1SDimitry Andric 
176145449b1SDimitry Andric   StackFrameListSP frames = GetStackFrameList();
177145449b1SDimitry Andric 
178145449b1SDimitry Andric   for (size_t idx = 0; idx < arr_size; idx++) {
179b1c73532SDimitry Andric     std::optional<StructuredData::Dictionary *> maybe_dict =
180b1c73532SDimitry Andric         arr_sp->GetItemAtIndexAsDictionary(idx);
181b1c73532SDimitry Andric     if (!maybe_dict)
182145449b1SDimitry Andric       return ScriptedInterface::ErrorWithMessage<bool>(
183145449b1SDimitry Andric           LLVM_PRETTY_FUNCTION,
184145449b1SDimitry Andric           llvm::Twine(
185145449b1SDimitry Andric               "Couldn't get artificial stackframe dictionary at index (" +
186145449b1SDimitry Andric               llvm::Twine(idx) + llvm::Twine(") from stackframe array."))
187145449b1SDimitry Andric               .str(),
188145449b1SDimitry Andric           error, LLDBLog::Thread);
189b1c73532SDimitry Andric     StructuredData::Dictionary *dict = *maybe_dict;
190145449b1SDimitry Andric 
191145449b1SDimitry Andric     lldb::addr_t pc;
192145449b1SDimitry Andric     if (!dict->GetValueForKeyAsInteger("pc", pc))
193145449b1SDimitry Andric       return ScriptedInterface::ErrorWithMessage<bool>(
194145449b1SDimitry Andric           LLVM_PRETTY_FUNCTION,
195145449b1SDimitry Andric           "Couldn't find value for key 'pc' in stackframe dictionary.", error,
196145449b1SDimitry Andric           LLDBLog::Thread);
197145449b1SDimitry Andric 
198145449b1SDimitry Andric     Address symbol_addr;
199145449b1SDimitry Andric     symbol_addr.SetLoadAddress(pc, &this->GetProcess()->GetTarget());
200145449b1SDimitry Andric 
201145449b1SDimitry Andric     lldb::addr_t cfa = LLDB_INVALID_ADDRESS;
202145449b1SDimitry Andric     bool cfa_is_valid = false;
203145449b1SDimitry Andric     const bool behaves_like_zeroth_frame = false;
204145449b1SDimitry Andric     SymbolContext sc;
205145449b1SDimitry Andric     symbol_addr.CalculateSymbolContext(&sc);
206145449b1SDimitry Andric 
207145449b1SDimitry Andric     StackFrameSP synth_frame_sp = std::make_shared<StackFrame>(
208145449b1SDimitry Andric         this->shared_from_this(), idx, idx, cfa, cfa_is_valid, pc,
209145449b1SDimitry Andric         StackFrame::Kind::Artificial, behaves_like_zeroth_frame, &sc);
210145449b1SDimitry Andric 
211145449b1SDimitry Andric     if (!frames->SetFrameAtIndex(static_cast<uint32_t>(idx), synth_frame_sp))
212145449b1SDimitry Andric       return ScriptedInterface::ErrorWithMessage<bool>(
213145449b1SDimitry Andric           LLVM_PRETTY_FUNCTION,
214145449b1SDimitry Andric           llvm::Twine("Couldn't add frame (" + llvm::Twine(idx) +
215145449b1SDimitry Andric                       llvm::Twine(") to ScriptedThread StackFrameList."))
216145449b1SDimitry Andric               .str(),
217145449b1SDimitry Andric           error, LLDBLog::Thread);
218145449b1SDimitry Andric   }
219145449b1SDimitry Andric 
220145449b1SDimitry Andric   return true;
221145449b1SDimitry Andric }
222145449b1SDimitry Andric 
CalculateStopInfo()223c0981da4SDimitry Andric bool ScriptedThread::CalculateStopInfo() {
224c0981da4SDimitry Andric   StructuredData::DictionarySP dict_sp = GetInterface()->GetStopReason();
225c0981da4SDimitry Andric 
226c0981da4SDimitry Andric   Status error;
2276f8fc217SDimitry Andric   if (!dict_sp)
228145449b1SDimitry Andric     return ScriptedInterface::ErrorWithMessage<bool>(
2296f8fc217SDimitry Andric         LLVM_PRETTY_FUNCTION, "Failed to get scripted thread stop info.", error,
230145449b1SDimitry Andric         LLDBLog::Thread);
2316f8fc217SDimitry Andric 
232c0981da4SDimitry Andric   lldb::StopInfoSP stop_info_sp;
233c0981da4SDimitry Andric   lldb::StopReason stop_reason_type;
234c0981da4SDimitry Andric 
235c0981da4SDimitry Andric   if (!dict_sp->GetValueForKeyAsInteger("type", stop_reason_type))
236145449b1SDimitry Andric     return ScriptedInterface::ErrorWithMessage<bool>(
237c0981da4SDimitry Andric         LLVM_PRETTY_FUNCTION,
238c0981da4SDimitry Andric         "Couldn't find value for key 'type' in stop reason dictionary.", error,
239145449b1SDimitry Andric         LLDBLog::Thread);
240c0981da4SDimitry Andric 
241c0981da4SDimitry Andric   StructuredData::Dictionary *data_dict;
242c0981da4SDimitry Andric   if (!dict_sp->GetValueForKeyAsDictionary("data", data_dict))
243145449b1SDimitry Andric     return ScriptedInterface::ErrorWithMessage<bool>(
244c0981da4SDimitry Andric         LLVM_PRETTY_FUNCTION,
2456f8fc217SDimitry Andric         "Couldn't find value for key 'data' in stop reason dictionary.", error,
246145449b1SDimitry Andric         LLDBLog::Thread);
247c0981da4SDimitry Andric 
248c0981da4SDimitry Andric   switch (stop_reason_type) {
249c0981da4SDimitry Andric   case lldb::eStopReasonNone:
2506f8fc217SDimitry Andric     return true;
251c0981da4SDimitry Andric   case lldb::eStopReasonBreakpoint: {
252c0981da4SDimitry Andric     lldb::break_id_t break_id;
253c0981da4SDimitry Andric     data_dict->GetValueForKeyAsInteger("break_id", break_id,
254c0981da4SDimitry Andric                                        LLDB_INVALID_BREAK_ID);
255c0981da4SDimitry Andric     stop_info_sp =
256c0981da4SDimitry Andric         StopInfo::CreateStopReasonWithBreakpointSiteID(*this, break_id);
257c0981da4SDimitry Andric   } break;
258c0981da4SDimitry Andric   case lldb::eStopReasonSignal: {
2597fa27ce4SDimitry Andric     uint32_t signal;
260c0981da4SDimitry Andric     llvm::StringRef description;
2617fa27ce4SDimitry Andric     if (!data_dict->GetValueForKeyAsInteger("signal", signal)) {
2627fa27ce4SDimitry Andric         signal = LLDB_INVALID_SIGNAL_NUMBER;
2637fa27ce4SDimitry Andric         return false;
2647fa27ce4SDimitry Andric     }
265c0981da4SDimitry Andric     data_dict->GetValueForKeyAsString("desc", description);
266c0981da4SDimitry Andric     stop_info_sp =
267c0981da4SDimitry Andric         StopInfo::CreateStopReasonWithSignal(*this, signal, description.data());
268c0981da4SDimitry Andric   } break;
2697fa27ce4SDimitry Andric   case lldb::eStopReasonTrace: {
2707fa27ce4SDimitry Andric     stop_info_sp = StopInfo::CreateStopReasonToTrace(*this);
2717fa27ce4SDimitry Andric   } break;
2726f8fc217SDimitry Andric   case lldb::eStopReasonException: {
273e3b55780SDimitry Andric #if defined(__APPLE__)
274e3b55780SDimitry Andric     StructuredData::Dictionary *mach_exception;
275e3b55780SDimitry Andric     if (data_dict->GetValueForKeyAsDictionary("mach_exception",
276e3b55780SDimitry Andric                                               mach_exception)) {
277e3b55780SDimitry Andric       llvm::StringRef value;
278e3b55780SDimitry Andric       mach_exception->GetValueForKeyAsString("type", value);
279e3b55780SDimitry Andric       auto exc_type =
280e3b55780SDimitry Andric           StopInfoMachException::MachException::ExceptionCode(value.data());
2816f8fc217SDimitry Andric 
282e3b55780SDimitry Andric       if (!exc_type)
283e3b55780SDimitry Andric         return false;
284e3b55780SDimitry Andric 
285e3b55780SDimitry Andric       uint32_t exc_data_size = 0;
286e3b55780SDimitry Andric       llvm::SmallVector<uint64_t, 3> raw_codes;
287e3b55780SDimitry Andric 
288e3b55780SDimitry Andric       StructuredData::Array *exc_rawcodes;
289e3b55780SDimitry Andric       mach_exception->GetValueForKeyAsArray("rawCodes", exc_rawcodes);
290e3b55780SDimitry Andric       if (exc_rawcodes) {
291e3b55780SDimitry Andric         auto fetch_data = [&raw_codes](StructuredData::Object *obj) {
292e3b55780SDimitry Andric           if (!obj)
293e3b55780SDimitry Andric             return false;
2947fa27ce4SDimitry Andric           raw_codes.push_back(obj->GetUnsignedIntegerValue());
295e3b55780SDimitry Andric           return true;
296e3b55780SDimitry Andric         };
297e3b55780SDimitry Andric 
298e3b55780SDimitry Andric         exc_rawcodes->ForEach(fetch_data);
299e3b55780SDimitry Andric         exc_data_size = raw_codes.size();
300e3b55780SDimitry Andric       }
301e3b55780SDimitry Andric 
302e3b55780SDimitry Andric       stop_info_sp = StopInfoMachException::CreateStopReasonWithMachException(
303e3b55780SDimitry Andric           *this, *exc_type, exc_data_size,
304e3b55780SDimitry Andric           exc_data_size >= 1 ? raw_codes[0] : 0,
305e3b55780SDimitry Andric           exc_data_size >= 2 ? raw_codes[1] : 0,
306e3b55780SDimitry Andric           exc_data_size >= 3 ? raw_codes[2] : 0);
307e3b55780SDimitry Andric 
308e3b55780SDimitry Andric       break;
309e3b55780SDimitry Andric     }
310e3b55780SDimitry Andric #endif
3116f8fc217SDimitry Andric     stop_info_sp =
312e3b55780SDimitry Andric         StopInfo::CreateStopReasonWithException(*this, "EXC_BAD_ACCESS");
3136f8fc217SDimitry Andric   } break;
314c0981da4SDimitry Andric   default:
315145449b1SDimitry Andric     return ScriptedInterface::ErrorWithMessage<bool>(
316c0981da4SDimitry Andric         LLVM_PRETTY_FUNCTION,
317c0981da4SDimitry Andric         llvm::Twine("Unsupported stop reason type (" +
318c0981da4SDimitry Andric                     llvm::Twine(stop_reason_type) + llvm::Twine(")."))
319c0981da4SDimitry Andric             .str(),
320145449b1SDimitry Andric         error, LLDBLog::Thread);
321c0981da4SDimitry Andric   }
322c0981da4SDimitry Andric 
3236f8fc217SDimitry Andric   if (!stop_info_sp)
3246f8fc217SDimitry Andric     return false;
3256f8fc217SDimitry Andric 
326c0981da4SDimitry Andric   SetStopInfo(stop_info_sp);
327c0981da4SDimitry Andric   return true;
328c0981da4SDimitry Andric }
329c0981da4SDimitry Andric 
RefreshStateAfterStop()330c0981da4SDimitry Andric void ScriptedThread::RefreshStateAfterStop() {
331c0981da4SDimitry Andric   GetRegisterContext()->InvalidateIfNeeded(/*force=*/false);
332145449b1SDimitry Andric   LoadArtificialStackFrames();
333c0981da4SDimitry Andric }
334c0981da4SDimitry Andric 
GetInterface() const335c0981da4SDimitry Andric lldb::ScriptedThreadInterfaceSP ScriptedThread::GetInterface() const {
3366f8fc217SDimitry Andric   return m_scripted_thread_interface_sp;
337c0981da4SDimitry Andric }
338c0981da4SDimitry Andric 
GetDynamicRegisterInfo()339c0981da4SDimitry Andric std::shared_ptr<DynamicRegisterInfo> ScriptedThread::GetDynamicRegisterInfo() {
340c0981da4SDimitry Andric   CheckInterpreterAndScriptObject();
341c0981da4SDimitry Andric 
342c0981da4SDimitry Andric   if (!m_register_info_sp) {
343c0981da4SDimitry Andric     StructuredData::DictionarySP reg_info = GetInterface()->GetRegisterInfo();
34477fc4c14SDimitry Andric 
34577fc4c14SDimitry Andric     Status error;
346c0981da4SDimitry Andric     if (!reg_info)
347e3b55780SDimitry Andric       return ScriptedInterface::ErrorWithMessage<
348e3b55780SDimitry Andric           std::shared_ptr<DynamicRegisterInfo>>(
349e3b55780SDimitry Andric           LLVM_PRETTY_FUNCTION, "Failed to get scripted thread registers info.",
350e3b55780SDimitry Andric           error, LLDBLog::Thread);
351c0981da4SDimitry Andric 
3527fa27ce4SDimitry Andric     m_register_info_sp = DynamicRegisterInfo::Create(
353c0981da4SDimitry Andric         *reg_info, m_scripted_process.GetTarget().GetArchitecture());
354c0981da4SDimitry Andric   }
355c0981da4SDimitry Andric 
356c0981da4SDimitry Andric   return m_register_info_sp;
357c0981da4SDimitry Andric }
358e3b55780SDimitry Andric 
FetchThreadExtendedInfo()359e3b55780SDimitry Andric StructuredData::ObjectSP ScriptedThread::FetchThreadExtendedInfo() {
360e3b55780SDimitry Andric   CheckInterpreterAndScriptObject();
361e3b55780SDimitry Andric 
362e3b55780SDimitry Andric   Status error;
363e3b55780SDimitry Andric   StructuredData::ArraySP extended_info_sp = GetInterface()->GetExtendedInfo();
364e3b55780SDimitry Andric 
365e3b55780SDimitry Andric   if (!extended_info_sp || !extended_info_sp->GetSize())
366e3b55780SDimitry Andric     return ScriptedInterface::ErrorWithMessage<StructuredData::ObjectSP>(
367e3b55780SDimitry Andric         LLVM_PRETTY_FUNCTION, "No extended information found", error);
368e3b55780SDimitry Andric 
369e3b55780SDimitry Andric   return extended_info_sp;
370e3b55780SDimitry Andric }
371