159d8dd79SMed Ismail Bennani //===-- ScriptedThread.cpp ------------------------------------------------===//
259d8dd79SMed Ismail Bennani //
359d8dd79SMed Ismail Bennani // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
459d8dd79SMed Ismail Bennani // See https://llvm.org/LICENSE.txt for license information.
559d8dd79SMed Ismail Bennani // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
659d8dd79SMed Ismail Bennani //
759d8dd79SMed Ismail Bennani //===----------------------------------------------------------------------===//
859d8dd79SMed Ismail Bennani
959d8dd79SMed Ismail Bennani #include "ScriptedThread.h"
1059d8dd79SMed Ismail Bennani
1159d8dd79SMed Ismail Bennani #include "Plugins/Process/Utility/RegisterContextThreadMemory.h"
12edc77353SMed Ismail Bennani #include "Plugins/Process/Utility/StopInfoMachException.h"
1359d8dd79SMed Ismail Bennani #include "lldb/Target/OperatingSystem.h"
1459d8dd79SMed Ismail Bennani #include "lldb/Target/Process.h"
1559d8dd79SMed Ismail Bennani #include "lldb/Target/RegisterContext.h"
1659d8dd79SMed Ismail Bennani #include "lldb/Target/StopInfo.h"
1759d8dd79SMed Ismail Bennani #include "lldb/Target/Unwind.h"
1859d8dd79SMed Ismail Bennani #include "lldb/Utility/DataBufferHeap.h"
19c34698a8SPavel Labath #include "lldb/Utility/LLDBLog.h"
2059d8dd79SMed Ismail Bennani #include <memory>
21f190ce62SKazu Hirata #include <optional>
2259d8dd79SMed Ismail Bennani
2359d8dd79SMed Ismail Bennani using namespace lldb;
2459d8dd79SMed Ismail Bennani using namespace lldb_private;
2559d8dd79SMed Ismail Bennani
CheckInterpreterAndScriptObject() const2659d8dd79SMed Ismail Bennani void ScriptedThread::CheckInterpreterAndScriptObject() const {
2759d8dd79SMed Ismail Bennani lldbassert(m_script_object_sp && "Invalid Script Object.");
2859d8dd79SMed Ismail Bennani lldbassert(GetInterface() && "Invalid Scripted Thread Interface.");
2959d8dd79SMed Ismail Bennani }
3059d8dd79SMed Ismail Bennani
3145148bfeSMed Ismail Bennani llvm::Expected<std::shared_ptr<ScriptedThread>>
Create(ScriptedProcess & process,StructuredData::Generic * script_object)3245148bfeSMed Ismail Bennani ScriptedThread::Create(ScriptedProcess &process,
3345148bfeSMed Ismail Bennani StructuredData::Generic *script_object) {
3445148bfeSMed Ismail Bennani if (!process.IsValid())
3545148bfeSMed Ismail Bennani return llvm::createStringError(llvm::inconvertibleErrorCode(),
3645148bfeSMed Ismail Bennani "Invalid scripted process.");
3759d8dd79SMed Ismail Bennani
38a3d4f739SMed Ismail Bennani process.CheckScriptedInterface();
3959d8dd79SMed Ismail Bennani
4045148bfeSMed Ismail Bennani auto scripted_thread_interface =
4145148bfeSMed Ismail Bennani process.GetInterface().CreateScriptedThreadInterface();
4245148bfeSMed Ismail Bennani if (!scripted_thread_interface)
4345148bfeSMed Ismail Bennani return llvm::createStringError(
4445148bfeSMed Ismail Bennani llvm::inconvertibleErrorCode(),
4545148bfeSMed Ismail Bennani "Failed to create scripted thread interface.");
4659d8dd79SMed Ismail Bennani
4745148bfeSMed Ismail Bennani llvm::StringRef thread_class_name;
4845148bfeSMed Ismail Bennani if (!script_object) {
492fe83274SKazu Hirata std::optional<std::string> class_name =
5059d8dd79SMed Ismail Bennani process.GetInterface().GetScriptedThreadPluginName();
5145148bfeSMed Ismail Bennani if (!class_name || class_name->empty())
5245148bfeSMed Ismail Bennani return llvm::createStringError(
5345148bfeSMed Ismail Bennani llvm::inconvertibleErrorCode(),
5445148bfeSMed Ismail Bennani "Failed to get scripted thread class name.");
5545148bfeSMed Ismail Bennani thread_class_name = *class_name;
5659d8dd79SMed Ismail Bennani }
5759d8dd79SMed Ismail Bennani
5859d8dd79SMed Ismail Bennani ExecutionContext exe_ctx(process);
59f22d82ceSMed Ismail Bennani auto obj_or_err = scripted_thread_interface->CreatePluginObject(
60d9f4d1b0SMed Ismail Bennani thread_class_name, exe_ctx, process.m_scripted_metadata.GetArgsSP(),
61d9f4d1b0SMed Ismail Bennani script_object);
6259d8dd79SMed Ismail Bennani
632abf997fSMed Ismail Bennani if (!obj_or_err) {
642abf997fSMed Ismail Bennani llvm::consumeError(obj_or_err.takeError());
6545148bfeSMed Ismail Bennani return llvm::createStringError(llvm::inconvertibleErrorCode(),
6645148bfeSMed Ismail Bennani "Failed to create script object.");
672abf997fSMed Ismail Bennani }
68f22d82ceSMed Ismail Bennani
69f22d82ceSMed Ismail Bennani StructuredData::GenericSP owned_script_object_sp = *obj_or_err;
70f22d82ceSMed Ismail Bennani
7145148bfeSMed Ismail Bennani if (!owned_script_object_sp->IsValid())
7245148bfeSMed Ismail Bennani return llvm::createStringError(llvm::inconvertibleErrorCode(),
7345148bfeSMed Ismail Bennani "Created script object is invalid.");
7459d8dd79SMed Ismail Bennani
75d3e0f7e1SMed Ismail Bennani lldb::tid_t tid = scripted_thread_interface->GetThreadID();
7645148bfeSMed Ismail Bennani
7745148bfeSMed Ismail Bennani return std::make_shared<ScriptedThread>(process, scripted_thread_interface,
7845148bfeSMed Ismail Bennani tid, owned_script_object_sp);
7959d8dd79SMed Ismail Bennani }
8059d8dd79SMed Ismail Bennani
ScriptedThread(ScriptedProcess & process,ScriptedThreadInterfaceSP interface_sp,lldb::tid_t tid,StructuredData::GenericSP script_object_sp)8145148bfeSMed Ismail Bennani ScriptedThread::ScriptedThread(ScriptedProcess &process,
8245148bfeSMed Ismail Bennani ScriptedThreadInterfaceSP interface_sp,
8345148bfeSMed Ismail Bennani lldb::tid_t tid,
8445148bfeSMed Ismail Bennani StructuredData::GenericSP script_object_sp)
8545148bfeSMed Ismail Bennani : Thread(process, tid), m_scripted_process(process),
8645148bfeSMed Ismail Bennani m_scripted_thread_interface_sp(interface_sp),
8745148bfeSMed Ismail Bennani m_script_object_sp(script_object_sp) {}
8845148bfeSMed Ismail Bennani
~ScriptedThread()8959d8dd79SMed Ismail Bennani ScriptedThread::~ScriptedThread() { DestroyThread(); }
9059d8dd79SMed Ismail Bennani
GetName()9159d8dd79SMed Ismail Bennani const char *ScriptedThread::GetName() {
9259d8dd79SMed Ismail Bennani CheckInterpreterAndScriptObject();
932fe83274SKazu Hirata std::optional<std::string> thread_name = GetInterface()->GetName();
9459d8dd79SMed Ismail Bennani if (!thread_name)
9559d8dd79SMed Ismail Bennani return nullptr;
9659d8dd79SMed Ismail Bennani return ConstString(thread_name->c_str()).AsCString();
9759d8dd79SMed Ismail Bennani }
9859d8dd79SMed Ismail Bennani
GetQueueName()9959d8dd79SMed Ismail Bennani const char *ScriptedThread::GetQueueName() {
10059d8dd79SMed Ismail Bennani CheckInterpreterAndScriptObject();
1012fe83274SKazu Hirata std::optional<std::string> queue_name = GetInterface()->GetQueue();
10259d8dd79SMed Ismail Bennani if (!queue_name)
10359d8dd79SMed Ismail Bennani return nullptr;
10459d8dd79SMed Ismail Bennani return ConstString(queue_name->c_str()).AsCString();
10559d8dd79SMed Ismail Bennani }
10659d8dd79SMed Ismail Bennani
WillResume(StateType resume_state)10759d8dd79SMed Ismail Bennani void ScriptedThread::WillResume(StateType resume_state) {}
10859d8dd79SMed Ismail Bennani
ClearStackFrames()10959d8dd79SMed Ismail Bennani void ScriptedThread::ClearStackFrames() { Thread::ClearStackFrames(); }
11059d8dd79SMed Ismail Bennani
GetRegisterContext()11159d8dd79SMed Ismail Bennani RegisterContextSP ScriptedThread::GetRegisterContext() {
112676576b6SMed Ismail Bennani if (!m_reg_context_sp)
113676576b6SMed Ismail Bennani m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
11459d8dd79SMed Ismail Bennani return m_reg_context_sp;
11559d8dd79SMed Ismail Bennani }
11659d8dd79SMed Ismail Bennani
11759d8dd79SMed Ismail Bennani RegisterContextSP
CreateRegisterContextForFrame(StackFrame * frame)11859d8dd79SMed Ismail Bennani ScriptedThread::CreateRegisterContextForFrame(StackFrame *frame) {
119676576b6SMed Ismail Bennani const uint32_t concrete_frame_idx =
120676576b6SMed Ismail Bennani frame ? frame->GetConcreteFrameIndex() : 0;
12159d8dd79SMed Ismail Bennani
122676576b6SMed Ismail Bennani if (concrete_frame_idx)
12359d8dd79SMed Ismail Bennani return GetUnwinder().CreateRegisterContextForFrame(frame);
124676576b6SMed Ismail Bennani
125676576b6SMed Ismail Bennani lldb::RegisterContextSP reg_ctx_sp;
126676576b6SMed Ismail Bennani Status error;
127676576b6SMed Ismail Bennani
1282fe83274SKazu Hirata std::optional<std::string> reg_data = GetInterface()->GetRegisterContext();
129676576b6SMed Ismail Bennani if (!reg_data)
1306eddd987SMed Ismail Bennani return ScriptedInterface::ErrorWithMessage<lldb::RegisterContextSP>(
131676576b6SMed Ismail Bennani LLVM_PRETTY_FUNCTION, "Failed to get scripted thread registers data.",
132a007a6d8SPavel Labath error, LLDBLog::Thread);
133676576b6SMed Ismail Bennani
134676576b6SMed Ismail Bennani DataBufferSP data_sp(
135676576b6SMed Ismail Bennani std::make_shared<DataBufferHeap>(reg_data->c_str(), reg_data->size()));
136676576b6SMed Ismail Bennani
137676576b6SMed Ismail Bennani if (!data_sp->GetByteSize())
1386eddd987SMed Ismail Bennani return ScriptedInterface::ErrorWithMessage<lldb::RegisterContextSP>(
139676576b6SMed Ismail Bennani LLVM_PRETTY_FUNCTION, "Failed to copy raw registers data.", error,
140a007a6d8SPavel Labath LLDBLog::Thread);
141676576b6SMed Ismail Bennani
142676576b6SMed Ismail Bennani std::shared_ptr<RegisterContextMemory> reg_ctx_memory =
143676576b6SMed Ismail Bennani std::make_shared<RegisterContextMemory>(
144676576b6SMed Ismail Bennani *this, 0, *GetDynamicRegisterInfo(), LLDB_INVALID_ADDRESS);
145676576b6SMed Ismail Bennani if (!reg_ctx_memory)
1466eddd987SMed Ismail Bennani return ScriptedInterface::ErrorWithMessage<lldb::RegisterContextSP>(
147676576b6SMed Ismail Bennani LLVM_PRETTY_FUNCTION, "Failed to create a register context.", error,
148a007a6d8SPavel Labath LLDBLog::Thread);
149676576b6SMed Ismail Bennani
150676576b6SMed Ismail Bennani reg_ctx_memory->SetAllRegisterData(data_sp);
151676576b6SMed Ismail Bennani m_reg_context_sp = reg_ctx_memory;
152676576b6SMed Ismail Bennani
153676576b6SMed Ismail Bennani return m_reg_context_sp;
15459d8dd79SMed Ismail Bennani }
15559d8dd79SMed Ismail Bennani
LoadArtificialStackFrames()15670665844SMed Ismail Bennani bool ScriptedThread::LoadArtificialStackFrames() {
15770665844SMed Ismail Bennani StructuredData::ArraySP arr_sp = GetInterface()->GetStackFrames();
15870665844SMed Ismail Bennani
15970665844SMed Ismail Bennani Status error;
16070665844SMed Ismail Bennani if (!arr_sp)
1616eddd987SMed Ismail Bennani return ScriptedInterface::ErrorWithMessage<bool>(
16270665844SMed Ismail Bennani LLVM_PRETTY_FUNCTION, "Failed to get scripted thread stackframes.",
16370665844SMed Ismail Bennani error, LLDBLog::Thread);
16470665844SMed Ismail Bennani
16570665844SMed Ismail Bennani size_t arr_size = arr_sp->GetSize();
16670665844SMed Ismail Bennani if (arr_size > std::numeric_limits<uint32_t>::max())
1676eddd987SMed Ismail Bennani return ScriptedInterface::ErrorWithMessage<bool>(
16870665844SMed Ismail Bennani LLVM_PRETTY_FUNCTION,
16970665844SMed Ismail Bennani llvm::Twine(
17070665844SMed Ismail Bennani "StackFrame array size (" + llvm::Twine(arr_size) +
17170665844SMed Ismail Bennani llvm::Twine(
1727240436cSGabriel Ravier ") is greater than maximum authorized for a StackFrameList."))
17370665844SMed Ismail Bennani .str(),
17470665844SMed Ismail Bennani error, LLDBLog::Thread);
17570665844SMed Ismail Bennani
17670665844SMed Ismail Bennani StackFrameListSP frames = GetStackFrameList();
17770665844SMed Ismail Bennani
17870665844SMed Ismail Bennani for (size_t idx = 0; idx < arr_size; idx++) {
179*133bcaceSAlex Langford std::optional<StructuredData::Dictionary *> maybe_dict =
180*133bcaceSAlex Langford arr_sp->GetItemAtIndexAsDictionary(idx);
181*133bcaceSAlex Langford if (!maybe_dict)
1826eddd987SMed Ismail Bennani return ScriptedInterface::ErrorWithMessage<bool>(
18370665844SMed Ismail Bennani LLVM_PRETTY_FUNCTION,
18470665844SMed Ismail Bennani llvm::Twine(
18570665844SMed Ismail Bennani "Couldn't get artificial stackframe dictionary at index (" +
18670665844SMed Ismail Bennani llvm::Twine(idx) + llvm::Twine(") from stackframe array."))
18770665844SMed Ismail Bennani .str(),
18870665844SMed Ismail Bennani error, LLDBLog::Thread);
189*133bcaceSAlex Langford StructuredData::Dictionary *dict = *maybe_dict;
19070665844SMed Ismail Bennani
19170665844SMed Ismail Bennani lldb::addr_t pc;
19270665844SMed Ismail Bennani if (!dict->GetValueForKeyAsInteger("pc", pc))
19370665844SMed Ismail Bennani return ScriptedInterface::ErrorWithMessage<bool>(
19470665844SMed Ismail Bennani LLVM_PRETTY_FUNCTION,
19570665844SMed Ismail Bennani "Couldn't find value for key 'pc' in stackframe dictionary.", error,
19670665844SMed Ismail Bennani LLDBLog::Thread);
19770665844SMed Ismail Bennani
19870665844SMed Ismail Bennani Address symbol_addr;
19970665844SMed Ismail Bennani symbol_addr.SetLoadAddress(pc, &this->GetProcess()->GetTarget());
20070665844SMed Ismail Bennani
20170665844SMed Ismail Bennani lldb::addr_t cfa = LLDB_INVALID_ADDRESS;
20270665844SMed Ismail Bennani bool cfa_is_valid = false;
20370665844SMed Ismail Bennani const bool behaves_like_zeroth_frame = false;
20470665844SMed Ismail Bennani SymbolContext sc;
20570665844SMed Ismail Bennani symbol_addr.CalculateSymbolContext(&sc);
20670665844SMed Ismail Bennani
20770665844SMed Ismail Bennani StackFrameSP synth_frame_sp = std::make_shared<StackFrame>(
20870665844SMed Ismail Bennani this->shared_from_this(), idx, idx, cfa, cfa_is_valid, pc,
20970665844SMed Ismail Bennani StackFrame::Kind::Artificial, behaves_like_zeroth_frame, &sc);
21070665844SMed Ismail Bennani
21170665844SMed Ismail Bennani if (!frames->SetFrameAtIndex(static_cast<uint32_t>(idx), synth_frame_sp))
2126eddd987SMed Ismail Bennani return ScriptedInterface::ErrorWithMessage<bool>(
21370665844SMed Ismail Bennani LLVM_PRETTY_FUNCTION,
21470665844SMed Ismail Bennani llvm::Twine("Couldn't add frame (" + llvm::Twine(idx) +
21570665844SMed Ismail Bennani llvm::Twine(") to ScriptedThread StackFrameList."))
21670665844SMed Ismail Bennani .str(),
21770665844SMed Ismail Bennani error, LLDBLog::Thread);
21870665844SMed Ismail Bennani }
21970665844SMed Ismail Bennani
22070665844SMed Ismail Bennani return true;
22170665844SMed Ismail Bennani }
22270665844SMed Ismail Bennani
CalculateStopInfo()22359d8dd79SMed Ismail Bennani bool ScriptedThread::CalculateStopInfo() {
22459d8dd79SMed Ismail Bennani StructuredData::DictionarySP dict_sp = GetInterface()->GetStopReason();
22559d8dd79SMed Ismail Bennani
22659d8dd79SMed Ismail Bennani Status error;
227cfa55bfeSMed Ismail Bennani if (!dict_sp)
2286eddd987SMed Ismail Bennani return ScriptedInterface::ErrorWithMessage<bool>(
229cfa55bfeSMed Ismail Bennani LLVM_PRETTY_FUNCTION, "Failed to get scripted thread stop info.", error,
230a007a6d8SPavel Labath LLDBLog::Thread);
231cfa55bfeSMed Ismail Bennani
23259d8dd79SMed Ismail Bennani lldb::StopInfoSP stop_info_sp;
23359d8dd79SMed Ismail Bennani lldb::StopReason stop_reason_type;
23459d8dd79SMed Ismail Bennani
23559d8dd79SMed Ismail Bennani if (!dict_sp->GetValueForKeyAsInteger("type", stop_reason_type))
2366eddd987SMed Ismail Bennani return ScriptedInterface::ErrorWithMessage<bool>(
23788a941baSMed Ismail Bennani LLVM_PRETTY_FUNCTION,
238676576b6SMed Ismail Bennani "Couldn't find value for key 'type' in stop reason dictionary.", error,
239a007a6d8SPavel Labath LLDBLog::Thread);
24059d8dd79SMed Ismail Bennani
24159d8dd79SMed Ismail Bennani StructuredData::Dictionary *data_dict;
24259d8dd79SMed Ismail Bennani if (!dict_sp->GetValueForKeyAsDictionary("data", data_dict))
2436eddd987SMed Ismail Bennani return ScriptedInterface::ErrorWithMessage<bool>(
24488a941baSMed Ismail Bennani LLVM_PRETTY_FUNCTION,
245cfa55bfeSMed Ismail Bennani "Couldn't find value for key 'data' in stop reason dictionary.", error,
246a007a6d8SPavel Labath LLDBLog::Thread);
24759d8dd79SMed Ismail Bennani
24859d8dd79SMed Ismail Bennani switch (stop_reason_type) {
24959d8dd79SMed Ismail Bennani case lldb::eStopReasonNone:
250cfa55bfeSMed Ismail Bennani return true;
25159d8dd79SMed Ismail Bennani case lldb::eStopReasonBreakpoint: {
25259d8dd79SMed Ismail Bennani lldb::break_id_t break_id;
25359d8dd79SMed Ismail Bennani data_dict->GetValueForKeyAsInteger("break_id", break_id,
25459d8dd79SMed Ismail Bennani LLDB_INVALID_BREAK_ID);
25559d8dd79SMed Ismail Bennani stop_info_sp =
25659d8dd79SMed Ismail Bennani StopInfo::CreateStopReasonWithBreakpointSiteID(*this, break_id);
25759d8dd79SMed Ismail Bennani } break;
25859d8dd79SMed Ismail Bennani case lldb::eStopReasonSignal: {
2590c5b6320SMed Ismail Bennani uint32_t signal;
26059d8dd79SMed Ismail Bennani llvm::StringRef description;
2610c5b6320SMed Ismail Bennani if (!data_dict->GetValueForKeyAsInteger("signal", signal)) {
2620c5b6320SMed Ismail Bennani signal = LLDB_INVALID_SIGNAL_NUMBER;
2630c5b6320SMed Ismail Bennani return false;
2640c5b6320SMed Ismail Bennani }
26559d8dd79SMed Ismail Bennani data_dict->GetValueForKeyAsString("desc", description);
26659d8dd79SMed Ismail Bennani stop_info_sp =
26759d8dd79SMed Ismail Bennani StopInfo::CreateStopReasonWithSignal(*this, signal, description.data());
26859d8dd79SMed Ismail Bennani } break;
2698f407b8eSMed Ismail Bennani case lldb::eStopReasonTrace: {
2708f407b8eSMed Ismail Bennani stop_info_sp = StopInfo::CreateStopReasonToTrace(*this);
2718f407b8eSMed Ismail Bennani } break;
272cfa55bfeSMed Ismail Bennani case lldb::eStopReasonException: {
273edc77353SMed Ismail Bennani #if defined(__APPLE__)
274edc77353SMed Ismail Bennani StructuredData::Dictionary *mach_exception;
275edc77353SMed Ismail Bennani if (data_dict->GetValueForKeyAsDictionary("mach_exception",
276edc77353SMed Ismail Bennani mach_exception)) {
277edc77353SMed Ismail Bennani llvm::StringRef value;
278edc77353SMed Ismail Bennani mach_exception->GetValueForKeyAsString("type", value);
279edc77353SMed Ismail Bennani auto exc_type =
280edc77353SMed Ismail Bennani StopInfoMachException::MachException::ExceptionCode(value.data());
281cfa55bfeSMed Ismail Bennani
282edc77353SMed Ismail Bennani if (!exc_type)
283edc77353SMed Ismail Bennani return false;
284edc77353SMed Ismail Bennani
285edc77353SMed Ismail Bennani uint32_t exc_data_size = 0;
286edc77353SMed Ismail Bennani llvm::SmallVector<uint64_t, 3> raw_codes;
287edc77353SMed Ismail Bennani
288edc77353SMed Ismail Bennani StructuredData::Array *exc_rawcodes;
289edc77353SMed Ismail Bennani mach_exception->GetValueForKeyAsArray("rawCodes", exc_rawcodes);
290edc77353SMed Ismail Bennani if (exc_rawcodes) {
291edc77353SMed Ismail Bennani auto fetch_data = [&raw_codes](StructuredData::Object *obj) {
292edc77353SMed Ismail Bennani if (!obj)
293edc77353SMed Ismail Bennani return false;
2941370a1cbSMed Ismail Bennani raw_codes.push_back(obj->GetUnsignedIntegerValue());
295edc77353SMed Ismail Bennani return true;
296edc77353SMed Ismail Bennani };
297edc77353SMed Ismail Bennani
298edc77353SMed Ismail Bennani exc_rawcodes->ForEach(fetch_data);
299edc77353SMed Ismail Bennani exc_data_size = raw_codes.size();
300edc77353SMed Ismail Bennani }
301edc77353SMed Ismail Bennani
302edc77353SMed Ismail Bennani stop_info_sp = StopInfoMachException::CreateStopReasonWithMachException(
303edc77353SMed Ismail Bennani *this, *exc_type, exc_data_size,
304edc77353SMed Ismail Bennani exc_data_size >= 1 ? raw_codes[0] : 0,
305edc77353SMed Ismail Bennani exc_data_size >= 2 ? raw_codes[1] : 0,
306edc77353SMed Ismail Bennani exc_data_size >= 3 ? raw_codes[2] : 0);
307edc77353SMed Ismail Bennani
308edc77353SMed Ismail Bennani break;
309edc77353SMed Ismail Bennani }
310edc77353SMed Ismail Bennani #endif
311cfa55bfeSMed Ismail Bennani stop_info_sp =
312edc77353SMed Ismail Bennani StopInfo::CreateStopReasonWithException(*this, "EXC_BAD_ACCESS");
313cfa55bfeSMed Ismail Bennani } break;
31459d8dd79SMed Ismail Bennani default:
3156eddd987SMed Ismail Bennani return ScriptedInterface::ErrorWithMessage<bool>(
31688a941baSMed Ismail Bennani LLVM_PRETTY_FUNCTION,
31759d8dd79SMed Ismail Bennani llvm::Twine("Unsupported stop reason type (" +
31859d8dd79SMed Ismail Bennani llvm::Twine(stop_reason_type) + llvm::Twine(")."))
31959d8dd79SMed Ismail Bennani .str(),
320a007a6d8SPavel Labath error, LLDBLog::Thread);
32159d8dd79SMed Ismail Bennani }
32259d8dd79SMed Ismail Bennani
323cfa55bfeSMed Ismail Bennani if (!stop_info_sp)
324cfa55bfeSMed Ismail Bennani return false;
325cfa55bfeSMed Ismail Bennani
32659d8dd79SMed Ismail Bennani SetStopInfo(stop_info_sp);
32759d8dd79SMed Ismail Bennani return true;
32859d8dd79SMed Ismail Bennani }
32959d8dd79SMed Ismail Bennani
RefreshStateAfterStop()33059d8dd79SMed Ismail Bennani void ScriptedThread::RefreshStateAfterStop() {
331676576b6SMed Ismail Bennani GetRegisterContext()->InvalidateIfNeeded(/*force=*/false);
33270665844SMed Ismail Bennani LoadArtificialStackFrames();
33359d8dd79SMed Ismail Bennani }
33459d8dd79SMed Ismail Bennani
GetInterface() const33559d8dd79SMed Ismail Bennani lldb::ScriptedThreadInterfaceSP ScriptedThread::GetInterface() const {
3361b86344fSMed Ismail Bennani return m_scripted_thread_interface_sp;
33759d8dd79SMed Ismail Bennani }
33859d8dd79SMed Ismail Bennani
GetDynamicRegisterInfo()33959d8dd79SMed Ismail Bennani std::shared_ptr<DynamicRegisterInfo> ScriptedThread::GetDynamicRegisterInfo() {
34059d8dd79SMed Ismail Bennani CheckInterpreterAndScriptObject();
34159d8dd79SMed Ismail Bennani
34259d8dd79SMed Ismail Bennani if (!m_register_info_sp) {
34359d8dd79SMed Ismail Bennani StructuredData::DictionarySP reg_info = GetInterface()->GetRegisterInfo();
344caea440aSMed Ismail Bennani
345caea440aSMed Ismail Bennani Status error;
34659d8dd79SMed Ismail Bennani if (!reg_info)
347cc05487aSMed Ismail Bennani return ScriptedInterface::ErrorWithMessage<
348cc05487aSMed Ismail Bennani std::shared_ptr<DynamicRegisterInfo>>(
349cc05487aSMed Ismail Bennani LLVM_PRETTY_FUNCTION, "Failed to get scripted thread registers info.",
350cc05487aSMed Ismail Bennani error, LLDBLog::Thread);
35159d8dd79SMed Ismail Bennani
35235b0b244SAlex Langford m_register_info_sp = DynamicRegisterInfo::Create(
35359d8dd79SMed Ismail Bennani *reg_info, m_scripted_process.GetTarget().GetArchitecture());
35459d8dd79SMed Ismail Bennani }
35559d8dd79SMed Ismail Bennani
35659d8dd79SMed Ismail Bennani return m_register_info_sp;
35759d8dd79SMed Ismail Bennani }
35878d6e1d1SMed Ismail Bennani
FetchThreadExtendedInfo()35978d6e1d1SMed Ismail Bennani StructuredData::ObjectSP ScriptedThread::FetchThreadExtendedInfo() {
36078d6e1d1SMed Ismail Bennani CheckInterpreterAndScriptObject();
36178d6e1d1SMed Ismail Bennani
36278d6e1d1SMed Ismail Bennani Status error;
36378d6e1d1SMed Ismail Bennani StructuredData::ArraySP extended_info_sp = GetInterface()->GetExtendedInfo();
36478d6e1d1SMed Ismail Bennani
36578d6e1d1SMed Ismail Bennani if (!extended_info_sp || !extended_info_sp->GetSize())
36678d6e1d1SMed Ismail Bennani return ScriptedInterface::ErrorWithMessage<StructuredData::ObjectSP>(
36778d6e1d1SMed Ismail Bennani LLVM_PRETTY_FUNCTION, "No extended information found", error);
36878d6e1d1SMed Ismail Bennani
36978d6e1d1SMed Ismail Bennani return extended_info_sp;
37078d6e1d1SMed Ismail Bennani }
371