32llvm::Expected<std::shared_ptr<ScriptedThread>>
36 return llvm::createStringError(llvm::inconvertibleErrorCode(),
37 "Invalid scripted process.");
41 auto scripted_thread_interface =
43 if (!scripted_thread_interface)
44 return llvm::createStringError(
45 llvm::inconvertibleErrorCode(),
46 "Failed to create scripted thread interface.");
48 llvm::StringRef thread_class_name;
50 std::optional<std::string> class_name =
52 if (!class_name || class_name->empty())
53 return llvm::createStringError(
54 llvm::inconvertibleErrorCode(),
55 "Failed to get scripted thread class name.");
56 thread_class_name = *class_name;
60 auto obj_or_err = scripted_thread_interface->CreatePluginObject(
65 llvm::consumeError(obj_or_err.takeError());
66 return llvm::createStringError(llvm::inconvertibleErrorCode(),
67 "Failed to create script object.");
72 if (!owned_script_object_sp->IsValid())
73 return llvm::createStringError(llvm::inconvertibleErrorCode(),
74 "Created script object is invalid.");
76 lldb::tid_t tid = scripted_thread_interface->GetThreadID();
78 return std::make_shared<ScriptedThread>(process, scripted_thread_interface,
79 tid, owned_script_object_sp);
94 std::optional<std::string> thread_name =
GetInterface()->GetName();
102 std::optional<std::string> queue_name =
GetInterface()->GetQueue();
120 const uint32_t concrete_frame_idx =
123 if (concrete_frame_idx)
129 std::optional<std::string> reg_data =
GetInterface()->GetRegisterContext();
132 LLVM_PRETTY_FUNCTION,
"Failed to get scripted thread registers data.",
136 std::make_shared<DataBufferHeap>(reg_data->c_str(), reg_data->size()));
138 if (!data_sp->GetByteSize())
140 LLVM_PRETTY_FUNCTION,
"Failed to copy raw registers data.",
error,
143 std::shared_ptr<RegisterContextMemory> reg_ctx_memory =
144 std::make_shared<RegisterContextMemory>(
148 LLVM_PRETTY_FUNCTION,
"Failed to create a register context.",
error,
151 reg_ctx_memory->SetAllRegisterData(data_sp);
163 LLVM_PRETTY_FUNCTION,
"Failed to get scripted thread stackframes.",
166 size_t arr_size = arr_sp->GetSize();
169 LLVM_PRETTY_FUNCTION,
"StackFrame array is empty.",
error,
172 if (arr_size > std::numeric_limits<uint32_t>::max())
174 LLVM_PRETTY_FUNCTION,
176 "StackFrame array size (" + llvm::Twine(arr_size) +
177 ") is greater than maximum authorized for a StackFrameList.")
181 auto create_frame_from_dict =
182 [
this, arr_sp](
size_t idx,
183 uint32_t frame_list_idx) -> llvm::Expected<StackFrameSP> {
185 std::optional<StructuredData::Dictionary *> maybe_dict =
186 arr_sp->GetItemAtIndexAsDictionary(idx);
189 LLVM_PRETTY_FUNCTION,
191 "Couldn't get artificial stackframe dictionary at index (" +
192 llvm::Twine(idx) + llvm::Twine(
") from stackframe array."))
195 return error.ToError();
202 LLVM_PRETTY_FUNCTION,
203 "Couldn't find value for key 'pc' in stackframe dictionary.",
error,
205 return error.ToError();
212 bool cfa_is_valid =
false;
213 const bool artificial =
false;
214 const bool behaves_like_zeroth_frame = (frame_list_idx == 0);
218 return std::make_shared<StackFrame>(shared_from_this(), frame_list_idx, idx,
219 cfa, cfa_is_valid,
pc,
221 behaves_like_zeroth_frame, &sc);
224 auto create_frame_from_script_object =
225 [
this, arr_sp](
size_t idx) -> llvm::Expected<StackFrameSP> {
228 if (!object_sp || !object_sp->GetAsGeneric()) {
230 LLVM_PRETTY_FUNCTION,
231 llvm::Twine(
"Couldn't get artificial stackframe object at index (" +
233 llvm::Twine(
") from stackframe array."))
236 return error.ToError();
240 shared_from_this(),
GetInterface(),
nullptr, object_sp->GetAsGeneric());
242 if (!frame_or_error) {
244 LLVM_PRETTY_FUNCTION,
toString(frame_or_error.takeError()),
error);
245 return error.ToError();
249 lldbassert(frame_sp &&
"Couldn't initialize scripted frame.");
255 uint32_t frame_list_idx = 0;
257 for (
size_t idx = 0; idx < arr_size; idx++) {
260 auto frame_from_dict_or_err = create_frame_from_dict(idx, frame_list_idx);
261 if (!frame_from_dict_or_err) {
262 auto frame_from_script_obj_or_err = create_frame_from_script_object(idx);
264 if (!frame_from_script_obj_or_err) {
266 LLVM_PRETTY_FUNCTION,
268 "Couldn't add artificial frame (" + llvm::Twine(idx) +
269 llvm::Twine(
") to ScriptedThread StackFrameList: ") +
270 llvm::toString(frame_from_script_obj_or_err.takeError()))
274 llvm::consumeError(frame_from_dict_or_err.takeError());
275 synth_frame_sp = *frame_from_script_obj_or_err;
278 synth_frame_sp = *frame_from_dict_or_err;
281 if (!frames->SetFrameAtIndex(frame_list_idx, synth_frame_sp))
283 LLVM_PRETTY_FUNCTION,
284 llvm::Twine(
"Couldn't add frame (" + llvm::Twine(idx) +
285 llvm::Twine(
") to ScriptedThread StackFrameList."))
291 frame_list_idx += frames->SynthesizeInlineFrames(
298 frames->SetAllFramesFetched();
309 LLVM_PRETTY_FUNCTION,
"Failed to get scripted thread stop info.",
error,
319 proc->GetBreakpointSiteList().FindByAddress(
pc))
320 if (proc->IsBreakpointSitePhysicallyEnabled(*bp_site_sp))
327 if (!dict_sp->GetValueForKeyAsInteger(
"type", stop_reason_type))
329 LLVM_PRETTY_FUNCTION,
330 "Couldn't find value for key 'type' in stop reason dictionary.",
error,
334 if (!dict_sp->GetValueForKeyAsDictionary(
"data", data_dict))
336 LLVM_PRETTY_FUNCTION,
337 "Couldn't find value for key 'data' in stop reason dictionary.",
error,
340 switch (stop_reason_type) {
352 llvm::StringRef description;
365#if defined(__APPLE__)
369 llvm::StringRef value;
372 StopInfoMachException::MachException::ExceptionCode(value.data());
377 uint32_t exc_data_size = 0;
378 llvm::SmallVector<uint64_t, 3> raw_codes;
386 raw_codes.push_back(obj->GetUnsignedIntegerValue());
390 exc_rawcodes->
ForEach(fetch_data);
391 exc_data_size = raw_codes.size();
395 *
this, *exc_type, exc_data_size,
396 exc_data_size >= 1 ? raw_codes[0] : 0,
397 exc_data_size >= 2 ? raw_codes[1] : 0,
398 exc_data_size >= 3 ? raw_codes[2] : 0);
408 LLVM_PRETTY_FUNCTION,
409 llvm::Twine(
"Unsupported stop reason type (" +
410 llvm::Twine(stop_reason_type) + llvm::Twine(
")."))
440 std::shared_ptr<DynamicRegisterInfo>>(
441 LLVM_PRETTY_FUNCTION,
"Failed to get scripted thread registers info.",
457 if (!extended_info_sp || !extended_info_sp->GetSize())
459 LLVM_PRETTY_FUNCTION,
"No extended information found",
error);
461 return extended_info_sp;
static llvm::raw_ostream & error(Stream &strm)
A section + offset based address class.
bool SetLoadAddress(lldb::addr_t load_addr, Target *target, bool allow_section_end=false)
Set the address to represent load_addr.
uint32_t CalculateSymbolContext(SymbolContext *sc, lldb::SymbolContextItem resolve_scope=lldb::eSymbolContextEverything) const
Reconstruct a symbol context from an address.
A uniqued constant string class.
const char * AsCString(const char *value_if_empty) 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.
bool IsValid() const
Return whether this object is valid (i.e.
static llvm::Expected< std::shared_ptr< ScriptedFrame > > Create(lldb::ThreadSP thread_sp, lldb::ScriptedThreadInterfaceSP scripted_thread_interface_sp, StructuredData::DictionarySP args_sp, StructuredData::Generic *script_object=nullptr)
Create a ScriptedFrame from a object instanciated in the script interpreter.
static Ret ErrorWithMessage(llvm::StringRef caller_name, llvm::StringRef error_msg, Status &error, LLDBLog log_category=LLDBLog::Process)
virtual lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface()
virtual std::optional< std::string > GetScriptedThreadPluginName()
const ScriptedMetadata m_scripted_metadata
void CheckScriptedInterface() const
ScriptedProcessInterface & GetInterface() const
void ClearStackFrames() override
void CheckInterpreterAndScriptObject() const
std::shared_ptr< DynamicRegisterInfo > GetDynamicRegisterInfo()
lldb_private::StructuredData::GenericSP m_script_object_sp
const char * GetQueueName() override
Retrieve the Queue name for the queue currently using this Thread.
lldb::RegisterContextSP CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override
std::shared_ptr< DynamicRegisterInfo > m_register_info_sp
lldb::ScriptedThreadInterfaceSP GetInterface() const
StructuredData::ObjectSP FetchThreadExtendedInfo() override
bool LoadArtificialStackFrames()
lldb::ScriptedThreadInterfaceSP m_scripted_thread_interface_sp
static llvm::Expected< std::shared_ptr< ScriptedThread > > Create(ScriptedProcess &process, StructuredData::Generic *script_object=nullptr)
void RefreshStateAfterStop() override
void WillResume(lldb::StateType resume_state) override
ScriptedThread(ScriptedProcess &process, lldb::ScriptedThreadInterfaceSP interface_sp, lldb::tid_t tid, StructuredData::GenericSP script_object_sp=nullptr)
const char * GetName() override
bool CalculateStopInfo() override
Ask the thread subclass to set its stop info.
const ScriptedProcess & m_scripted_process
~ScriptedThread() override
lldb::RegisterContextSP GetRegisterContext() override
virtual uint32_t GetConcreteFrameIndex()
Query this frame to find what frame it is in this Thread's StackFrameList, not counting inlined frame...
@ Synthetic
An synthetic stack frame (e.g.
static lldb::StopInfoSP CreateStopReasonWithMachException(Thread &thread, uint32_t exc_type, uint32_t exc_data_count, uint64_t exc_code, uint64_t exc_sub_code, uint64_t exc_sub_sub_code, bool pc_already_adjusted=true, bool adjust_pc_if_needed=false)
static lldb::StopInfoSP CreateStopReasonToTrace(Thread &thread)
static lldb::StopInfoSP CreateStopReasonWithSignal(Thread &thread, int signo, const char *description=nullptr, std::optional< int > code=std::nullopt)
static lldb::StopInfoSP CreateStopReasonWithException(Thread &thread, const char *description)
static lldb::StopInfoSP CreateStopReasonWithBreakpointSiteID(Thread &thread, lldb::break_id_t break_id)
bool ForEach(std::function< bool(Object *object)> const &foreach_callback) const
bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const
bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result) const
bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const
bool GetValueForKeyAsDictionary(llvm::StringRef key, Dictionary *&result) const
std::shared_ptr< Generic > GenericSP
std::shared_ptr< Dictionary > DictionarySP
std::shared_ptr< Object > ObjectSP
std::shared_ptr< Array > ArraySP
Defines a symbol context baton that can be handed other debug core functions.
void SetStopInfo(const lldb::StopInfoSP &stop_info_sp)
virtual void DestroyThread()
virtual void ClearStackFrames()
virtual Unwind & GetUnwinder()
Thread(Process &process, lldb::tid_t tid, bool use_invalid_index_id=false)
Constructor.
void SetThreadStoppedAtUnexecutedBP(lldb::addr_t pc)
When a thread stops at an enabled BreakpointSite that has not executed, the Process plugin should cal...
lldb::ProcessSP GetProcess() const
lldb::StackFrameListSP GetStackFrameList()
lldb::RegisterContextSP m_reg_context_sp
The register context for this thread's current register state.
lldb::RegisterContextSP CreateRegisterContextForFrame(StackFrame *frame)
#define LLDB_INVALID_BREAK_ID
#define LLDB_INVALID_SIGNAL_NUMBER
#define LLDB_INVALID_ADDRESS
A class that represents a running process on the host machine.
std::string toString(FormatterBytecode::OpCodes op)
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::BreakpointSite > BreakpointSiteSP
StateType
Process and Thread States.
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::ScriptedThreadInterface > ScriptedThreadInterfaceSP
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::StopInfo > StopInfoSP
StopReason
Thread stop reasons.
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
std::shared_ptr< lldb_private::StackFrameList > StackFrameListSP