[mlir][py] Enable loading only specified dialects during creation. (#121421)
[llvm-project.git] / lldb / source / API / SBThread.cpp
blob4e61c83889b0b093a6b12200f8a1509013ab7460
1 //===-- SBThread.cpp ------------------------------------------------------===//
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 //===----------------------------------------------------------------------===//
9 #include "lldb/API/SBThread.h"
10 #include "Utils.h"
11 #include "lldb/API/SBAddress.h"
12 #include "lldb/API/SBDebugger.h"
13 #include "lldb/API/SBEvent.h"
14 #include "lldb/API/SBFileSpec.h"
15 #include "lldb/API/SBFormat.h"
16 #include "lldb/API/SBFrame.h"
17 #include "lldb/API/SBProcess.h"
18 #include "lldb/API/SBStream.h"
19 #include "lldb/API/SBStructuredData.h"
20 #include "lldb/API/SBSymbolContext.h"
21 #include "lldb/API/SBThreadCollection.h"
22 #include "lldb/API/SBThreadPlan.h"
23 #include "lldb/API/SBValue.h"
24 #include "lldb/Breakpoint/BreakpointLocation.h"
25 #include "lldb/Core/Debugger.h"
26 #include "lldb/Core/StructuredDataImpl.h"
27 #include "lldb/Interpreter/CommandInterpreter.h"
28 #include "lldb/Symbol/CompileUnit.h"
29 #include "lldb/Symbol/SymbolContext.h"
30 #include "lldb/Target/Process.h"
31 #include "lldb/Target/Queue.h"
32 #include "lldb/Target/StopInfo.h"
33 #include "lldb/Target/SystemRuntime.h"
34 #include "lldb/Target/Target.h"
35 #include "lldb/Target/Thread.h"
36 #include "lldb/Target/ThreadPlan.h"
37 #include "lldb/Target/ThreadPlanStepInRange.h"
38 #include "lldb/Target/ThreadPlanStepInstruction.h"
39 #include "lldb/Target/ThreadPlanStepOut.h"
40 #include "lldb/Target/ThreadPlanStepRange.h"
41 #include "lldb/Utility/Instrumentation.h"
42 #include "lldb/Utility/State.h"
43 #include "lldb/Utility/Stream.h"
44 #include "lldb/Utility/StructuredData.h"
45 #include "lldb/ValueObject/ValueObject.h"
46 #include "lldb/lldb-enumerations.h"
48 #include <memory>
50 using namespace lldb;
51 using namespace lldb_private;
53 const char *SBThread::GetBroadcasterClassName() {
54 LLDB_INSTRUMENT();
56 return ConstString(Thread::GetStaticBroadcasterClass()).AsCString();
59 // Constructors
60 SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {
61 LLDB_INSTRUMENT_VA(this);
64 SBThread::SBThread(const ThreadSP &lldb_object_sp)
65 : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {
66 LLDB_INSTRUMENT_VA(this, lldb_object_sp);
69 SBThread::SBThread(const SBThread &rhs) {
70 LLDB_INSTRUMENT_VA(this, rhs);
72 m_opaque_sp = clone(rhs.m_opaque_sp);
75 // Assignment operator
77 const lldb::SBThread &SBThread::operator=(const SBThread &rhs) {
78 LLDB_INSTRUMENT_VA(this, rhs);
80 if (this != &rhs)
81 m_opaque_sp = clone(rhs.m_opaque_sp);
82 return *this;
85 // Destructor
86 SBThread::~SBThread() = default;
88 lldb::SBQueue SBThread::GetQueue() const {
89 LLDB_INSTRUMENT_VA(this);
91 SBQueue sb_queue;
92 QueueSP queue_sp;
93 std::unique_lock<std::recursive_mutex> lock;
94 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
96 if (exe_ctx.HasThreadScope()) {
97 Process::StopLocker stop_locker;
98 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
99 queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
100 if (queue_sp) {
101 sb_queue.SetQueue(queue_sp);
106 return sb_queue;
109 bool SBThread::IsValid() const {
110 LLDB_INSTRUMENT_VA(this);
111 return this->operator bool();
113 SBThread::operator bool() const {
114 LLDB_INSTRUMENT_VA(this);
116 std::unique_lock<std::recursive_mutex> lock;
117 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
119 Target *target = exe_ctx.GetTargetPtr();
120 Process *process = exe_ctx.GetProcessPtr();
121 if (target && process) {
122 Process::StopLocker stop_locker;
123 if (stop_locker.TryLock(&process->GetRunLock()))
124 return m_opaque_sp->GetThreadSP().get() != nullptr;
126 // Without a valid target & process, this thread can't be valid.
127 return false;
130 void SBThread::Clear() {
131 LLDB_INSTRUMENT_VA(this);
133 m_opaque_sp->Clear();
136 StopReason SBThread::GetStopReason() {
137 LLDB_INSTRUMENT_VA(this);
139 StopReason reason = eStopReasonInvalid;
140 std::unique_lock<std::recursive_mutex> lock;
141 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
143 if (exe_ctx.HasThreadScope()) {
144 Process::StopLocker stop_locker;
145 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
146 return exe_ctx.GetThreadPtr()->GetStopReason();
150 return reason;
153 size_t SBThread::GetStopReasonDataCount() {
154 LLDB_INSTRUMENT_VA(this);
156 std::unique_lock<std::recursive_mutex> lock;
157 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
159 if (exe_ctx.HasThreadScope()) {
160 Process::StopLocker stop_locker;
161 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
162 StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
163 if (stop_info_sp) {
164 StopReason reason = stop_info_sp->GetStopReason();
165 switch (reason) {
166 case eStopReasonInvalid:
167 case eStopReasonNone:
168 case eStopReasonTrace:
169 case eStopReasonExec:
170 case eStopReasonPlanComplete:
171 case eStopReasonThreadExiting:
172 case eStopReasonInstrumentation:
173 case eStopReasonProcessorTrace:
174 case eStopReasonVForkDone:
175 // There is no data for these stop reasons.
176 return 0;
178 case eStopReasonBreakpoint: {
179 break_id_t site_id = stop_info_sp->GetValue();
180 lldb::BreakpointSiteSP bp_site_sp(
181 exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
182 site_id));
183 if (bp_site_sp)
184 return bp_site_sp->GetNumberOfConstituents() * 2;
185 else
186 return 0; // Breakpoint must have cleared itself...
187 } break;
189 case eStopReasonWatchpoint:
190 return 1;
192 case eStopReasonSignal:
193 return 1;
195 case eStopReasonInterrupt:
196 return 1;
198 case eStopReasonException:
199 return 1;
201 case eStopReasonFork:
202 return 1;
204 case eStopReasonVFork:
205 return 1;
210 return 0;
213 uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
214 LLDB_INSTRUMENT_VA(this, idx);
216 std::unique_lock<std::recursive_mutex> lock;
217 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
219 if (exe_ctx.HasThreadScope()) {
220 Process::StopLocker stop_locker;
221 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
222 Thread *thread = exe_ctx.GetThreadPtr();
223 StopInfoSP stop_info_sp = thread->GetStopInfo();
224 if (stop_info_sp) {
225 StopReason reason = stop_info_sp->GetStopReason();
226 switch (reason) {
227 case eStopReasonInvalid:
228 case eStopReasonNone:
229 case eStopReasonTrace:
230 case eStopReasonExec:
231 case eStopReasonPlanComplete:
232 case eStopReasonThreadExiting:
233 case eStopReasonInstrumentation:
234 case eStopReasonProcessorTrace:
235 case eStopReasonVForkDone:
236 // There is no data for these stop reasons.
237 return 0;
239 case eStopReasonBreakpoint: {
240 break_id_t site_id = stop_info_sp->GetValue();
241 lldb::BreakpointSiteSP bp_site_sp(
242 exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
243 site_id));
244 if (bp_site_sp) {
245 uint32_t bp_index = idx / 2;
246 BreakpointLocationSP bp_loc_sp(
247 bp_site_sp->GetConstituentAtIndex(bp_index));
248 if (bp_loc_sp) {
249 if (idx & 1) {
250 // Odd idx, return the breakpoint location ID
251 return bp_loc_sp->GetID();
252 } else {
253 // Even idx, return the breakpoint ID
254 return bp_loc_sp->GetBreakpoint().GetID();
258 return LLDB_INVALID_BREAK_ID;
259 } break;
261 case eStopReasonWatchpoint:
262 return stop_info_sp->GetValue();
264 case eStopReasonSignal:
265 return stop_info_sp->GetValue();
267 case eStopReasonInterrupt:
268 return stop_info_sp->GetValue();
270 case eStopReasonException:
271 return stop_info_sp->GetValue();
273 case eStopReasonFork:
274 return stop_info_sp->GetValue();
276 case eStopReasonVFork:
277 return stop_info_sp->GetValue();
282 return 0;
285 bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) {
286 LLDB_INSTRUMENT_VA(this, stream);
288 Stream &strm = stream.ref();
290 std::unique_lock<std::recursive_mutex> lock;
291 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
293 if (!exe_ctx.HasThreadScope())
294 return false;
296 StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
297 StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
298 if (!info)
299 return false;
301 info->Dump(strm);
303 return true;
306 SBThreadCollection
307 SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
308 LLDB_INSTRUMENT_VA(this, type);
310 SBThreadCollection threads;
312 std::unique_lock<std::recursive_mutex> lock;
313 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
315 if (!exe_ctx.HasThreadScope())
316 return SBThreadCollection();
318 ProcessSP process_sp = exe_ctx.GetProcessSP();
320 StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
321 StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
322 if (!info)
323 return threads;
325 threads = process_sp->GetInstrumentationRuntime(type)
326 ->GetBacktracesFromExtendedStopInfo(info);
327 return threads;
330 size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
331 LLDB_INSTRUMENT_VA(this, dst, dst_len);
333 std::unique_lock<std::recursive_mutex> lock;
334 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
336 if (dst)
337 *dst = 0;
339 if (!exe_ctx.HasThreadScope())
340 return 0;
342 Process::StopLocker stop_locker;
343 if (!stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
344 return 0;
346 std::string thread_stop_desc = exe_ctx.GetThreadPtr()->GetStopDescription();
347 if (thread_stop_desc.empty())
348 return 0;
350 if (dst)
351 return ::snprintf(dst, dst_len, "%s", thread_stop_desc.c_str()) + 1;
353 // NULL dst passed in, return the length needed to contain the
354 // description.
355 return thread_stop_desc.size() + 1; // Include the NULL byte for size
358 SBValue SBThread::GetStopReturnValue() {
359 LLDB_INSTRUMENT_VA(this);
361 ValueObjectSP return_valobj_sp;
362 std::unique_lock<std::recursive_mutex> lock;
363 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
365 if (exe_ctx.HasThreadScope()) {
366 Process::StopLocker stop_locker;
367 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
368 StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
369 if (stop_info_sp) {
370 return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp);
375 return SBValue(return_valobj_sp);
378 void SBThread::SetThread(const ThreadSP &lldb_object_sp) {
379 m_opaque_sp->SetThreadSP(lldb_object_sp);
382 lldb::tid_t SBThread::GetThreadID() const {
383 LLDB_INSTRUMENT_VA(this);
385 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
386 if (thread_sp)
387 return thread_sp->GetID();
388 return LLDB_INVALID_THREAD_ID;
391 uint32_t SBThread::GetIndexID() const {
392 LLDB_INSTRUMENT_VA(this);
394 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
395 if (thread_sp)
396 return thread_sp->GetIndexID();
397 return LLDB_INVALID_INDEX32;
400 const char *SBThread::GetName() const {
401 LLDB_INSTRUMENT_VA(this);
403 std::unique_lock<std::recursive_mutex> lock;
404 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
406 if (!exe_ctx.HasThreadScope())
407 return nullptr;
409 Process::StopLocker stop_locker;
410 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
411 return ConstString(exe_ctx.GetThreadPtr()->GetName()).GetCString();
413 return nullptr;
416 const char *SBThread::GetQueueName() const {
417 LLDB_INSTRUMENT_VA(this);
419 std::unique_lock<std::recursive_mutex> lock;
420 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
422 if (!exe_ctx.HasThreadScope())
423 return nullptr;
425 Process::StopLocker stop_locker;
426 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
427 return ConstString(exe_ctx.GetThreadPtr()->GetQueueName()).GetCString();
429 return nullptr;
432 lldb::queue_id_t SBThread::GetQueueID() const {
433 LLDB_INSTRUMENT_VA(this);
435 queue_id_t id = LLDB_INVALID_QUEUE_ID;
436 std::unique_lock<std::recursive_mutex> lock;
437 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
439 if (exe_ctx.HasThreadScope()) {
440 Process::StopLocker stop_locker;
441 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
442 id = exe_ctx.GetThreadPtr()->GetQueueID();
446 return id;
449 bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
450 LLDB_INSTRUMENT_VA(this, path, strm);
452 bool success = false;
453 std::unique_lock<std::recursive_mutex> lock;
454 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
456 if (exe_ctx.HasThreadScope()) {
457 Process::StopLocker stop_locker;
458 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
459 Thread *thread = exe_ctx.GetThreadPtr();
460 StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
461 if (info_root_sp) {
462 StructuredData::ObjectSP node =
463 info_root_sp->GetObjectForDotSeparatedPath(path);
464 if (node) {
465 if (node->GetType() == eStructuredDataTypeString) {
466 strm.ref() << node->GetAsString()->GetValue();
467 success = true;
469 if (node->GetType() == eStructuredDataTypeInteger) {
470 strm.Printf("0x%" PRIx64, node->GetUnsignedIntegerValue());
471 success = true;
473 if (node->GetType() == eStructuredDataTypeFloat) {
474 strm.Printf("0x%f", node->GetAsFloat()->GetValue());
475 success = true;
477 if (node->GetType() == eStructuredDataTypeBoolean) {
478 if (node->GetAsBoolean()->GetValue())
479 strm.Printf("true");
480 else
481 strm.Printf("false");
482 success = true;
484 if (node->GetType() == eStructuredDataTypeNull) {
485 strm.Printf("null");
486 success = true;
493 return success;
496 SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
497 ThreadPlan *new_plan) {
498 SBError sb_error;
500 Process *process = exe_ctx.GetProcessPtr();
501 if (!process) {
502 sb_error = Status::FromErrorString("No process in SBThread::ResumeNewPlan");
503 return sb_error;
506 Thread *thread = exe_ctx.GetThreadPtr();
507 if (!thread) {
508 sb_error = Status::FromErrorString("No thread in SBThread::ResumeNewPlan");
509 return sb_error;
512 // User level plans should be Controlling Plans so they can be interrupted,
513 // other plans executed, and then a "continue" will resume the plan.
514 if (new_plan != nullptr) {
515 new_plan->SetIsControllingPlan(true);
516 new_plan->SetOkayToDiscard(false);
519 // Why do we need to set the current thread by ID here???
520 process->GetThreadList().SetSelectedThreadByID(thread->GetID());
522 if (process->GetTarget().GetDebugger().GetAsyncExecution())
523 sb_error.ref() = process->Resume();
524 else
525 sb_error.ref() = process->ResumeSynchronous(nullptr);
527 return sb_error;
530 void SBThread::StepOver(lldb::RunMode stop_other_threads) {
531 LLDB_INSTRUMENT_VA(this, stop_other_threads);
533 SBError error; // Ignored
534 StepOver(stop_other_threads, error);
537 void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
538 LLDB_INSTRUMENT_VA(this, stop_other_threads, error);
540 std::unique_lock<std::recursive_mutex> lock;
541 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
543 if (!exe_ctx.HasThreadScope()) {
544 error = Status::FromErrorString("this SBThread object is invalid");
545 return;
548 Thread *thread = exe_ctx.GetThreadPtr();
549 bool abort_other_plans = false;
550 StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
552 Status new_plan_status;
553 ThreadPlanSP new_plan_sp;
554 if (frame_sp) {
555 if (frame_sp->HasDebugInformation()) {
556 const LazyBool avoid_no_debug = eLazyBoolCalculate;
557 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
558 new_plan_sp = thread->QueueThreadPlanForStepOverRange(
559 abort_other_plans, sc.line_entry, sc, stop_other_threads,
560 new_plan_status, avoid_no_debug);
561 } else {
562 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
563 true, abort_other_plans, stop_other_threads, new_plan_status);
566 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
569 void SBThread::StepInto(lldb::RunMode stop_other_threads) {
570 LLDB_INSTRUMENT_VA(this, stop_other_threads);
572 StepInto(nullptr, stop_other_threads);
575 void SBThread::StepInto(const char *target_name,
576 lldb::RunMode stop_other_threads) {
577 LLDB_INSTRUMENT_VA(this, target_name, stop_other_threads);
579 SBError error; // Ignored
580 StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
583 void SBThread::StepInto(const char *target_name, uint32_t end_line,
584 SBError &error, lldb::RunMode stop_other_threads) {
585 LLDB_INSTRUMENT_VA(this, target_name, end_line, error, stop_other_threads);
587 std::unique_lock<std::recursive_mutex> lock;
588 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
590 if (!exe_ctx.HasThreadScope()) {
591 error = Status::FromErrorString("this SBThread object is invalid");
592 return;
595 bool abort_other_plans = false;
597 Thread *thread = exe_ctx.GetThreadPtr();
598 StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
599 ThreadPlanSP new_plan_sp;
600 Status new_plan_status;
602 if (frame_sp && frame_sp->HasDebugInformation()) {
603 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
604 AddressRange range;
605 if (end_line == LLDB_INVALID_LINE_NUMBER)
606 range = sc.line_entry.range;
607 else {
608 llvm::Error err = sc.GetAddressRangeFromHereToEndLine(end_line, range);
609 if (err) {
610 error = Status::FromErrorString(llvm::toString(std::move(err)).c_str());
611 return;
615 const LazyBool step_out_avoids_code_without_debug_info =
616 eLazyBoolCalculate;
617 const LazyBool step_in_avoids_code_without_debug_info =
618 eLazyBoolCalculate;
619 new_plan_sp = thread->QueueThreadPlanForStepInRange(
620 abort_other_plans, range, sc, target_name, stop_other_threads,
621 new_plan_status, step_in_avoids_code_without_debug_info,
622 step_out_avoids_code_without_debug_info);
623 } else {
624 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
625 false, abort_other_plans, stop_other_threads, new_plan_status);
628 if (new_plan_status.Success())
629 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
630 else
631 error = Status::FromErrorString(new_plan_status.AsCString());
634 void SBThread::StepOut() {
635 LLDB_INSTRUMENT_VA(this);
637 SBError error; // Ignored
638 StepOut(error);
641 void SBThread::StepOut(SBError &error) {
642 LLDB_INSTRUMENT_VA(this, error);
644 std::unique_lock<std::recursive_mutex> lock;
645 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
647 if (!exe_ctx.HasThreadScope()) {
648 error = Status::FromErrorString("this SBThread object is invalid");
649 return;
652 bool abort_other_plans = false;
653 bool stop_other_threads = false;
655 Thread *thread = exe_ctx.GetThreadPtr();
657 const LazyBool avoid_no_debug = eLazyBoolCalculate;
658 Status new_plan_status;
659 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
660 abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
661 eVoteNoOpinion, 0, new_plan_status, avoid_no_debug));
663 if (new_plan_status.Success())
664 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
665 else
666 error = Status::FromErrorString(new_plan_status.AsCString());
669 void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
670 LLDB_INSTRUMENT_VA(this, sb_frame);
672 SBError error; // Ignored
673 StepOutOfFrame(sb_frame, error);
676 void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
677 LLDB_INSTRUMENT_VA(this, sb_frame, error);
679 std::unique_lock<std::recursive_mutex> lock;
680 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
682 if (!sb_frame.IsValid()) {
683 error = Status::FromErrorString("passed invalid SBFrame object");
684 return;
687 StackFrameSP frame_sp(sb_frame.GetFrameSP());
689 if (!exe_ctx.HasThreadScope()) {
690 error = Status::FromErrorString("this SBThread object is invalid");
691 return;
694 bool abort_other_plans = false;
695 bool stop_other_threads = false;
696 Thread *thread = exe_ctx.GetThreadPtr();
697 if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
698 error = Status::FromErrorString("passed a frame from another thread");
699 return;
702 Status new_plan_status;
703 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
704 abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
705 eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status));
707 if (new_plan_status.Success())
708 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
709 else
710 error = Status::FromErrorString(new_plan_status.AsCString());
713 void SBThread::StepInstruction(bool step_over) {
714 LLDB_INSTRUMENT_VA(this, step_over);
716 SBError error; // Ignored
717 StepInstruction(step_over, error);
720 void SBThread::StepInstruction(bool step_over, SBError &error) {
721 LLDB_INSTRUMENT_VA(this, step_over, error);
723 std::unique_lock<std::recursive_mutex> lock;
724 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
726 if (!exe_ctx.HasThreadScope()) {
727 error = Status::FromErrorString("this SBThread object is invalid");
728 return;
731 Thread *thread = exe_ctx.GetThreadPtr();
732 Status new_plan_status;
733 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction(
734 step_over, false, true, new_plan_status));
736 if (new_plan_status.Success())
737 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
738 else
739 error = Status::FromErrorString(new_plan_status.AsCString());
742 void SBThread::RunToAddress(lldb::addr_t addr) {
743 LLDB_INSTRUMENT_VA(this, addr);
745 SBError error; // Ignored
746 RunToAddress(addr, error);
749 void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
750 LLDB_INSTRUMENT_VA(this, addr, error);
752 std::unique_lock<std::recursive_mutex> lock;
753 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
755 if (!exe_ctx.HasThreadScope()) {
756 error = Status::FromErrorString("this SBThread object is invalid");
757 return;
760 bool abort_other_plans = false;
761 bool stop_other_threads = true;
763 Address target_addr(addr);
765 Thread *thread = exe_ctx.GetThreadPtr();
767 Status new_plan_status;
768 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
769 abort_other_plans, target_addr, stop_other_threads, new_plan_status));
771 if (new_plan_status.Success())
772 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
773 else
774 error = Status::FromErrorString(new_plan_status.AsCString());
777 SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
778 lldb::SBFileSpec &sb_file_spec, uint32_t line) {
779 LLDB_INSTRUMENT_VA(this, sb_frame, sb_file_spec, line);
781 SBError sb_error;
782 char path[PATH_MAX];
784 std::unique_lock<std::recursive_mutex> lock;
785 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
787 StackFrameSP frame_sp(sb_frame.GetFrameSP());
789 if (exe_ctx.HasThreadScope()) {
790 Target *target = exe_ctx.GetTargetPtr();
791 Thread *thread = exe_ctx.GetThreadPtr();
793 if (line == 0) {
794 sb_error = Status::FromErrorString("invalid line argument");
795 return sb_error;
798 if (!frame_sp) {
799 // We don't want to run SelectMostRelevantFrame here, for instance if
800 // you called a sequence of StepOverUntil's you wouldn't want the
801 // frame changed out from under you because you stepped into a
802 // recognized frame.
803 frame_sp = thread->GetSelectedFrame(DoNoSelectMostRelevantFrame);
804 if (!frame_sp)
805 frame_sp = thread->GetStackFrameAtIndex(0);
808 SymbolContext frame_sc;
809 if (!frame_sp) {
810 sb_error = Status::FromErrorString("no valid frames in thread to step");
811 return sb_error;
814 // If we have a frame, get its line
815 frame_sc = frame_sp->GetSymbolContext(
816 eSymbolContextCompUnit | eSymbolContextFunction |
817 eSymbolContextLineEntry | eSymbolContextSymbol);
819 if (frame_sc.comp_unit == nullptr) {
820 sb_error = Status::FromErrorStringWithFormat(
821 "frame %u doesn't have debug information", frame_sp->GetFrameIndex());
822 return sb_error;
825 FileSpec step_file_spec;
826 if (sb_file_spec.IsValid()) {
827 // The file spec passed in was valid, so use it
828 step_file_spec = sb_file_spec.ref();
829 } else {
830 if (frame_sc.line_entry.IsValid())
831 step_file_spec = frame_sc.line_entry.GetFile();
832 else {
833 sb_error = Status::FromErrorString(
834 "invalid file argument or no file for frame");
835 return sb_error;
839 // Grab the current function, then we will make sure the "until" address is
840 // within the function. We discard addresses that are out of the current
841 // function, and then if there are no addresses remaining, give an
842 // appropriate error message.
844 bool all_in_function = true;
845 AddressRange fun_range = frame_sc.function->GetAddressRange();
847 std::vector<addr_t> step_over_until_addrs;
848 const bool abort_other_plans = false;
849 const bool stop_other_threads = false;
850 // TODO: Handle SourceLocationSpec column information
851 SourceLocationSpec location_spec(
852 step_file_spec, line, /*column=*/std::nullopt, /*check_inlines=*/true,
853 /*exact_match=*/false);
855 SymbolContextList sc_list;
856 frame_sc.comp_unit->ResolveSymbolContext(location_spec,
857 eSymbolContextLineEntry, sc_list);
858 for (const SymbolContext &sc : sc_list) {
859 addr_t step_addr =
860 sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
861 if (step_addr != LLDB_INVALID_ADDRESS) {
862 if (fun_range.ContainsLoadAddress(step_addr, target))
863 step_over_until_addrs.push_back(step_addr);
864 else
865 all_in_function = false;
869 if (step_over_until_addrs.empty()) {
870 if (all_in_function) {
871 step_file_spec.GetPath(path, sizeof(path));
872 sb_error = Status::FromErrorStringWithFormat(
873 "No line entries for %s:%u", path, line);
874 } else
875 sb_error = Status::FromErrorString(
876 "step until target not in current function");
877 } else {
878 Status new_plan_status;
879 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil(
880 abort_other_plans, &step_over_until_addrs[0],
881 step_over_until_addrs.size(), stop_other_threads,
882 frame_sp->GetFrameIndex(), new_plan_status));
884 if (new_plan_status.Success())
885 sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
886 else
887 sb_error = Status::FromErrorString(new_plan_status.AsCString());
889 } else {
890 sb_error = Status::FromErrorString("this SBThread object is invalid");
892 return sb_error;
895 SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) {
896 LLDB_INSTRUMENT_VA(this, script_class_name);
898 return StepUsingScriptedThreadPlan(script_class_name, true);
901 SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
902 bool resume_immediately) {
903 LLDB_INSTRUMENT_VA(this, script_class_name, resume_immediately);
905 lldb::SBStructuredData no_data;
906 return StepUsingScriptedThreadPlan(script_class_name, no_data,
907 resume_immediately);
910 SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
911 SBStructuredData &args_data,
912 bool resume_immediately) {
913 LLDB_INSTRUMENT_VA(this, script_class_name, args_data, resume_immediately);
915 SBError error;
917 std::unique_lock<std::recursive_mutex> lock;
918 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
920 if (!exe_ctx.HasThreadScope()) {
921 error = Status::FromErrorString("this SBThread object is invalid");
922 return error;
925 Thread *thread = exe_ctx.GetThreadPtr();
926 Status new_plan_status;
927 StructuredData::ObjectSP obj_sp = args_data.m_impl_up->GetObjectSP();
929 ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted(
930 false, script_class_name, obj_sp, false, new_plan_status);
932 if (new_plan_status.Fail()) {
933 error = Status::FromErrorString(new_plan_status.AsCString());
934 return error;
937 if (!resume_immediately)
938 return error;
940 if (new_plan_status.Success())
941 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
942 else
943 error = Status::FromErrorString(new_plan_status.AsCString());
945 return error;
948 SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
949 LLDB_INSTRUMENT_VA(this, file_spec, line);
951 SBError sb_error;
953 std::unique_lock<std::recursive_mutex> lock;
954 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
956 if (!exe_ctx.HasThreadScope()) {
957 sb_error = Status::FromErrorString("this SBThread object is invalid");
958 return sb_error;
961 Thread *thread = exe_ctx.GetThreadPtr();
963 Status err = thread->JumpToLine(file_spec.ref(), line, true);
964 sb_error.SetError(std::move(err));
965 return sb_error;
968 SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
969 LLDB_INSTRUMENT_VA(this, frame, return_value);
971 SBError sb_error;
973 std::unique_lock<std::recursive_mutex> lock;
974 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
976 if (exe_ctx.HasThreadScope()) {
977 Thread *thread = exe_ctx.GetThreadPtr();
978 sb_error.SetError(
979 thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
982 return sb_error;
985 SBError SBThread::UnwindInnermostExpression() {
986 LLDB_INSTRUMENT_VA(this);
988 SBError sb_error;
990 std::unique_lock<std::recursive_mutex> lock;
991 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
993 if (exe_ctx.HasThreadScope()) {
994 Thread *thread = exe_ctx.GetThreadPtr();
995 sb_error.SetError(thread->UnwindInnermostExpression());
996 if (sb_error.Success())
997 thread->SetSelectedFrameByIndex(0, false);
1000 return sb_error;
1003 bool SBThread::Suspend() {
1004 LLDB_INSTRUMENT_VA(this);
1006 SBError error; // Ignored
1007 return Suspend(error);
1010 bool SBThread::Suspend(SBError &error) {
1011 LLDB_INSTRUMENT_VA(this, error);
1013 std::unique_lock<std::recursive_mutex> lock;
1014 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1016 bool result = false;
1017 if (exe_ctx.HasThreadScope()) {
1018 Process::StopLocker stop_locker;
1019 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1020 exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
1021 result = true;
1022 } else {
1023 error = Status::FromErrorString("process is running");
1025 } else
1026 error = Status::FromErrorString("this SBThread object is invalid");
1027 return result;
1030 bool SBThread::Resume() {
1031 LLDB_INSTRUMENT_VA(this);
1033 SBError error; // Ignored
1034 return Resume(error);
1037 bool SBThread::Resume(SBError &error) {
1038 LLDB_INSTRUMENT_VA(this, error);
1040 std::unique_lock<std::recursive_mutex> lock;
1041 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1043 bool result = false;
1044 if (exe_ctx.HasThreadScope()) {
1045 Process::StopLocker stop_locker;
1046 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1047 const bool override_suspend = true;
1048 exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
1049 result = true;
1050 } else {
1051 error = Status::FromErrorString("process is running");
1053 } else
1054 error = Status::FromErrorString("this SBThread object is invalid");
1055 return result;
1058 bool SBThread::IsSuspended() {
1059 LLDB_INSTRUMENT_VA(this);
1061 std::unique_lock<std::recursive_mutex> lock;
1062 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1064 if (exe_ctx.HasThreadScope())
1065 return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
1066 return false;
1069 bool SBThread::IsStopped() {
1070 LLDB_INSTRUMENT_VA(this);
1072 std::unique_lock<std::recursive_mutex> lock;
1073 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1075 if (exe_ctx.HasThreadScope())
1076 return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1077 return false;
1080 SBProcess SBThread::GetProcess() {
1081 LLDB_INSTRUMENT_VA(this);
1083 SBProcess sb_process;
1084 std::unique_lock<std::recursive_mutex> lock;
1085 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1087 if (exe_ctx.HasThreadScope()) {
1088 // Have to go up to the target so we can get a shared pointer to our
1089 // process...
1090 sb_process.SetSP(exe_ctx.GetProcessSP());
1093 return sb_process;
1096 uint32_t SBThread::GetNumFrames() {
1097 LLDB_INSTRUMENT_VA(this);
1099 uint32_t num_frames = 0;
1100 std::unique_lock<std::recursive_mutex> lock;
1101 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1103 if (exe_ctx.HasThreadScope()) {
1104 Process::StopLocker stop_locker;
1105 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1106 num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1110 return num_frames;
1113 SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
1114 LLDB_INSTRUMENT_VA(this, idx);
1116 SBFrame sb_frame;
1117 StackFrameSP frame_sp;
1118 std::unique_lock<std::recursive_mutex> lock;
1119 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1121 if (exe_ctx.HasThreadScope()) {
1122 Process::StopLocker stop_locker;
1123 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1124 frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
1125 sb_frame.SetFrameSP(frame_sp);
1129 return sb_frame;
1132 lldb::SBFrame SBThread::GetSelectedFrame() {
1133 LLDB_INSTRUMENT_VA(this);
1135 SBFrame sb_frame;
1136 StackFrameSP frame_sp;
1137 std::unique_lock<std::recursive_mutex> lock;
1138 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1140 if (exe_ctx.HasThreadScope()) {
1141 Process::StopLocker stop_locker;
1142 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1143 frame_sp =
1144 exe_ctx.GetThreadPtr()->GetSelectedFrame(SelectMostRelevantFrame);
1145 sb_frame.SetFrameSP(frame_sp);
1149 return sb_frame;
1152 lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
1153 LLDB_INSTRUMENT_VA(this, idx);
1155 SBFrame sb_frame;
1156 StackFrameSP frame_sp;
1157 std::unique_lock<std::recursive_mutex> lock;
1158 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1160 if (exe_ctx.HasThreadScope()) {
1161 Process::StopLocker stop_locker;
1162 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1163 Thread *thread = exe_ctx.GetThreadPtr();
1164 frame_sp = thread->GetStackFrameAtIndex(idx);
1165 if (frame_sp) {
1166 thread->SetSelectedFrame(frame_sp.get());
1167 sb_frame.SetFrameSP(frame_sp);
1172 return sb_frame;
1175 bool SBThread::EventIsThreadEvent(const SBEvent &event) {
1176 LLDB_INSTRUMENT_VA(event);
1178 return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != nullptr;
1181 SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) {
1182 LLDB_INSTRUMENT_VA(event);
1184 return Thread::ThreadEventData::GetStackFrameFromEvent(event.get());
1187 SBThread SBThread::GetThreadFromEvent(const SBEvent &event) {
1188 LLDB_INSTRUMENT_VA(event);
1190 return Thread::ThreadEventData::GetThreadFromEvent(event.get());
1193 bool SBThread::operator==(const SBThread &rhs) const {
1194 LLDB_INSTRUMENT_VA(this, rhs);
1196 return m_opaque_sp->GetThreadSP().get() ==
1197 rhs.m_opaque_sp->GetThreadSP().get();
1200 bool SBThread::operator!=(const SBThread &rhs) const {
1201 LLDB_INSTRUMENT_VA(this, rhs);
1203 return m_opaque_sp->GetThreadSP().get() !=
1204 rhs.m_opaque_sp->GetThreadSP().get();
1207 bool SBThread::GetStatus(SBStream &status) const {
1208 LLDB_INSTRUMENT_VA(this, status);
1210 Stream &strm = status.ref();
1212 std::unique_lock<std::recursive_mutex> lock;
1213 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1215 if (exe_ctx.HasThreadScope()) {
1216 exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true,
1217 /*show_hidden=*/true);
1218 } else
1219 strm.PutCString("No status");
1221 return true;
1224 bool SBThread::GetDescription(SBStream &description) const {
1225 LLDB_INSTRUMENT_VA(this, description);
1227 return GetDescription(description, false);
1230 bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
1231 LLDB_INSTRUMENT_VA(this, description, stop_format);
1233 Stream &strm = description.ref();
1235 std::unique_lock<std::recursive_mutex> lock;
1236 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1238 if (exe_ctx.HasThreadScope()) {
1239 exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(
1240 strm, LLDB_INVALID_THREAD_ID, stop_format);
1241 } else
1242 strm.PutCString("No value");
1244 return true;
1247 SBError SBThread::GetDescriptionWithFormat(const SBFormat &format,
1248 SBStream &output) {
1249 Stream &strm = output.ref();
1251 SBError error;
1252 if (!format) {
1253 error = Status::FromErrorString("The provided SBFormat object is invalid");
1254 return error;
1257 std::unique_lock<std::recursive_mutex> lock;
1258 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1260 if (exe_ctx.HasThreadScope()) {
1261 if (exe_ctx.GetThreadPtr()->DumpUsingFormat(
1262 strm, LLDB_INVALID_THREAD_ID, format.GetFormatEntrySP().get())) {
1263 return error;
1267 error = Status::FromErrorStringWithFormat(
1268 "It was not possible to generate a thread description with the given "
1269 "format string '%s'",
1270 format.GetFormatEntrySP()->string.c_str());
1271 return error;
1274 SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
1275 LLDB_INSTRUMENT_VA(this, type);
1277 std::unique_lock<std::recursive_mutex> lock;
1278 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1279 SBThread sb_origin_thread;
1281 Process::StopLocker stop_locker;
1282 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1283 if (exe_ctx.HasThreadScope()) {
1284 ThreadSP real_thread(exe_ctx.GetThreadSP());
1285 if (real_thread) {
1286 ConstString type_const(type);
1287 Process *process = exe_ctx.GetProcessPtr();
1288 if (process) {
1289 SystemRuntime *runtime = process->GetSystemRuntime();
1290 if (runtime) {
1291 ThreadSP new_thread_sp(
1292 runtime->GetExtendedBacktraceThread(real_thread, type_const));
1293 if (new_thread_sp) {
1294 // Save this in the Process' ExtendedThreadList so a strong
1295 // pointer retains the object.
1296 process->GetExtendedThreadList().AddThread(new_thread_sp);
1297 sb_origin_thread.SetThread(new_thread_sp);
1305 return sb_origin_thread;
1308 uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
1309 LLDB_INSTRUMENT_VA(this);
1311 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1312 if (thread_sp)
1313 return thread_sp->GetExtendedBacktraceOriginatingIndexID();
1314 return LLDB_INVALID_INDEX32;
1317 SBValue SBThread::GetCurrentException() {
1318 LLDB_INSTRUMENT_VA(this);
1320 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1321 if (!thread_sp)
1322 return SBValue();
1324 return SBValue(thread_sp->GetCurrentException());
1327 SBThread SBThread::GetCurrentExceptionBacktrace() {
1328 LLDB_INSTRUMENT_VA(this);
1330 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1331 if (!thread_sp)
1332 return SBThread();
1334 return SBThread(thread_sp->GetCurrentExceptionBacktrace());
1337 bool SBThread::SafeToCallFunctions() {
1338 LLDB_INSTRUMENT_VA(this);
1340 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1341 if (thread_sp)
1342 return thread_sp->SafeToCallFunctions();
1343 return true;
1346 lldb::ThreadSP SBThread::GetSP() const { return m_opaque_sp->GetThreadSP(); }
1348 lldb_private::Thread *SBThread::operator->() {
1349 return get();
1352 lldb_private::Thread *SBThread::get() {
1353 return m_opaque_sp->GetThreadSP().get();
1356 SBValue SBThread::GetSiginfo() {
1357 LLDB_INSTRUMENT_VA(this);
1359 ThreadSP thread_sp = m_opaque_sp->GetThreadSP();
1360 if (!thread_sp)
1361 return SBValue();
1362 return thread_sp->GetSiginfoValue();