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/SBFrame.h"
16 #include "lldb/API/SBProcess.h"
17 #include "lldb/API/SBStream.h"
18 #include "lldb/API/SBStructuredData.h"
19 #include "lldb/API/SBSymbolContext.h"
20 #include "lldb/API/SBThreadCollection.h"
21 #include "lldb/API/SBThreadPlan.h"
22 #include "lldb/API/SBValue.h"
23 #include "lldb/Breakpoint/BreakpointLocation.h"
24 #include "lldb/Core/Debugger.h"
25 #include "lldb/Core/StructuredDataImpl.h"
26 #include "lldb/Core/ValueObject.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/lldb-enumerations.h"
50 using namespace lldb_private
;
52 const char *SBThread::GetBroadcasterClassName() {
55 return Thread::GetStaticBroadcasterClass().AsCString();
59 SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {
60 LLDB_INSTRUMENT_VA(this);
63 SBThread::SBThread(const ThreadSP
&lldb_object_sp
)
64 : m_opaque_sp(new ExecutionContextRef(lldb_object_sp
)) {
65 LLDB_INSTRUMENT_VA(this, lldb_object_sp
);
68 SBThread::SBThread(const SBThread
&rhs
) {
69 LLDB_INSTRUMENT_VA(this, rhs
);
71 m_opaque_sp
= clone(rhs
.m_opaque_sp
);
74 // Assignment operator
76 const lldb::SBThread
&SBThread::operator=(const SBThread
&rhs
) {
77 LLDB_INSTRUMENT_VA(this, rhs
);
80 m_opaque_sp
= clone(rhs
.m_opaque_sp
);
85 SBThread::~SBThread() = default;
87 lldb::SBQueue
SBThread::GetQueue() const {
88 LLDB_INSTRUMENT_VA(this);
92 std::unique_lock
<std::recursive_mutex
> lock
;
93 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
95 if (exe_ctx
.HasThreadScope()) {
96 Process::StopLocker stop_locker
;
97 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
98 queue_sp
= exe_ctx
.GetThreadPtr()->GetQueue();
100 sb_queue
.SetQueue(queue_sp
);
108 bool SBThread::IsValid() const {
109 LLDB_INSTRUMENT_VA(this);
110 return this->operator bool();
112 SBThread::operator bool() const {
113 LLDB_INSTRUMENT_VA(this);
115 std::unique_lock
<std::recursive_mutex
> lock
;
116 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
118 Target
*target
= exe_ctx
.GetTargetPtr();
119 Process
*process
= exe_ctx
.GetProcessPtr();
120 if (target
&& process
) {
121 Process::StopLocker stop_locker
;
122 if (stop_locker
.TryLock(&process
->GetRunLock()))
123 return m_opaque_sp
->GetThreadSP().get() != nullptr;
125 // Without a valid target & process, this thread can't be valid.
129 void SBThread::Clear() {
130 LLDB_INSTRUMENT_VA(this);
132 m_opaque_sp
->Clear();
135 StopReason
SBThread::GetStopReason() {
136 LLDB_INSTRUMENT_VA(this);
138 StopReason reason
= eStopReasonInvalid
;
139 std::unique_lock
<std::recursive_mutex
> lock
;
140 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
142 if (exe_ctx
.HasThreadScope()) {
143 Process::StopLocker stop_locker
;
144 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
145 return exe_ctx
.GetThreadPtr()->GetStopReason();
152 size_t SBThread::GetStopReasonDataCount() {
153 LLDB_INSTRUMENT_VA(this);
155 std::unique_lock
<std::recursive_mutex
> lock
;
156 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
158 if (exe_ctx
.HasThreadScope()) {
159 Process::StopLocker stop_locker
;
160 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
161 StopInfoSP stop_info_sp
= exe_ctx
.GetThreadPtr()->GetStopInfo();
163 StopReason reason
= stop_info_sp
->GetStopReason();
165 case eStopReasonInvalid
:
166 case eStopReasonNone
:
167 case eStopReasonTrace
:
168 case eStopReasonExec
:
169 case eStopReasonPlanComplete
:
170 case eStopReasonThreadExiting
:
171 case eStopReasonInstrumentation
:
172 case eStopReasonProcessorTrace
:
173 case eStopReasonVForkDone
:
174 // There is no data for these stop reasons.
177 case eStopReasonBreakpoint
: {
178 break_id_t site_id
= stop_info_sp
->GetValue();
179 lldb::BreakpointSiteSP
bp_site_sp(
180 exe_ctx
.GetProcessPtr()->GetBreakpointSiteList().FindByID(
183 return bp_site_sp
->GetNumberOfOwners() * 2;
185 return 0; // Breakpoint must have cleared itself...
188 case eStopReasonWatchpoint
:
191 case eStopReasonSignal
:
194 case eStopReasonException
:
197 case eStopReasonFork
:
200 case eStopReasonVFork
:
209 uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx
) {
210 LLDB_INSTRUMENT_VA(this, idx
);
212 std::unique_lock
<std::recursive_mutex
> lock
;
213 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
215 if (exe_ctx
.HasThreadScope()) {
216 Process::StopLocker stop_locker
;
217 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
218 Thread
*thread
= exe_ctx
.GetThreadPtr();
219 StopInfoSP stop_info_sp
= thread
->GetStopInfo();
221 StopReason reason
= stop_info_sp
->GetStopReason();
223 case eStopReasonInvalid
:
224 case eStopReasonNone
:
225 case eStopReasonTrace
:
226 case eStopReasonExec
:
227 case eStopReasonPlanComplete
:
228 case eStopReasonThreadExiting
:
229 case eStopReasonInstrumentation
:
230 case eStopReasonProcessorTrace
:
231 case eStopReasonVForkDone
:
232 // There is no data for these stop reasons.
235 case eStopReasonBreakpoint
: {
236 break_id_t site_id
= stop_info_sp
->GetValue();
237 lldb::BreakpointSiteSP
bp_site_sp(
238 exe_ctx
.GetProcessPtr()->GetBreakpointSiteList().FindByID(
241 uint32_t bp_index
= idx
/ 2;
242 BreakpointLocationSP
bp_loc_sp(
243 bp_site_sp
->GetOwnerAtIndex(bp_index
));
246 // Odd idx, return the breakpoint location ID
247 return bp_loc_sp
->GetID();
249 // Even idx, return the breakpoint ID
250 return bp_loc_sp
->GetBreakpoint().GetID();
254 return LLDB_INVALID_BREAK_ID
;
257 case eStopReasonWatchpoint
:
258 return stop_info_sp
->GetValue();
260 case eStopReasonSignal
:
261 return stop_info_sp
->GetValue();
263 case eStopReasonException
:
264 return stop_info_sp
->GetValue();
266 case eStopReasonFork
:
267 return stop_info_sp
->GetValue();
269 case eStopReasonVFork
:
270 return stop_info_sp
->GetValue();
278 bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream
&stream
) {
279 LLDB_INSTRUMENT_VA(this, stream
);
281 Stream
&strm
= stream
.ref();
283 std::unique_lock
<std::recursive_mutex
> lock
;
284 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
286 if (!exe_ctx
.HasThreadScope())
289 StopInfoSP stop_info
= exe_ctx
.GetThreadPtr()->GetStopInfo();
290 StructuredData::ObjectSP info
= stop_info
->GetExtendedInfo();
300 SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type
) {
301 LLDB_INSTRUMENT_VA(this, type
);
303 SBThreadCollection threads
;
305 std::unique_lock
<std::recursive_mutex
> lock
;
306 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
308 if (!exe_ctx
.HasThreadScope())
309 return SBThreadCollection();
311 ProcessSP process_sp
= exe_ctx
.GetProcessSP();
313 StopInfoSP stop_info
= exe_ctx
.GetThreadPtr()->GetStopInfo();
314 StructuredData::ObjectSP info
= stop_info
->GetExtendedInfo();
318 threads
= process_sp
->GetInstrumentationRuntime(type
)
319 ->GetBacktracesFromExtendedStopInfo(info
);
323 size_t SBThread::GetStopDescription(char *dst
, size_t dst_len
) {
324 LLDB_INSTRUMENT_VA(this, dst
, dst_len
);
326 std::unique_lock
<std::recursive_mutex
> lock
;
327 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
332 if (!exe_ctx
.HasThreadScope())
335 Process::StopLocker stop_locker
;
336 if (!stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock()))
339 std::string thread_stop_desc
= exe_ctx
.GetThreadPtr()->GetStopDescription();
340 if (thread_stop_desc
.empty())
344 return ::snprintf(dst
, dst_len
, "%s", thread_stop_desc
.c_str()) + 1;
346 // NULL dst passed in, return the length needed to contain the
348 return thread_stop_desc
.size() + 1; // Include the NULL byte for size
351 SBValue
SBThread::GetStopReturnValue() {
352 LLDB_INSTRUMENT_VA(this);
354 ValueObjectSP return_valobj_sp
;
355 std::unique_lock
<std::recursive_mutex
> lock
;
356 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
358 if (exe_ctx
.HasThreadScope()) {
359 Process::StopLocker stop_locker
;
360 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
361 StopInfoSP stop_info_sp
= exe_ctx
.GetThreadPtr()->GetStopInfo();
363 return_valobj_sp
= StopInfo::GetReturnValueObject(stop_info_sp
);
368 return SBValue(return_valobj_sp
);
371 void SBThread::SetThread(const ThreadSP
&lldb_object_sp
) {
372 m_opaque_sp
->SetThreadSP(lldb_object_sp
);
375 lldb::tid_t
SBThread::GetThreadID() const {
376 LLDB_INSTRUMENT_VA(this);
378 ThreadSP
thread_sp(m_opaque_sp
->GetThreadSP());
380 return thread_sp
->GetID();
381 return LLDB_INVALID_THREAD_ID
;
384 uint32_t SBThread::GetIndexID() const {
385 LLDB_INSTRUMENT_VA(this);
387 ThreadSP
thread_sp(m_opaque_sp
->GetThreadSP());
389 return thread_sp
->GetIndexID();
390 return LLDB_INVALID_INDEX32
;
393 const char *SBThread::GetName() const {
394 LLDB_INSTRUMENT_VA(this);
396 std::unique_lock
<std::recursive_mutex
> lock
;
397 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
399 if (!exe_ctx
.HasThreadScope())
402 Process::StopLocker stop_locker
;
403 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock()))
404 return ConstString(exe_ctx
.GetThreadPtr()->GetName()).GetCString();
409 const char *SBThread::GetQueueName() const {
410 LLDB_INSTRUMENT_VA(this);
412 std::unique_lock
<std::recursive_mutex
> lock
;
413 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
415 if (!exe_ctx
.HasThreadScope())
418 Process::StopLocker stop_locker
;
419 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock()))
420 return ConstString(exe_ctx
.GetThreadPtr()->GetQueueName()).GetCString();
425 lldb::queue_id_t
SBThread::GetQueueID() const {
426 LLDB_INSTRUMENT_VA(this);
428 queue_id_t id
= LLDB_INVALID_QUEUE_ID
;
429 std::unique_lock
<std::recursive_mutex
> lock
;
430 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
432 if (exe_ctx
.HasThreadScope()) {
433 Process::StopLocker stop_locker
;
434 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
435 id
= exe_ctx
.GetThreadPtr()->GetQueueID();
442 bool SBThread::GetInfoItemByPathAsString(const char *path
, SBStream
&strm
) {
443 LLDB_INSTRUMENT_VA(this, path
, strm
);
445 bool success
= false;
446 std::unique_lock
<std::recursive_mutex
> lock
;
447 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
449 if (exe_ctx
.HasThreadScope()) {
450 Process::StopLocker stop_locker
;
451 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
452 Thread
*thread
= exe_ctx
.GetThreadPtr();
453 StructuredData::ObjectSP info_root_sp
= thread
->GetExtendedInfo();
455 StructuredData::ObjectSP node
=
456 info_root_sp
->GetObjectForDotSeparatedPath(path
);
458 if (node
->GetType() == eStructuredDataTypeString
) {
459 strm
.ref() << node
->GetAsString()->GetValue();
462 if (node
->GetType() == eStructuredDataTypeInteger
) {
463 strm
.Printf("0x%" PRIx64
, node
->GetUnsignedIntegerValue());
466 if (node
->GetType() == eStructuredDataTypeFloat
) {
467 strm
.Printf("0x%f", node
->GetAsFloat()->GetValue());
470 if (node
->GetType() == eStructuredDataTypeBoolean
) {
471 if (node
->GetAsBoolean()->GetValue())
474 strm
.Printf("false");
477 if (node
->GetType() == eStructuredDataTypeNull
) {
489 SBError
SBThread::ResumeNewPlan(ExecutionContext
&exe_ctx
,
490 ThreadPlan
*new_plan
) {
493 Process
*process
= exe_ctx
.GetProcessPtr();
495 sb_error
.SetErrorString("No process in SBThread::ResumeNewPlan");
499 Thread
*thread
= exe_ctx
.GetThreadPtr();
501 sb_error
.SetErrorString("No thread in SBThread::ResumeNewPlan");
505 // User level plans should be Controlling Plans so they can be interrupted,
506 // other plans executed, and then a "continue" will resume the plan.
507 if (new_plan
!= nullptr) {
508 new_plan
->SetIsControllingPlan(true);
509 new_plan
->SetOkayToDiscard(false);
512 // Why do we need to set the current thread by ID here???
513 process
->GetThreadList().SetSelectedThreadByID(thread
->GetID());
515 if (process
->GetTarget().GetDebugger().GetAsyncExecution())
516 sb_error
.ref() = process
->Resume();
518 sb_error
.ref() = process
->ResumeSynchronous(nullptr);
523 void SBThread::StepOver(lldb::RunMode stop_other_threads
) {
524 LLDB_INSTRUMENT_VA(this, stop_other_threads
);
526 SBError error
; // Ignored
527 StepOver(stop_other_threads
, error
);
530 void SBThread::StepOver(lldb::RunMode stop_other_threads
, SBError
&error
) {
531 LLDB_INSTRUMENT_VA(this, stop_other_threads
, error
);
533 std::unique_lock
<std::recursive_mutex
> lock
;
534 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
536 if (!exe_ctx
.HasThreadScope()) {
537 error
.SetErrorString("this SBThread object is invalid");
541 Thread
*thread
= exe_ctx
.GetThreadPtr();
542 bool abort_other_plans
= false;
543 StackFrameSP
frame_sp(thread
->GetStackFrameAtIndex(0));
545 Status new_plan_status
;
546 ThreadPlanSP new_plan_sp
;
548 if (frame_sp
->HasDebugInformation()) {
549 const LazyBool avoid_no_debug
= eLazyBoolCalculate
;
550 SymbolContext
sc(frame_sp
->GetSymbolContext(eSymbolContextEverything
));
551 new_plan_sp
= thread
->QueueThreadPlanForStepOverRange(
552 abort_other_plans
, sc
.line_entry
, sc
, stop_other_threads
,
553 new_plan_status
, avoid_no_debug
);
555 new_plan_sp
= thread
->QueueThreadPlanForStepSingleInstruction(
556 true, abort_other_plans
, stop_other_threads
, new_plan_status
);
559 error
= ResumeNewPlan(exe_ctx
, new_plan_sp
.get());
562 void SBThread::StepInto(lldb::RunMode stop_other_threads
) {
563 LLDB_INSTRUMENT_VA(this, stop_other_threads
);
565 StepInto(nullptr, stop_other_threads
);
568 void SBThread::StepInto(const char *target_name
,
569 lldb::RunMode stop_other_threads
) {
570 LLDB_INSTRUMENT_VA(this, target_name
, stop_other_threads
);
572 SBError error
; // Ignored
573 StepInto(target_name
, LLDB_INVALID_LINE_NUMBER
, error
, stop_other_threads
);
576 void SBThread::StepInto(const char *target_name
, uint32_t end_line
,
577 SBError
&error
, lldb::RunMode stop_other_threads
) {
578 LLDB_INSTRUMENT_VA(this, target_name
, end_line
, error
, stop_other_threads
);
580 std::unique_lock
<std::recursive_mutex
> lock
;
581 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
583 if (!exe_ctx
.HasThreadScope()) {
584 error
.SetErrorString("this SBThread object is invalid");
588 bool abort_other_plans
= false;
590 Thread
*thread
= exe_ctx
.GetThreadPtr();
591 StackFrameSP
frame_sp(thread
->GetStackFrameAtIndex(0));
592 ThreadPlanSP new_plan_sp
;
593 Status new_plan_status
;
595 if (frame_sp
&& frame_sp
->HasDebugInformation()) {
596 SymbolContext
sc(frame_sp
->GetSymbolContext(eSymbolContextEverything
));
598 if (end_line
== LLDB_INVALID_LINE_NUMBER
)
599 range
= sc
.line_entry
.range
;
601 if (!sc
.GetAddressRangeFromHereToEndLine(end_line
, range
, error
.ref()))
605 const LazyBool step_out_avoids_code_without_debug_info
=
607 const LazyBool step_in_avoids_code_without_debug_info
=
609 new_plan_sp
= thread
->QueueThreadPlanForStepInRange(
610 abort_other_plans
, range
, sc
, target_name
, stop_other_threads
,
611 new_plan_status
, step_in_avoids_code_without_debug_info
,
612 step_out_avoids_code_without_debug_info
);
614 new_plan_sp
= thread
->QueueThreadPlanForStepSingleInstruction(
615 false, abort_other_plans
, stop_other_threads
, new_plan_status
);
618 if (new_plan_status
.Success())
619 error
= ResumeNewPlan(exe_ctx
, new_plan_sp
.get());
621 error
.SetErrorString(new_plan_status
.AsCString());
624 void SBThread::StepOut() {
625 LLDB_INSTRUMENT_VA(this);
627 SBError error
; // Ignored
631 void SBThread::StepOut(SBError
&error
) {
632 LLDB_INSTRUMENT_VA(this, error
);
634 std::unique_lock
<std::recursive_mutex
> lock
;
635 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
637 if (!exe_ctx
.HasThreadScope()) {
638 error
.SetErrorString("this SBThread object is invalid");
642 bool abort_other_plans
= false;
643 bool stop_other_threads
= false;
645 Thread
*thread
= exe_ctx
.GetThreadPtr();
647 const LazyBool avoid_no_debug
= eLazyBoolCalculate
;
648 Status new_plan_status
;
649 ThreadPlanSP
new_plan_sp(thread
->QueueThreadPlanForStepOut(
650 abort_other_plans
, nullptr, false, stop_other_threads
, eVoteYes
,
651 eVoteNoOpinion
, 0, new_plan_status
, avoid_no_debug
));
653 if (new_plan_status
.Success())
654 error
= ResumeNewPlan(exe_ctx
, new_plan_sp
.get());
656 error
.SetErrorString(new_plan_status
.AsCString());
659 void SBThread::StepOutOfFrame(SBFrame
&sb_frame
) {
660 LLDB_INSTRUMENT_VA(this, sb_frame
);
662 SBError error
; // Ignored
663 StepOutOfFrame(sb_frame
, error
);
666 void SBThread::StepOutOfFrame(SBFrame
&sb_frame
, SBError
&error
) {
667 LLDB_INSTRUMENT_VA(this, sb_frame
, error
);
669 std::unique_lock
<std::recursive_mutex
> lock
;
670 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
672 if (!sb_frame
.IsValid()) {
673 error
.SetErrorString("passed invalid SBFrame object");
677 StackFrameSP
frame_sp(sb_frame
.GetFrameSP());
679 if (!exe_ctx
.HasThreadScope()) {
680 error
.SetErrorString("this SBThread object is invalid");
684 bool abort_other_plans
= false;
685 bool stop_other_threads
= false;
686 Thread
*thread
= exe_ctx
.GetThreadPtr();
687 if (sb_frame
.GetThread().GetThreadID() != thread
->GetID()) {
688 error
.SetErrorString("passed a frame from another thread");
692 Status new_plan_status
;
693 ThreadPlanSP
new_plan_sp(thread
->QueueThreadPlanForStepOut(
694 abort_other_plans
, nullptr, false, stop_other_threads
, eVoteYes
,
695 eVoteNoOpinion
, frame_sp
->GetFrameIndex(), new_plan_status
));
697 if (new_plan_status
.Success())
698 error
= ResumeNewPlan(exe_ctx
, new_plan_sp
.get());
700 error
.SetErrorString(new_plan_status
.AsCString());
703 void SBThread::StepInstruction(bool step_over
) {
704 LLDB_INSTRUMENT_VA(this, step_over
);
706 SBError error
; // Ignored
707 StepInstruction(step_over
, error
);
710 void SBThread::StepInstruction(bool step_over
, SBError
&error
) {
711 LLDB_INSTRUMENT_VA(this, step_over
, error
);
713 std::unique_lock
<std::recursive_mutex
> lock
;
714 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
716 if (!exe_ctx
.HasThreadScope()) {
717 error
.SetErrorString("this SBThread object is invalid");
721 Thread
*thread
= exe_ctx
.GetThreadPtr();
722 Status new_plan_status
;
723 ThreadPlanSP
new_plan_sp(thread
->QueueThreadPlanForStepSingleInstruction(
724 step_over
, true, true, new_plan_status
));
726 if (new_plan_status
.Success())
727 error
= ResumeNewPlan(exe_ctx
, new_plan_sp
.get());
729 error
.SetErrorString(new_plan_status
.AsCString());
732 void SBThread::RunToAddress(lldb::addr_t addr
) {
733 LLDB_INSTRUMENT_VA(this, addr
);
735 SBError error
; // Ignored
736 RunToAddress(addr
, error
);
739 void SBThread::RunToAddress(lldb::addr_t addr
, SBError
&error
) {
740 LLDB_INSTRUMENT_VA(this, addr
, error
);
742 std::unique_lock
<std::recursive_mutex
> lock
;
743 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
745 if (!exe_ctx
.HasThreadScope()) {
746 error
.SetErrorString("this SBThread object is invalid");
750 bool abort_other_plans
= false;
751 bool stop_other_threads
= true;
753 Address
target_addr(addr
);
755 Thread
*thread
= exe_ctx
.GetThreadPtr();
757 Status new_plan_status
;
758 ThreadPlanSP
new_plan_sp(thread
->QueueThreadPlanForRunToAddress(
759 abort_other_plans
, target_addr
, stop_other_threads
, new_plan_status
));
761 if (new_plan_status
.Success())
762 error
= ResumeNewPlan(exe_ctx
, new_plan_sp
.get());
764 error
.SetErrorString(new_plan_status
.AsCString());
767 SBError
SBThread::StepOverUntil(lldb::SBFrame
&sb_frame
,
768 lldb::SBFileSpec
&sb_file_spec
, uint32_t line
) {
769 LLDB_INSTRUMENT_VA(this, sb_frame
, sb_file_spec
, line
);
774 std::unique_lock
<std::recursive_mutex
> lock
;
775 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
777 StackFrameSP
frame_sp(sb_frame
.GetFrameSP());
779 if (exe_ctx
.HasThreadScope()) {
780 Target
*target
= exe_ctx
.GetTargetPtr();
781 Thread
*thread
= exe_ctx
.GetThreadPtr();
784 sb_error
.SetErrorString("invalid line argument");
789 // We don't want to run SelectMostRelevantFrame here, for instance if
790 // you called a sequence of StepOverUntil's you wouldn't want the
791 // frame changed out from under you because you stepped into a
793 frame_sp
= thread
->GetSelectedFrame(DoNoSelectMostRelevantFrame
);
795 frame_sp
= thread
->GetStackFrameAtIndex(0);
798 SymbolContext frame_sc
;
800 sb_error
.SetErrorString("no valid frames in thread to step");
804 // If we have a frame, get its line
805 frame_sc
= frame_sp
->GetSymbolContext(
806 eSymbolContextCompUnit
| eSymbolContextFunction
|
807 eSymbolContextLineEntry
| eSymbolContextSymbol
);
809 if (frame_sc
.comp_unit
== nullptr) {
810 sb_error
.SetErrorStringWithFormat(
811 "frame %u doesn't have debug information", frame_sp
->GetFrameIndex());
815 FileSpec step_file_spec
;
816 if (sb_file_spec
.IsValid()) {
817 // The file spec passed in was valid, so use it
818 step_file_spec
= sb_file_spec
.ref();
820 if (frame_sc
.line_entry
.IsValid())
821 step_file_spec
= frame_sc
.line_entry
.file
;
823 sb_error
.SetErrorString("invalid file argument or no file for frame");
828 // Grab the current function, then we will make sure the "until" address is
829 // within the function. We discard addresses that are out of the current
830 // function, and then if there are no addresses remaining, give an
831 // appropriate error message.
833 bool all_in_function
= true;
834 AddressRange fun_range
= frame_sc
.function
->GetAddressRange();
836 std::vector
<addr_t
> step_over_until_addrs
;
837 const bool abort_other_plans
= false;
838 const bool stop_other_threads
= false;
839 // TODO: Handle SourceLocationSpec column information
840 SourceLocationSpec
location_spec(
841 step_file_spec
, line
, /*column=*/std::nullopt
, /*check_inlines=*/true,
842 /*exact_match=*/false);
844 SymbolContextList sc_list
;
845 frame_sc
.comp_unit
->ResolveSymbolContext(location_spec
,
846 eSymbolContextLineEntry
, sc_list
);
847 for (const SymbolContext
&sc
: sc_list
) {
849 sc
.line_entry
.range
.GetBaseAddress().GetLoadAddress(target
);
850 if (step_addr
!= LLDB_INVALID_ADDRESS
) {
851 if (fun_range
.ContainsLoadAddress(step_addr
, target
))
852 step_over_until_addrs
.push_back(step_addr
);
854 all_in_function
= false;
858 if (step_over_until_addrs
.empty()) {
859 if (all_in_function
) {
860 step_file_spec
.GetPath(path
, sizeof(path
));
861 sb_error
.SetErrorStringWithFormat("No line entries for %s:%u", path
,
864 sb_error
.SetErrorString("step until target not in current function");
866 Status new_plan_status
;
867 ThreadPlanSP
new_plan_sp(thread
->QueueThreadPlanForStepUntil(
868 abort_other_plans
, &step_over_until_addrs
[0],
869 step_over_until_addrs
.size(), stop_other_threads
,
870 frame_sp
->GetFrameIndex(), new_plan_status
));
872 if (new_plan_status
.Success())
873 sb_error
= ResumeNewPlan(exe_ctx
, new_plan_sp
.get());
875 sb_error
.SetErrorString(new_plan_status
.AsCString());
878 sb_error
.SetErrorString("this SBThread object is invalid");
883 SBError
SBThread::StepUsingScriptedThreadPlan(const char *script_class_name
) {
884 LLDB_INSTRUMENT_VA(this, script_class_name
);
886 return StepUsingScriptedThreadPlan(script_class_name
, true);
889 SBError
SBThread::StepUsingScriptedThreadPlan(const char *script_class_name
,
890 bool resume_immediately
) {
891 LLDB_INSTRUMENT_VA(this, script_class_name
, resume_immediately
);
893 lldb::SBStructuredData no_data
;
894 return StepUsingScriptedThreadPlan(script_class_name
, no_data
,
898 SBError
SBThread::StepUsingScriptedThreadPlan(const char *script_class_name
,
899 SBStructuredData
&args_data
,
900 bool resume_immediately
) {
901 LLDB_INSTRUMENT_VA(this, script_class_name
, args_data
, resume_immediately
);
905 std::unique_lock
<std::recursive_mutex
> lock
;
906 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
908 if (!exe_ctx
.HasThreadScope()) {
909 error
.SetErrorString("this SBThread object is invalid");
913 Thread
*thread
= exe_ctx
.GetThreadPtr();
914 Status new_plan_status
;
915 StructuredData::ObjectSP obj_sp
= args_data
.m_impl_up
->GetObjectSP();
917 ThreadPlanSP new_plan_sp
= thread
->QueueThreadPlanForStepScripted(
918 false, script_class_name
, obj_sp
, false, new_plan_status
);
920 if (new_plan_status
.Fail()) {
921 error
.SetErrorString(new_plan_status
.AsCString());
925 if (!resume_immediately
)
928 if (new_plan_status
.Success())
929 error
= ResumeNewPlan(exe_ctx
, new_plan_sp
.get());
931 error
.SetErrorString(new_plan_status
.AsCString());
936 SBError
SBThread::JumpToLine(lldb::SBFileSpec
&file_spec
, uint32_t line
) {
937 LLDB_INSTRUMENT_VA(this, file_spec
, line
);
941 std::unique_lock
<std::recursive_mutex
> lock
;
942 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
944 if (!exe_ctx
.HasThreadScope()) {
945 sb_error
.SetErrorString("this SBThread object is invalid");
949 Thread
*thread
= exe_ctx
.GetThreadPtr();
951 Status err
= thread
->JumpToLine(file_spec
.ref(), line
, true);
952 sb_error
.SetError(err
);
956 SBError
SBThread::ReturnFromFrame(SBFrame
&frame
, SBValue
&return_value
) {
957 LLDB_INSTRUMENT_VA(this, frame
, return_value
);
961 std::unique_lock
<std::recursive_mutex
> lock
;
962 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
964 if (exe_ctx
.HasThreadScope()) {
965 Thread
*thread
= exe_ctx
.GetThreadPtr();
967 thread
->ReturnFromFrame(frame
.GetFrameSP(), return_value
.GetSP()));
973 SBError
SBThread::UnwindInnermostExpression() {
974 LLDB_INSTRUMENT_VA(this);
978 std::unique_lock
<std::recursive_mutex
> lock
;
979 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
981 if (exe_ctx
.HasThreadScope()) {
982 Thread
*thread
= exe_ctx
.GetThreadPtr();
983 sb_error
.SetError(thread
->UnwindInnermostExpression());
984 if (sb_error
.Success())
985 thread
->SetSelectedFrameByIndex(0, false);
991 bool SBThread::Suspend() {
992 LLDB_INSTRUMENT_VA(this);
994 SBError error
; // Ignored
995 return Suspend(error
);
998 bool SBThread::Suspend(SBError
&error
) {
999 LLDB_INSTRUMENT_VA(this, error
);
1001 std::unique_lock
<std::recursive_mutex
> lock
;
1002 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1004 bool result
= false;
1005 if (exe_ctx
.HasThreadScope()) {
1006 Process::StopLocker stop_locker
;
1007 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
1008 exe_ctx
.GetThreadPtr()->SetResumeState(eStateSuspended
);
1011 error
.SetErrorString("process is running");
1014 error
.SetErrorString("this SBThread object is invalid");
1018 bool SBThread::Resume() {
1019 LLDB_INSTRUMENT_VA(this);
1021 SBError error
; // Ignored
1022 return Resume(error
);
1025 bool SBThread::Resume(SBError
&error
) {
1026 LLDB_INSTRUMENT_VA(this, error
);
1028 std::unique_lock
<std::recursive_mutex
> lock
;
1029 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1031 bool result
= false;
1032 if (exe_ctx
.HasThreadScope()) {
1033 Process::StopLocker stop_locker
;
1034 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
1035 const bool override_suspend
= true;
1036 exe_ctx
.GetThreadPtr()->SetResumeState(eStateRunning
, override_suspend
);
1039 error
.SetErrorString("process is running");
1042 error
.SetErrorString("this SBThread object is invalid");
1046 bool SBThread::IsSuspended() {
1047 LLDB_INSTRUMENT_VA(this);
1049 std::unique_lock
<std::recursive_mutex
> lock
;
1050 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1052 if (exe_ctx
.HasThreadScope())
1053 return exe_ctx
.GetThreadPtr()->GetResumeState() == eStateSuspended
;
1057 bool SBThread::IsStopped() {
1058 LLDB_INSTRUMENT_VA(this);
1060 std::unique_lock
<std::recursive_mutex
> lock
;
1061 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1063 if (exe_ctx
.HasThreadScope())
1064 return StateIsStoppedState(exe_ctx
.GetThreadPtr()->GetState(), true);
1068 SBProcess
SBThread::GetProcess() {
1069 LLDB_INSTRUMENT_VA(this);
1071 SBProcess sb_process
;
1072 std::unique_lock
<std::recursive_mutex
> lock
;
1073 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1075 if (exe_ctx
.HasThreadScope()) {
1076 // Have to go up to the target so we can get a shared pointer to our
1078 sb_process
.SetSP(exe_ctx
.GetProcessSP());
1084 uint32_t SBThread::GetNumFrames() {
1085 LLDB_INSTRUMENT_VA(this);
1087 uint32_t num_frames
= 0;
1088 std::unique_lock
<std::recursive_mutex
> lock
;
1089 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1091 if (exe_ctx
.HasThreadScope()) {
1092 Process::StopLocker stop_locker
;
1093 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
1094 num_frames
= exe_ctx
.GetThreadPtr()->GetStackFrameCount();
1101 SBFrame
SBThread::GetFrameAtIndex(uint32_t idx
) {
1102 LLDB_INSTRUMENT_VA(this, idx
);
1105 StackFrameSP frame_sp
;
1106 std::unique_lock
<std::recursive_mutex
> lock
;
1107 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1109 if (exe_ctx
.HasThreadScope()) {
1110 Process::StopLocker stop_locker
;
1111 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
1112 frame_sp
= exe_ctx
.GetThreadPtr()->GetStackFrameAtIndex(idx
);
1113 sb_frame
.SetFrameSP(frame_sp
);
1120 lldb::SBFrame
SBThread::GetSelectedFrame() {
1121 LLDB_INSTRUMENT_VA(this);
1124 StackFrameSP frame_sp
;
1125 std::unique_lock
<std::recursive_mutex
> lock
;
1126 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1128 if (exe_ctx
.HasThreadScope()) {
1129 Process::StopLocker stop_locker
;
1130 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
1132 exe_ctx
.GetThreadPtr()->GetSelectedFrame(SelectMostRelevantFrame
);
1133 sb_frame
.SetFrameSP(frame_sp
);
1140 lldb::SBFrame
SBThread::SetSelectedFrame(uint32_t idx
) {
1141 LLDB_INSTRUMENT_VA(this, idx
);
1144 StackFrameSP frame_sp
;
1145 std::unique_lock
<std::recursive_mutex
> lock
;
1146 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1148 if (exe_ctx
.HasThreadScope()) {
1149 Process::StopLocker stop_locker
;
1150 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
1151 Thread
*thread
= exe_ctx
.GetThreadPtr();
1152 frame_sp
= thread
->GetStackFrameAtIndex(idx
);
1154 thread
->SetSelectedFrame(frame_sp
.get());
1155 sb_frame
.SetFrameSP(frame_sp
);
1163 bool SBThread::EventIsThreadEvent(const SBEvent
&event
) {
1164 LLDB_INSTRUMENT_VA(event
);
1166 return Thread::ThreadEventData::GetEventDataFromEvent(event
.get()) != nullptr;
1169 SBFrame
SBThread::GetStackFrameFromEvent(const SBEvent
&event
) {
1170 LLDB_INSTRUMENT_VA(event
);
1172 return Thread::ThreadEventData::GetStackFrameFromEvent(event
.get());
1175 SBThread
SBThread::GetThreadFromEvent(const SBEvent
&event
) {
1176 LLDB_INSTRUMENT_VA(event
);
1178 return Thread::ThreadEventData::GetThreadFromEvent(event
.get());
1181 bool SBThread::operator==(const SBThread
&rhs
) const {
1182 LLDB_INSTRUMENT_VA(this, rhs
);
1184 return m_opaque_sp
->GetThreadSP().get() ==
1185 rhs
.m_opaque_sp
->GetThreadSP().get();
1188 bool SBThread::operator!=(const SBThread
&rhs
) const {
1189 LLDB_INSTRUMENT_VA(this, rhs
);
1191 return m_opaque_sp
->GetThreadSP().get() !=
1192 rhs
.m_opaque_sp
->GetThreadSP().get();
1195 bool SBThread::GetStatus(SBStream
&status
) const {
1196 LLDB_INSTRUMENT_VA(this, status
);
1198 Stream
&strm
= status
.ref();
1200 std::unique_lock
<std::recursive_mutex
> lock
;
1201 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1203 if (exe_ctx
.HasThreadScope()) {
1204 exe_ctx
.GetThreadPtr()->GetStatus(strm
, 0, 1, 1, true);
1206 strm
.PutCString("No status");
1211 bool SBThread::GetDescription(SBStream
&description
) const {
1212 LLDB_INSTRUMENT_VA(this, description
);
1214 return GetDescription(description
, false);
1217 bool SBThread::GetDescription(SBStream
&description
, bool stop_format
) const {
1218 LLDB_INSTRUMENT_VA(this, description
, stop_format
);
1220 Stream
&strm
= description
.ref();
1222 std::unique_lock
<std::recursive_mutex
> lock
;
1223 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1225 if (exe_ctx
.HasThreadScope()) {
1226 exe_ctx
.GetThreadPtr()->DumpUsingSettingsFormat(strm
,
1227 LLDB_INVALID_THREAD_ID
,
1229 // strm.Printf("SBThread: tid = 0x%4.4" PRIx64,
1230 // exe_ctx.GetThreadPtr()->GetID());
1232 strm
.PutCString("No value");
1237 SBThread
SBThread::GetExtendedBacktraceThread(const char *type
) {
1238 LLDB_INSTRUMENT_VA(this, type
);
1240 std::unique_lock
<std::recursive_mutex
> lock
;
1241 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1242 SBThread sb_origin_thread
;
1244 Process::StopLocker stop_locker
;
1245 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
1246 if (exe_ctx
.HasThreadScope()) {
1247 ThreadSP
real_thread(exe_ctx
.GetThreadSP());
1249 ConstString
type_const(type
);
1250 Process
*process
= exe_ctx
.GetProcessPtr();
1252 SystemRuntime
*runtime
= process
->GetSystemRuntime();
1254 ThreadSP
new_thread_sp(
1255 runtime
->GetExtendedBacktraceThread(real_thread
, type_const
));
1256 if (new_thread_sp
) {
1257 // Save this in the Process' ExtendedThreadList so a strong
1258 // pointer retains the object.
1259 process
->GetExtendedThreadList().AddThread(new_thread_sp
);
1260 sb_origin_thread
.SetThread(new_thread_sp
);
1268 return sb_origin_thread
;
1271 uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
1272 LLDB_INSTRUMENT_VA(this);
1274 ThreadSP
thread_sp(m_opaque_sp
->GetThreadSP());
1276 return thread_sp
->GetExtendedBacktraceOriginatingIndexID();
1277 return LLDB_INVALID_INDEX32
;
1280 SBValue
SBThread::GetCurrentException() {
1281 LLDB_INSTRUMENT_VA(this);
1283 ThreadSP
thread_sp(m_opaque_sp
->GetThreadSP());
1287 return SBValue(thread_sp
->GetCurrentException());
1290 SBThread
SBThread::GetCurrentExceptionBacktrace() {
1291 LLDB_INSTRUMENT_VA(this);
1293 ThreadSP
thread_sp(m_opaque_sp
->GetThreadSP());
1297 return SBThread(thread_sp
->GetCurrentExceptionBacktrace());
1300 bool SBThread::SafeToCallFunctions() {
1301 LLDB_INSTRUMENT_VA(this);
1303 ThreadSP
thread_sp(m_opaque_sp
->GetThreadSP());
1305 return thread_sp
->SafeToCallFunctions();
1309 lldb_private::Thread
*SBThread::operator->() {
1313 lldb_private::Thread
*SBThread::get() {
1314 return m_opaque_sp
->GetThreadSP().get();
1317 SBValue
SBThread::GetSiginfo() {
1318 LLDB_INSTRUMENT_VA(this);
1320 ThreadSP thread_sp
= m_opaque_sp
->GetThreadSP();
1323 return thread_sp
->GetSiginfoValue();