1 //===-- SBThread.cpp ------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "lldb/API/SBThread.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"
51 using namespace lldb_private
;
53 const char *SBThread::GetBroadcasterClassName() {
56 return ConstString(Thread::GetStaticBroadcasterClass()).AsCString();
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
);
81 m_opaque_sp
= clone(rhs
.m_opaque_sp
);
86 SBThread::~SBThread() = default;
88 lldb::SBQueue
SBThread::GetQueue() const {
89 LLDB_INSTRUMENT_VA(this);
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();
101 sb_queue
.SetQueue(queue_sp
);
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.
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();
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();
164 StopReason reason
= stop_info_sp
->GetStopReason();
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.
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(
184 return bp_site_sp
->GetNumberOfConstituents() * 2;
186 return 0; // Breakpoint must have cleared itself...
189 case eStopReasonWatchpoint
:
192 case eStopReasonSignal
:
195 case eStopReasonInterrupt
:
198 case eStopReasonException
:
201 case eStopReasonFork
:
204 case eStopReasonVFork
:
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();
225 StopReason reason
= stop_info_sp
->GetStopReason();
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.
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(
245 uint32_t bp_index
= idx
/ 2;
246 BreakpointLocationSP
bp_loc_sp(
247 bp_site_sp
->GetConstituentAtIndex(bp_index
));
250 // Odd idx, return the breakpoint location ID
251 return bp_loc_sp
->GetID();
253 // Even idx, return the breakpoint ID
254 return bp_loc_sp
->GetBreakpoint().GetID();
258 return LLDB_INVALID_BREAK_ID
;
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();
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())
296 StopInfoSP stop_info
= exe_ctx
.GetThreadPtr()->GetStopInfo();
297 StructuredData::ObjectSP info
= stop_info
->GetExtendedInfo();
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();
325 threads
= process_sp
->GetInstrumentationRuntime(type
)
326 ->GetBacktracesFromExtendedStopInfo(info
);
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
);
339 if (!exe_ctx
.HasThreadScope())
342 Process::StopLocker stop_locker
;
343 if (!stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock()))
346 std::string thread_stop_desc
= exe_ctx
.GetThreadPtr()->GetStopDescription();
347 if (thread_stop_desc
.empty())
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
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();
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());
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());
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())
409 Process::StopLocker stop_locker
;
410 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock()))
411 return ConstString(exe_ctx
.GetThreadPtr()->GetName()).GetCString();
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())
425 Process::StopLocker stop_locker
;
426 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock()))
427 return ConstString(exe_ctx
.GetThreadPtr()->GetQueueName()).GetCString();
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();
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();
462 StructuredData::ObjectSP node
=
463 info_root_sp
->GetObjectForDotSeparatedPath(path
);
465 if (node
->GetType() == eStructuredDataTypeString
) {
466 strm
.ref() << node
->GetAsString()->GetValue();
469 if (node
->GetType() == eStructuredDataTypeInteger
) {
470 strm
.Printf("0x%" PRIx64
, node
->GetUnsignedIntegerValue());
473 if (node
->GetType() == eStructuredDataTypeFloat
) {
474 strm
.Printf("0x%f", node
->GetAsFloat()->GetValue());
477 if (node
->GetType() == eStructuredDataTypeBoolean
) {
478 if (node
->GetAsBoolean()->GetValue())
481 strm
.Printf("false");
484 if (node
->GetType() == eStructuredDataTypeNull
) {
496 SBError
SBThread::ResumeNewPlan(ExecutionContext
&exe_ctx
,
497 ThreadPlan
*new_plan
) {
500 Process
*process
= exe_ctx
.GetProcessPtr();
502 sb_error
= Status::FromErrorString("No process in SBThread::ResumeNewPlan");
506 Thread
*thread
= exe_ctx
.GetThreadPtr();
508 sb_error
= Status::FromErrorString("No thread in SBThread::ResumeNewPlan");
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();
525 sb_error
.ref() = process
->ResumeSynchronous(nullptr);
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");
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
;
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
);
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");
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
));
605 if (end_line
== LLDB_INVALID_LINE_NUMBER
)
606 range
= sc
.line_entry
.range
;
608 llvm::Error err
= sc
.GetAddressRangeFromHereToEndLine(end_line
, range
);
610 error
= Status::FromErrorString(llvm::toString(std::move(err
)).c_str());
615 const LazyBool step_out_avoids_code_without_debug_info
=
617 const LazyBool step_in_avoids_code_without_debug_info
=
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
);
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());
631 error
= Status::FromErrorString(new_plan_status
.AsCString());
634 void SBThread::StepOut() {
635 LLDB_INSTRUMENT_VA(this);
637 SBError error
; // Ignored
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");
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());
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");
687 StackFrameSP
frame_sp(sb_frame
.GetFrameSP());
689 if (!exe_ctx
.HasThreadScope()) {
690 error
= Status::FromErrorString("this SBThread object is invalid");
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");
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());
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");
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());
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");
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());
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
);
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();
794 sb_error
= Status::FromErrorString("invalid line argument");
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
803 frame_sp
= thread
->GetSelectedFrame(DoNoSelectMostRelevantFrame
);
805 frame_sp
= thread
->GetStackFrameAtIndex(0);
808 SymbolContext frame_sc
;
810 sb_error
= Status::FromErrorString("no valid frames in thread to step");
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());
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();
830 if (frame_sc
.line_entry
.IsValid())
831 step_file_spec
= frame_sc
.line_entry
.GetFile();
833 sb_error
= Status::FromErrorString(
834 "invalid file argument or no file for frame");
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
) {
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
);
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
);
875 sb_error
= Status::FromErrorString(
876 "step until target not in current function");
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());
887 sb_error
= Status::FromErrorString(new_plan_status
.AsCString());
890 sb_error
= Status::FromErrorString("this SBThread object is invalid");
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
,
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
);
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");
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());
937 if (!resume_immediately
)
940 if (new_plan_status
.Success())
941 error
= ResumeNewPlan(exe_ctx
, new_plan_sp
.get());
943 error
= Status::FromErrorString(new_plan_status
.AsCString());
948 SBError
SBThread::JumpToLine(lldb::SBFileSpec
&file_spec
, uint32_t line
) {
949 LLDB_INSTRUMENT_VA(this, file_spec
, line
);
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");
961 Thread
*thread
= exe_ctx
.GetThreadPtr();
963 Status err
= thread
->JumpToLine(file_spec
.ref(), line
, true);
964 sb_error
.SetError(std::move(err
));
968 SBError
SBThread::ReturnFromFrame(SBFrame
&frame
, SBValue
&return_value
) {
969 LLDB_INSTRUMENT_VA(this, frame
, return_value
);
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();
979 thread
->ReturnFromFrame(frame
.GetFrameSP(), return_value
.GetSP()));
985 SBError
SBThread::UnwindInnermostExpression() {
986 LLDB_INSTRUMENT_VA(this);
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);
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
);
1023 error
= Status::FromErrorString("process is running");
1026 error
= Status::FromErrorString("this SBThread object is invalid");
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
);
1051 error
= Status::FromErrorString("process is running");
1054 error
= Status::FromErrorString("this SBThread object is invalid");
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
;
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);
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
1090 sb_process
.SetSP(exe_ctx
.GetProcessSP());
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();
1113 SBFrame
SBThread::GetFrameAtIndex(uint32_t idx
) {
1114 LLDB_INSTRUMENT_VA(this, idx
);
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
);
1132 lldb::SBFrame
SBThread::GetSelectedFrame() {
1133 LLDB_INSTRUMENT_VA(this);
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())) {
1144 exe_ctx
.GetThreadPtr()->GetSelectedFrame(SelectMostRelevantFrame
);
1145 sb_frame
.SetFrameSP(frame_sp
);
1152 lldb::SBFrame
SBThread::SetSelectedFrame(uint32_t idx
) {
1153 LLDB_INSTRUMENT_VA(this, idx
);
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
);
1166 thread
->SetSelectedFrame(frame_sp
.get());
1167 sb_frame
.SetFrameSP(frame_sp
);
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);
1219 strm
.PutCString("No status");
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
);
1242 strm
.PutCString("No value");
1247 SBError
SBThread::GetDescriptionWithFormat(const SBFormat
&format
,
1249 Stream
&strm
= output
.ref();
1253 error
= Status::FromErrorString("The provided SBFormat object is invalid");
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())) {
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());
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());
1286 ConstString
type_const(type
);
1287 Process
*process
= exe_ctx
.GetProcessPtr();
1289 SystemRuntime
*runtime
= process
->GetSystemRuntime();
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());
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());
1324 return SBValue(thread_sp
->GetCurrentException());
1327 SBThread
SBThread::GetCurrentExceptionBacktrace() {
1328 LLDB_INSTRUMENT_VA(this);
1330 ThreadSP
thread_sp(m_opaque_sp
->GetThreadSP());
1334 return SBThread(thread_sp
->GetCurrentExceptionBacktrace());
1337 bool SBThread::SafeToCallFunctions() {
1338 LLDB_INSTRUMENT_VA(this);
1340 ThreadSP
thread_sp(m_opaque_sp
->GetThreadSP());
1342 return thread_sp
->SafeToCallFunctions();
1346 lldb::ThreadSP
SBThread::GetSP() const { return m_opaque_sp
->GetThreadSP(); }
1348 lldb_private::Thread
*SBThread::operator->() {
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();
1362 return thread_sp
->GetSiginfoValue();