xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
1349cc55cSDimitry Andric //===-- ScriptedThread.cpp ------------------------------------------------===//
2349cc55cSDimitry Andric //
3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6349cc55cSDimitry Andric //
7349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
8349cc55cSDimitry Andric 
9349cc55cSDimitry Andric #include "ScriptedThread.h"
10349cc55cSDimitry Andric 
11349cc55cSDimitry Andric #include "Plugins/Process/Utility/RegisterContextThreadMemory.h"
12bdd1243dSDimitry Andric #include "Plugins/Process/Utility/StopInfoMachException.h"
13349cc55cSDimitry Andric #include "lldb/Target/OperatingSystem.h"
14349cc55cSDimitry Andric #include "lldb/Target/Process.h"
15349cc55cSDimitry Andric #include "lldb/Target/RegisterContext.h"
16349cc55cSDimitry Andric #include "lldb/Target/StopInfo.h"
17349cc55cSDimitry Andric #include "lldb/Target/Unwind.h"
18349cc55cSDimitry Andric #include "lldb/Utility/DataBufferHeap.h"
1981ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h"
20349cc55cSDimitry Andric #include <memory>
21bdd1243dSDimitry Andric #include <optional>
22349cc55cSDimitry Andric 
23349cc55cSDimitry Andric using namespace lldb;
24349cc55cSDimitry Andric using namespace lldb_private;
25349cc55cSDimitry Andric 
CheckInterpreterAndScriptObject() const26349cc55cSDimitry Andric void ScriptedThread::CheckInterpreterAndScriptObject() const {
27349cc55cSDimitry Andric   lldbassert(m_script_object_sp && "Invalid Script Object.");
28349cc55cSDimitry Andric   lldbassert(GetInterface() && "Invalid Scripted Thread Interface.");
29349cc55cSDimitry Andric }
30349cc55cSDimitry Andric 
3104eeddc0SDimitry Andric llvm::Expected<std::shared_ptr<ScriptedThread>>
Create(ScriptedProcess & process,StructuredData::Generic * script_object)3204eeddc0SDimitry Andric ScriptedThread::Create(ScriptedProcess &process,
3304eeddc0SDimitry Andric                        StructuredData::Generic *script_object) {
3404eeddc0SDimitry Andric   if (!process.IsValid())
3504eeddc0SDimitry Andric     return llvm::createStringError(llvm::inconvertibleErrorCode(),
3604eeddc0SDimitry Andric                                    "Invalid scripted process.");
37349cc55cSDimitry Andric 
3806c3fb27SDimitry Andric   process.CheckScriptedInterface();
39349cc55cSDimitry Andric 
4004eeddc0SDimitry Andric   auto scripted_thread_interface =
4104eeddc0SDimitry Andric       process.GetInterface().CreateScriptedThreadInterface();
4204eeddc0SDimitry Andric   if (!scripted_thread_interface)
4304eeddc0SDimitry Andric     return llvm::createStringError(
4404eeddc0SDimitry Andric         llvm::inconvertibleErrorCode(),
4504eeddc0SDimitry Andric         "Failed to create scripted thread interface.");
46349cc55cSDimitry Andric 
4704eeddc0SDimitry Andric   llvm::StringRef thread_class_name;
4804eeddc0SDimitry Andric   if (!script_object) {
49bdd1243dSDimitry Andric     std::optional<std::string> class_name =
50349cc55cSDimitry Andric         process.GetInterface().GetScriptedThreadPluginName();
5104eeddc0SDimitry Andric     if (!class_name || class_name->empty())
5204eeddc0SDimitry Andric       return llvm::createStringError(
5304eeddc0SDimitry Andric           llvm::inconvertibleErrorCode(),
5404eeddc0SDimitry Andric           "Failed to get scripted thread class name.");
5504eeddc0SDimitry Andric     thread_class_name = *class_name;
56349cc55cSDimitry Andric   }
57349cc55cSDimitry Andric 
58349cc55cSDimitry Andric   ExecutionContext exe_ctx(process);
59*5f757f3fSDimitry Andric   auto obj_or_err = scripted_thread_interface->CreatePluginObject(
60bdd1243dSDimitry Andric       thread_class_name, exe_ctx, process.m_scripted_metadata.GetArgsSP(),
61bdd1243dSDimitry Andric       script_object);
6204eeddc0SDimitry Andric 
63*5f757f3fSDimitry Andric   if (!obj_or_err) {
64*5f757f3fSDimitry Andric     llvm::consumeError(obj_or_err.takeError());
6504eeddc0SDimitry Andric     return llvm::createStringError(llvm::inconvertibleErrorCode(),
6604eeddc0SDimitry Andric                                    "Failed to create script object.");
67*5f757f3fSDimitry Andric   }
68*5f757f3fSDimitry Andric 
69*5f757f3fSDimitry Andric   StructuredData::GenericSP owned_script_object_sp = *obj_or_err;
70*5f757f3fSDimitry Andric 
7104eeddc0SDimitry Andric   if (!owned_script_object_sp->IsValid())
7204eeddc0SDimitry Andric     return llvm::createStringError(llvm::inconvertibleErrorCode(),
7304eeddc0SDimitry Andric                                    "Created script object is invalid.");
7404eeddc0SDimitry Andric 
7504eeddc0SDimitry Andric   lldb::tid_t tid = scripted_thread_interface->GetThreadID();
7604eeddc0SDimitry Andric 
7704eeddc0SDimitry Andric   return std::make_shared<ScriptedThread>(process, scripted_thread_interface,
7804eeddc0SDimitry Andric                                           tid, owned_script_object_sp);
79349cc55cSDimitry Andric }
80349cc55cSDimitry Andric 
ScriptedThread(ScriptedProcess & process,ScriptedThreadInterfaceSP interface_sp,lldb::tid_t tid,StructuredData::GenericSP script_object_sp)8104eeddc0SDimitry Andric ScriptedThread::ScriptedThread(ScriptedProcess &process,
8204eeddc0SDimitry Andric                                ScriptedThreadInterfaceSP interface_sp,
8304eeddc0SDimitry Andric                                lldb::tid_t tid,
8404eeddc0SDimitry Andric                                StructuredData::GenericSP script_object_sp)
8504eeddc0SDimitry Andric     : Thread(process, tid), m_scripted_process(process),
8604eeddc0SDimitry Andric       m_scripted_thread_interface_sp(interface_sp),
8704eeddc0SDimitry Andric       m_script_object_sp(script_object_sp) {}
88349cc55cSDimitry Andric 
~ScriptedThread()89349cc55cSDimitry Andric ScriptedThread::~ScriptedThread() { DestroyThread(); }
90349cc55cSDimitry Andric 
GetName()91349cc55cSDimitry Andric const char *ScriptedThread::GetName() {
92349cc55cSDimitry Andric   CheckInterpreterAndScriptObject();
93bdd1243dSDimitry Andric   std::optional<std::string> thread_name = GetInterface()->GetName();
94349cc55cSDimitry Andric   if (!thread_name)
95349cc55cSDimitry Andric     return nullptr;
96349cc55cSDimitry Andric   return ConstString(thread_name->c_str()).AsCString();
97349cc55cSDimitry Andric }
98349cc55cSDimitry Andric 
GetQueueName()99349cc55cSDimitry Andric const char *ScriptedThread::GetQueueName() {
100349cc55cSDimitry Andric   CheckInterpreterAndScriptObject();
101bdd1243dSDimitry Andric   std::optional<std::string> queue_name = GetInterface()->GetQueue();
102349cc55cSDimitry Andric   if (!queue_name)
103349cc55cSDimitry Andric     return nullptr;
104349cc55cSDimitry Andric   return ConstString(queue_name->c_str()).AsCString();
105349cc55cSDimitry Andric }
106349cc55cSDimitry Andric 
WillResume(StateType resume_state)107349cc55cSDimitry Andric void ScriptedThread::WillResume(StateType resume_state) {}
108349cc55cSDimitry Andric 
ClearStackFrames()109349cc55cSDimitry Andric void ScriptedThread::ClearStackFrames() { Thread::ClearStackFrames(); }
110349cc55cSDimitry Andric 
GetRegisterContext()111349cc55cSDimitry Andric RegisterContextSP ScriptedThread::GetRegisterContext() {
112349cc55cSDimitry Andric   if (!m_reg_context_sp)
113349cc55cSDimitry Andric     m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
114349cc55cSDimitry Andric   return m_reg_context_sp;
115349cc55cSDimitry Andric }
116349cc55cSDimitry Andric 
117349cc55cSDimitry Andric RegisterContextSP
CreateRegisterContextForFrame(StackFrame * frame)118349cc55cSDimitry Andric ScriptedThread::CreateRegisterContextForFrame(StackFrame *frame) {
119349cc55cSDimitry Andric   const uint32_t concrete_frame_idx =
120349cc55cSDimitry Andric       frame ? frame->GetConcreteFrameIndex() : 0;
121349cc55cSDimitry Andric 
122349cc55cSDimitry Andric   if (concrete_frame_idx)
123349cc55cSDimitry Andric     return GetUnwinder().CreateRegisterContextForFrame(frame);
124349cc55cSDimitry Andric 
125349cc55cSDimitry Andric   lldb::RegisterContextSP reg_ctx_sp;
126349cc55cSDimitry Andric   Status error;
127349cc55cSDimitry Andric 
128bdd1243dSDimitry Andric   std::optional<std::string> reg_data = GetInterface()->GetRegisterContext();
129349cc55cSDimitry Andric   if (!reg_data)
13081ad6265SDimitry Andric     return ScriptedInterface::ErrorWithMessage<lldb::RegisterContextSP>(
131349cc55cSDimitry Andric         LLVM_PRETTY_FUNCTION, "Failed to get scripted thread registers data.",
13281ad6265SDimitry Andric         error, LLDBLog::Thread);
133349cc55cSDimitry Andric 
134349cc55cSDimitry Andric   DataBufferSP data_sp(
135349cc55cSDimitry Andric       std::make_shared<DataBufferHeap>(reg_data->c_str(), reg_data->size()));
136349cc55cSDimitry Andric 
137349cc55cSDimitry Andric   if (!data_sp->GetByteSize())
13881ad6265SDimitry Andric     return ScriptedInterface::ErrorWithMessage<lldb::RegisterContextSP>(
139349cc55cSDimitry Andric         LLVM_PRETTY_FUNCTION, "Failed to copy raw registers data.", error,
14081ad6265SDimitry Andric         LLDBLog::Thread);
141349cc55cSDimitry Andric 
142349cc55cSDimitry Andric   std::shared_ptr<RegisterContextMemory> reg_ctx_memory =
143349cc55cSDimitry Andric       std::make_shared<RegisterContextMemory>(
144349cc55cSDimitry Andric           *this, 0, *GetDynamicRegisterInfo(), LLDB_INVALID_ADDRESS);
145349cc55cSDimitry Andric   if (!reg_ctx_memory)
14681ad6265SDimitry Andric     return ScriptedInterface::ErrorWithMessage<lldb::RegisterContextSP>(
147349cc55cSDimitry Andric         LLVM_PRETTY_FUNCTION, "Failed to create a register context.", error,
14881ad6265SDimitry Andric         LLDBLog::Thread);
149349cc55cSDimitry Andric 
150349cc55cSDimitry Andric   reg_ctx_memory->SetAllRegisterData(data_sp);
151349cc55cSDimitry Andric   m_reg_context_sp = reg_ctx_memory;
152349cc55cSDimitry Andric 
153349cc55cSDimitry Andric   return m_reg_context_sp;
154349cc55cSDimitry Andric }
155349cc55cSDimitry Andric 
LoadArtificialStackFrames()15681ad6265SDimitry Andric bool ScriptedThread::LoadArtificialStackFrames() {
15781ad6265SDimitry Andric   StructuredData::ArraySP arr_sp = GetInterface()->GetStackFrames();
15881ad6265SDimitry Andric 
15981ad6265SDimitry Andric   Status error;
16081ad6265SDimitry Andric   if (!arr_sp)
16181ad6265SDimitry Andric     return ScriptedInterface::ErrorWithMessage<bool>(
16281ad6265SDimitry Andric         LLVM_PRETTY_FUNCTION, "Failed to get scripted thread stackframes.",
16381ad6265SDimitry Andric         error, LLDBLog::Thread);
16481ad6265SDimitry Andric 
16581ad6265SDimitry Andric   size_t arr_size = arr_sp->GetSize();
16681ad6265SDimitry Andric   if (arr_size > std::numeric_limits<uint32_t>::max())
16781ad6265SDimitry Andric     return ScriptedInterface::ErrorWithMessage<bool>(
16881ad6265SDimitry Andric         LLVM_PRETTY_FUNCTION,
16981ad6265SDimitry Andric         llvm::Twine(
17081ad6265SDimitry Andric             "StackFrame array size (" + llvm::Twine(arr_size) +
17181ad6265SDimitry Andric             llvm::Twine(
172bdd1243dSDimitry Andric                 ") is greater than maximum authorized for a StackFrameList."))
17381ad6265SDimitry Andric             .str(),
17481ad6265SDimitry Andric         error, LLDBLog::Thread);
17581ad6265SDimitry Andric 
17681ad6265SDimitry Andric   StackFrameListSP frames = GetStackFrameList();
17781ad6265SDimitry Andric 
17881ad6265SDimitry Andric   for (size_t idx = 0; idx < arr_size; idx++) {
179*5f757f3fSDimitry Andric     std::optional<StructuredData::Dictionary *> maybe_dict =
180*5f757f3fSDimitry Andric         arr_sp->GetItemAtIndexAsDictionary(idx);
181*5f757f3fSDimitry Andric     if (!maybe_dict)
18281ad6265SDimitry Andric       return ScriptedInterface::ErrorWithMessage<bool>(
18381ad6265SDimitry Andric           LLVM_PRETTY_FUNCTION,
18481ad6265SDimitry Andric           llvm::Twine(
18581ad6265SDimitry Andric               "Couldn't get artificial stackframe dictionary at index (" +
18681ad6265SDimitry Andric               llvm::Twine(idx) + llvm::Twine(") from stackframe array."))
18781ad6265SDimitry Andric               .str(),
18881ad6265SDimitry Andric           error, LLDBLog::Thread);
189*5f757f3fSDimitry Andric     StructuredData::Dictionary *dict = *maybe_dict;
19081ad6265SDimitry Andric 
19181ad6265SDimitry Andric     lldb::addr_t pc;
19281ad6265SDimitry Andric     if (!dict->GetValueForKeyAsInteger("pc", pc))
19381ad6265SDimitry Andric       return ScriptedInterface::ErrorWithMessage<bool>(
19481ad6265SDimitry Andric           LLVM_PRETTY_FUNCTION,
19581ad6265SDimitry Andric           "Couldn't find value for key 'pc' in stackframe dictionary.", error,
19681ad6265SDimitry Andric           LLDBLog::Thread);
19781ad6265SDimitry Andric 
19881ad6265SDimitry Andric     Address symbol_addr;
19981ad6265SDimitry Andric     symbol_addr.SetLoadAddress(pc, &this->GetProcess()->GetTarget());
20081ad6265SDimitry Andric 
20181ad6265SDimitry Andric     lldb::addr_t cfa = LLDB_INVALID_ADDRESS;
20281ad6265SDimitry Andric     bool cfa_is_valid = false;
20381ad6265SDimitry Andric     const bool behaves_like_zeroth_frame = false;
20481ad6265SDimitry Andric     SymbolContext sc;
20581ad6265SDimitry Andric     symbol_addr.CalculateSymbolContext(&sc);
20681ad6265SDimitry Andric 
20781ad6265SDimitry Andric     StackFrameSP synth_frame_sp = std::make_shared<StackFrame>(
20881ad6265SDimitry Andric         this->shared_from_this(), idx, idx, cfa, cfa_is_valid, pc,
20981ad6265SDimitry Andric         StackFrame::Kind::Artificial, behaves_like_zeroth_frame, &sc);
21081ad6265SDimitry Andric 
21181ad6265SDimitry Andric     if (!frames->SetFrameAtIndex(static_cast<uint32_t>(idx), synth_frame_sp))
21281ad6265SDimitry Andric       return ScriptedInterface::ErrorWithMessage<bool>(
21381ad6265SDimitry Andric           LLVM_PRETTY_FUNCTION,
21481ad6265SDimitry Andric           llvm::Twine("Couldn't add frame (" + llvm::Twine(idx) +
21581ad6265SDimitry Andric                       llvm::Twine(") to ScriptedThread StackFrameList."))
21681ad6265SDimitry Andric               .str(),
21781ad6265SDimitry Andric           error, LLDBLog::Thread);
21881ad6265SDimitry Andric   }
21981ad6265SDimitry Andric 
22081ad6265SDimitry Andric   return true;
22181ad6265SDimitry Andric }
22281ad6265SDimitry Andric 
CalculateStopInfo()223349cc55cSDimitry Andric bool ScriptedThread::CalculateStopInfo() {
224349cc55cSDimitry Andric   StructuredData::DictionarySP dict_sp = GetInterface()->GetStopReason();
225349cc55cSDimitry Andric 
226349cc55cSDimitry Andric   Status error;
22704eeddc0SDimitry Andric   if (!dict_sp)
22881ad6265SDimitry Andric     return ScriptedInterface::ErrorWithMessage<bool>(
22904eeddc0SDimitry Andric         LLVM_PRETTY_FUNCTION, "Failed to get scripted thread stop info.", error,
23081ad6265SDimitry Andric         LLDBLog::Thread);
23104eeddc0SDimitry Andric 
232349cc55cSDimitry Andric   lldb::StopInfoSP stop_info_sp;
233349cc55cSDimitry Andric   lldb::StopReason stop_reason_type;
234349cc55cSDimitry Andric 
235349cc55cSDimitry Andric   if (!dict_sp->GetValueForKeyAsInteger("type", stop_reason_type))
23681ad6265SDimitry Andric     return ScriptedInterface::ErrorWithMessage<bool>(
237349cc55cSDimitry Andric         LLVM_PRETTY_FUNCTION,
238349cc55cSDimitry Andric         "Couldn't find value for key 'type' in stop reason dictionary.", error,
23981ad6265SDimitry Andric         LLDBLog::Thread);
240349cc55cSDimitry Andric 
241349cc55cSDimitry Andric   StructuredData::Dictionary *data_dict;
242349cc55cSDimitry Andric   if (!dict_sp->GetValueForKeyAsDictionary("data", data_dict))
24381ad6265SDimitry Andric     return ScriptedInterface::ErrorWithMessage<bool>(
244349cc55cSDimitry Andric         LLVM_PRETTY_FUNCTION,
24504eeddc0SDimitry Andric         "Couldn't find value for key 'data' in stop reason dictionary.", error,
24681ad6265SDimitry Andric         LLDBLog::Thread);
247349cc55cSDimitry Andric 
248349cc55cSDimitry Andric   switch (stop_reason_type) {
249349cc55cSDimitry Andric   case lldb::eStopReasonNone:
25004eeddc0SDimitry Andric     return true;
251349cc55cSDimitry Andric   case lldb::eStopReasonBreakpoint: {
252349cc55cSDimitry Andric     lldb::break_id_t break_id;
253349cc55cSDimitry Andric     data_dict->GetValueForKeyAsInteger("break_id", break_id,
254349cc55cSDimitry Andric                                        LLDB_INVALID_BREAK_ID);
255349cc55cSDimitry Andric     stop_info_sp =
256349cc55cSDimitry Andric         StopInfo::CreateStopReasonWithBreakpointSiteID(*this, break_id);
257349cc55cSDimitry Andric   } break;
258349cc55cSDimitry Andric   case lldb::eStopReasonSignal: {
25906c3fb27SDimitry Andric     uint32_t signal;
260349cc55cSDimitry Andric     llvm::StringRef description;
26106c3fb27SDimitry Andric     if (!data_dict->GetValueForKeyAsInteger("signal", signal)) {
26206c3fb27SDimitry Andric         signal = LLDB_INVALID_SIGNAL_NUMBER;
26306c3fb27SDimitry Andric         return false;
26406c3fb27SDimitry Andric     }
265349cc55cSDimitry Andric     data_dict->GetValueForKeyAsString("desc", description);
266349cc55cSDimitry Andric     stop_info_sp =
267349cc55cSDimitry Andric         StopInfo::CreateStopReasonWithSignal(*this, signal, description.data());
268349cc55cSDimitry Andric   } break;
26906c3fb27SDimitry Andric   case lldb::eStopReasonTrace: {
27006c3fb27SDimitry Andric     stop_info_sp = StopInfo::CreateStopReasonToTrace(*this);
27106c3fb27SDimitry Andric   } break;
27204eeddc0SDimitry Andric   case lldb::eStopReasonException: {
273bdd1243dSDimitry Andric #if defined(__APPLE__)
274bdd1243dSDimitry Andric     StructuredData::Dictionary *mach_exception;
275bdd1243dSDimitry Andric     if (data_dict->GetValueForKeyAsDictionary("mach_exception",
276bdd1243dSDimitry Andric                                               mach_exception)) {
277bdd1243dSDimitry Andric       llvm::StringRef value;
278bdd1243dSDimitry Andric       mach_exception->GetValueForKeyAsString("type", value);
279bdd1243dSDimitry Andric       auto exc_type =
280bdd1243dSDimitry Andric           StopInfoMachException::MachException::ExceptionCode(value.data());
28104eeddc0SDimitry Andric 
282bdd1243dSDimitry Andric       if (!exc_type)
283bdd1243dSDimitry Andric         return false;
284bdd1243dSDimitry Andric 
285bdd1243dSDimitry Andric       uint32_t exc_data_size = 0;
286bdd1243dSDimitry Andric       llvm::SmallVector<uint64_t, 3> raw_codes;
287bdd1243dSDimitry Andric 
288bdd1243dSDimitry Andric       StructuredData::Array *exc_rawcodes;
289bdd1243dSDimitry Andric       mach_exception->GetValueForKeyAsArray("rawCodes", exc_rawcodes);
290bdd1243dSDimitry Andric       if (exc_rawcodes) {
291bdd1243dSDimitry Andric         auto fetch_data = [&raw_codes](StructuredData::Object *obj) {
292bdd1243dSDimitry Andric           if (!obj)
293bdd1243dSDimitry Andric             return false;
29406c3fb27SDimitry Andric           raw_codes.push_back(obj->GetUnsignedIntegerValue());
295bdd1243dSDimitry Andric           return true;
296bdd1243dSDimitry Andric         };
297bdd1243dSDimitry Andric 
298bdd1243dSDimitry Andric         exc_rawcodes->ForEach(fetch_data);
299bdd1243dSDimitry Andric         exc_data_size = raw_codes.size();
300bdd1243dSDimitry Andric       }
301bdd1243dSDimitry Andric 
302bdd1243dSDimitry Andric       stop_info_sp = StopInfoMachException::CreateStopReasonWithMachException(
303bdd1243dSDimitry Andric           *this, *exc_type, exc_data_size,
304bdd1243dSDimitry Andric           exc_data_size >= 1 ? raw_codes[0] : 0,
305bdd1243dSDimitry Andric           exc_data_size >= 2 ? raw_codes[1] : 0,
306bdd1243dSDimitry Andric           exc_data_size >= 3 ? raw_codes[2] : 0);
307bdd1243dSDimitry Andric 
308bdd1243dSDimitry Andric       break;
309bdd1243dSDimitry Andric     }
310bdd1243dSDimitry Andric #endif
31104eeddc0SDimitry Andric     stop_info_sp =
312bdd1243dSDimitry Andric         StopInfo::CreateStopReasonWithException(*this, "EXC_BAD_ACCESS");
31304eeddc0SDimitry Andric   } break;
314349cc55cSDimitry Andric   default:
31581ad6265SDimitry Andric     return ScriptedInterface::ErrorWithMessage<bool>(
316349cc55cSDimitry Andric         LLVM_PRETTY_FUNCTION,
317349cc55cSDimitry Andric         llvm::Twine("Unsupported stop reason type (" +
318349cc55cSDimitry Andric                     llvm::Twine(stop_reason_type) + llvm::Twine(")."))
319349cc55cSDimitry Andric             .str(),
32081ad6265SDimitry Andric         error, LLDBLog::Thread);
321349cc55cSDimitry Andric   }
322349cc55cSDimitry Andric 
32304eeddc0SDimitry Andric   if (!stop_info_sp)
32404eeddc0SDimitry Andric     return false;
32504eeddc0SDimitry Andric 
326349cc55cSDimitry Andric   SetStopInfo(stop_info_sp);
327349cc55cSDimitry Andric   return true;
328349cc55cSDimitry Andric }
329349cc55cSDimitry Andric 
RefreshStateAfterStop()330349cc55cSDimitry Andric void ScriptedThread::RefreshStateAfterStop() {
331349cc55cSDimitry Andric   GetRegisterContext()->InvalidateIfNeeded(/*force=*/false);
33281ad6265SDimitry Andric   LoadArtificialStackFrames();
333349cc55cSDimitry Andric }
334349cc55cSDimitry Andric 
GetInterface() const335349cc55cSDimitry Andric lldb::ScriptedThreadInterfaceSP ScriptedThread::GetInterface() const {
33604eeddc0SDimitry Andric   return m_scripted_thread_interface_sp;
337349cc55cSDimitry Andric }
338349cc55cSDimitry Andric 
GetDynamicRegisterInfo()339349cc55cSDimitry Andric std::shared_ptr<DynamicRegisterInfo> ScriptedThread::GetDynamicRegisterInfo() {
340349cc55cSDimitry Andric   CheckInterpreterAndScriptObject();
341349cc55cSDimitry Andric 
342349cc55cSDimitry Andric   if (!m_register_info_sp) {
343349cc55cSDimitry Andric     StructuredData::DictionarySP reg_info = GetInterface()->GetRegisterInfo();
3440eae32dcSDimitry Andric 
3450eae32dcSDimitry Andric     Status error;
346349cc55cSDimitry Andric     if (!reg_info)
347bdd1243dSDimitry Andric       return ScriptedInterface::ErrorWithMessage<
348bdd1243dSDimitry Andric           std::shared_ptr<DynamicRegisterInfo>>(
349bdd1243dSDimitry Andric           LLVM_PRETTY_FUNCTION, "Failed to get scripted thread registers info.",
350bdd1243dSDimitry Andric           error, LLDBLog::Thread);
351349cc55cSDimitry Andric 
35206c3fb27SDimitry Andric     m_register_info_sp = DynamicRegisterInfo::Create(
353349cc55cSDimitry Andric         *reg_info, m_scripted_process.GetTarget().GetArchitecture());
354349cc55cSDimitry Andric   }
355349cc55cSDimitry Andric 
356349cc55cSDimitry Andric   return m_register_info_sp;
357349cc55cSDimitry Andric }
358bdd1243dSDimitry Andric 
FetchThreadExtendedInfo()359bdd1243dSDimitry Andric StructuredData::ObjectSP ScriptedThread::FetchThreadExtendedInfo() {
360bdd1243dSDimitry Andric   CheckInterpreterAndScriptObject();
361bdd1243dSDimitry Andric 
362bdd1243dSDimitry Andric   Status error;
363bdd1243dSDimitry Andric   StructuredData::ArraySP extended_info_sp = GetInterface()->GetExtendedInfo();
364bdd1243dSDimitry Andric 
365bdd1243dSDimitry Andric   if (!extended_info_sp || !extended_info_sp->GetSize())
366bdd1243dSDimitry Andric     return ScriptedInterface::ErrorWithMessage<StructuredData::ObjectSP>(
367bdd1243dSDimitry Andric         LLVM_PRETTY_FUNCTION, "No extended information found", error);
368bdd1243dSDimitry Andric 
369bdd1243dSDimitry Andric   return extended_info_sp;
370bdd1243dSDimitry Andric }
371