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/Core/ValueObject.h"
28 #include "lldb/Interpreter/CommandInterpreter.h"
29 #include "lldb/Symbol/CompileUnit.h"
30 #include "lldb/Symbol/SymbolContext.h"
31 #include "lldb/Target/Process.h"
32 #include "lldb/Target/Queue.h"
33 #include "lldb/Target/StopInfo.h"
34 #include "lldb/Target/SystemRuntime.h"
35 #include "lldb/Target/Target.h"
36 #include "lldb/Target/Thread.h"
37 #include "lldb/Target/ThreadPlan.h"
38 #include "lldb/Target/ThreadPlanStepInRange.h"
39 #include "lldb/Target/ThreadPlanStepInstruction.h"
40 #include "lldb/Target/ThreadPlanStepOut.h"
41 #include "lldb/Target/ThreadPlanStepRange.h"
42 #include "lldb/Utility/Instrumentation.h"
43 #include "lldb/Utility/State.h"
44 #include "lldb/Utility/Stream.h"
45 #include "lldb/Utility/StructuredData.h"
46 #include "lldb/lldb-enumerations.h"
51 using namespace lldb_private
;
53 const char *SBThread::GetBroadcasterClassName() {
56 return 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 eStopReasonException
:
198 case eStopReasonFork
:
201 case eStopReasonVFork
:
210 uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx
) {
211 LLDB_INSTRUMENT_VA(this, idx
);
213 std::unique_lock
<std::recursive_mutex
> lock
;
214 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
216 if (exe_ctx
.HasThreadScope()) {
217 Process::StopLocker stop_locker
;
218 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
219 Thread
*thread
= exe_ctx
.GetThreadPtr();
220 StopInfoSP stop_info_sp
= thread
->GetStopInfo();
222 StopReason reason
= stop_info_sp
->GetStopReason();
224 case eStopReasonInvalid
:
225 case eStopReasonNone
:
226 case eStopReasonTrace
:
227 case eStopReasonExec
:
228 case eStopReasonPlanComplete
:
229 case eStopReasonThreadExiting
:
230 case eStopReasonInstrumentation
:
231 case eStopReasonProcessorTrace
:
232 case eStopReasonVForkDone
:
233 // There is no data for these stop reasons.
236 case eStopReasonBreakpoint
: {
237 break_id_t site_id
= stop_info_sp
->GetValue();
238 lldb::BreakpointSiteSP
bp_site_sp(
239 exe_ctx
.GetProcessPtr()->GetBreakpointSiteList().FindByID(
242 uint32_t bp_index
= idx
/ 2;
243 BreakpointLocationSP
bp_loc_sp(
244 bp_site_sp
->GetConstituentAtIndex(bp_index
));
247 // Odd idx, return the breakpoint location ID
248 return bp_loc_sp
->GetID();
250 // Even idx, return the breakpoint ID
251 return bp_loc_sp
->GetBreakpoint().GetID();
255 return LLDB_INVALID_BREAK_ID
;
258 case eStopReasonWatchpoint
:
259 return stop_info_sp
->GetValue();
261 case eStopReasonSignal
:
262 return stop_info_sp
->GetValue();
264 case eStopReasonException
:
265 return stop_info_sp
->GetValue();
267 case eStopReasonFork
:
268 return stop_info_sp
->GetValue();
270 case eStopReasonVFork
:
271 return stop_info_sp
->GetValue();
279 bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream
&stream
) {
280 LLDB_INSTRUMENT_VA(this, stream
);
282 Stream
&strm
= stream
.ref();
284 std::unique_lock
<std::recursive_mutex
> lock
;
285 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
287 if (!exe_ctx
.HasThreadScope())
290 StopInfoSP stop_info
= exe_ctx
.GetThreadPtr()->GetStopInfo();
291 StructuredData::ObjectSP info
= stop_info
->GetExtendedInfo();
301 SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type
) {
302 LLDB_INSTRUMENT_VA(this, type
);
304 SBThreadCollection threads
;
306 std::unique_lock
<std::recursive_mutex
> lock
;
307 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
309 if (!exe_ctx
.HasThreadScope())
310 return SBThreadCollection();
312 ProcessSP process_sp
= exe_ctx
.GetProcessSP();
314 StopInfoSP stop_info
= exe_ctx
.GetThreadPtr()->GetStopInfo();
315 StructuredData::ObjectSP info
= stop_info
->GetExtendedInfo();
319 threads
= process_sp
->GetInstrumentationRuntime(type
)
320 ->GetBacktracesFromExtendedStopInfo(info
);
324 size_t SBThread::GetStopDescription(char *dst
, size_t dst_len
) {
325 LLDB_INSTRUMENT_VA(this, dst
, dst_len
);
327 std::unique_lock
<std::recursive_mutex
> lock
;
328 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
333 if (!exe_ctx
.HasThreadScope())
336 Process::StopLocker stop_locker
;
337 if (!stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock()))
340 std::string thread_stop_desc
= exe_ctx
.GetThreadPtr()->GetStopDescription();
341 if (thread_stop_desc
.empty())
345 return ::snprintf(dst
, dst_len
, "%s", thread_stop_desc
.c_str()) + 1;
347 // NULL dst passed in, return the length needed to contain the
349 return thread_stop_desc
.size() + 1; // Include the NULL byte for size
352 SBValue
SBThread::GetStopReturnValue() {
353 LLDB_INSTRUMENT_VA(this);
355 ValueObjectSP return_valobj_sp
;
356 std::unique_lock
<std::recursive_mutex
> lock
;
357 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
359 if (exe_ctx
.HasThreadScope()) {
360 Process::StopLocker stop_locker
;
361 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
362 StopInfoSP stop_info_sp
= exe_ctx
.GetThreadPtr()->GetStopInfo();
364 return_valobj_sp
= StopInfo::GetReturnValueObject(stop_info_sp
);
369 return SBValue(return_valobj_sp
);
372 void SBThread::SetThread(const ThreadSP
&lldb_object_sp
) {
373 m_opaque_sp
->SetThreadSP(lldb_object_sp
);
376 lldb::tid_t
SBThread::GetThreadID() const {
377 LLDB_INSTRUMENT_VA(this);
379 ThreadSP
thread_sp(m_opaque_sp
->GetThreadSP());
381 return thread_sp
->GetID();
382 return LLDB_INVALID_THREAD_ID
;
385 uint32_t SBThread::GetIndexID() const {
386 LLDB_INSTRUMENT_VA(this);
388 ThreadSP
thread_sp(m_opaque_sp
->GetThreadSP());
390 return thread_sp
->GetIndexID();
391 return LLDB_INVALID_INDEX32
;
394 const char *SBThread::GetName() const {
395 LLDB_INSTRUMENT_VA(this);
397 std::unique_lock
<std::recursive_mutex
> lock
;
398 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
400 if (!exe_ctx
.HasThreadScope())
403 Process::StopLocker stop_locker
;
404 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock()))
405 return ConstString(exe_ctx
.GetThreadPtr()->GetName()).GetCString();
410 const char *SBThread::GetQueueName() const {
411 LLDB_INSTRUMENT_VA(this);
413 std::unique_lock
<std::recursive_mutex
> lock
;
414 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
416 if (!exe_ctx
.HasThreadScope())
419 Process::StopLocker stop_locker
;
420 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock()))
421 return ConstString(exe_ctx
.GetThreadPtr()->GetQueueName()).GetCString();
426 lldb::queue_id_t
SBThread::GetQueueID() const {
427 LLDB_INSTRUMENT_VA(this);
429 queue_id_t id
= LLDB_INVALID_QUEUE_ID
;
430 std::unique_lock
<std::recursive_mutex
> lock
;
431 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
433 if (exe_ctx
.HasThreadScope()) {
434 Process::StopLocker stop_locker
;
435 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
436 id
= exe_ctx
.GetThreadPtr()->GetQueueID();
443 bool SBThread::GetInfoItemByPathAsString(const char *path
, SBStream
&strm
) {
444 LLDB_INSTRUMENT_VA(this, path
, strm
);
446 bool success
= false;
447 std::unique_lock
<std::recursive_mutex
> lock
;
448 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
450 if (exe_ctx
.HasThreadScope()) {
451 Process::StopLocker stop_locker
;
452 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
453 Thread
*thread
= exe_ctx
.GetThreadPtr();
454 StructuredData::ObjectSP info_root_sp
= thread
->GetExtendedInfo();
456 StructuredData::ObjectSP node
=
457 info_root_sp
->GetObjectForDotSeparatedPath(path
);
459 if (node
->GetType() == eStructuredDataTypeString
) {
460 strm
.ref() << node
->GetAsString()->GetValue();
463 if (node
->GetType() == eStructuredDataTypeInteger
) {
464 strm
.Printf("0x%" PRIx64
, node
->GetUnsignedIntegerValue());
467 if (node
->GetType() == eStructuredDataTypeFloat
) {
468 strm
.Printf("0x%f", node
->GetAsFloat()->GetValue());
471 if (node
->GetType() == eStructuredDataTypeBoolean
) {
472 if (node
->GetAsBoolean()->GetValue())
475 strm
.Printf("false");
478 if (node
->GetType() == eStructuredDataTypeNull
) {
490 SBError
SBThread::ResumeNewPlan(ExecutionContext
&exe_ctx
,
491 ThreadPlan
*new_plan
) {
494 Process
*process
= exe_ctx
.GetProcessPtr();
496 sb_error
.SetErrorString("No process in SBThread::ResumeNewPlan");
500 Thread
*thread
= exe_ctx
.GetThreadPtr();
502 sb_error
.SetErrorString("No thread in SBThread::ResumeNewPlan");
506 // User level plans should be Controlling Plans so they can be interrupted,
507 // other plans executed, and then a "continue" will resume the plan.
508 if (new_plan
!= nullptr) {
509 new_plan
->SetIsControllingPlan(true);
510 new_plan
->SetOkayToDiscard(false);
513 // Why do we need to set the current thread by ID here???
514 process
->GetThreadList().SetSelectedThreadByID(thread
->GetID());
516 if (process
->GetTarget().GetDebugger().GetAsyncExecution())
517 sb_error
.ref() = process
->Resume();
519 sb_error
.ref() = process
->ResumeSynchronous(nullptr);
524 void SBThread::StepOver(lldb::RunMode stop_other_threads
) {
525 LLDB_INSTRUMENT_VA(this, stop_other_threads
);
527 SBError error
; // Ignored
528 StepOver(stop_other_threads
, error
);
531 void SBThread::StepOver(lldb::RunMode stop_other_threads
, SBError
&error
) {
532 LLDB_INSTRUMENT_VA(this, stop_other_threads
, error
);
534 std::unique_lock
<std::recursive_mutex
> lock
;
535 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
537 if (!exe_ctx
.HasThreadScope()) {
538 error
.SetErrorString("this SBThread object is invalid");
542 Thread
*thread
= exe_ctx
.GetThreadPtr();
543 bool abort_other_plans
= false;
544 StackFrameSP
frame_sp(thread
->GetStackFrameAtIndex(0));
546 Status new_plan_status
;
547 ThreadPlanSP new_plan_sp
;
549 if (frame_sp
->HasDebugInformation()) {
550 const LazyBool avoid_no_debug
= eLazyBoolCalculate
;
551 SymbolContext
sc(frame_sp
->GetSymbolContext(eSymbolContextEverything
));
552 new_plan_sp
= thread
->QueueThreadPlanForStepOverRange(
553 abort_other_plans
, sc
.line_entry
, sc
, stop_other_threads
,
554 new_plan_status
, avoid_no_debug
);
556 new_plan_sp
= thread
->QueueThreadPlanForStepSingleInstruction(
557 true, abort_other_plans
, stop_other_threads
, new_plan_status
);
560 error
= ResumeNewPlan(exe_ctx
, new_plan_sp
.get());
563 void SBThread::StepInto(lldb::RunMode stop_other_threads
) {
564 LLDB_INSTRUMENT_VA(this, stop_other_threads
);
566 StepInto(nullptr, stop_other_threads
);
569 void SBThread::StepInto(const char *target_name
,
570 lldb::RunMode stop_other_threads
) {
571 LLDB_INSTRUMENT_VA(this, target_name
, stop_other_threads
);
573 SBError error
; // Ignored
574 StepInto(target_name
, LLDB_INVALID_LINE_NUMBER
, error
, stop_other_threads
);
577 void SBThread::StepInto(const char *target_name
, uint32_t end_line
,
578 SBError
&error
, lldb::RunMode stop_other_threads
) {
579 LLDB_INSTRUMENT_VA(this, target_name
, end_line
, error
, stop_other_threads
);
581 std::unique_lock
<std::recursive_mutex
> lock
;
582 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
584 if (!exe_ctx
.HasThreadScope()) {
585 error
.SetErrorString("this SBThread object is invalid");
589 bool abort_other_plans
= false;
591 Thread
*thread
= exe_ctx
.GetThreadPtr();
592 StackFrameSP
frame_sp(thread
->GetStackFrameAtIndex(0));
593 ThreadPlanSP new_plan_sp
;
594 Status new_plan_status
;
596 if (frame_sp
&& frame_sp
->HasDebugInformation()) {
597 SymbolContext
sc(frame_sp
->GetSymbolContext(eSymbolContextEverything
));
599 if (end_line
== LLDB_INVALID_LINE_NUMBER
)
600 range
= sc
.line_entry
.range
;
602 if (!sc
.GetAddressRangeFromHereToEndLine(end_line
, range
, error
.ref()))
606 const LazyBool step_out_avoids_code_without_debug_info
=
608 const LazyBool step_in_avoids_code_without_debug_info
=
610 new_plan_sp
= thread
->QueueThreadPlanForStepInRange(
611 abort_other_plans
, range
, sc
, target_name
, stop_other_threads
,
612 new_plan_status
, step_in_avoids_code_without_debug_info
,
613 step_out_avoids_code_without_debug_info
);
615 new_plan_sp
= thread
->QueueThreadPlanForStepSingleInstruction(
616 false, abort_other_plans
, stop_other_threads
, new_plan_status
);
619 if (new_plan_status
.Success())
620 error
= ResumeNewPlan(exe_ctx
, new_plan_sp
.get());
622 error
.SetErrorString(new_plan_status
.AsCString());
625 void SBThread::StepOut() {
626 LLDB_INSTRUMENT_VA(this);
628 SBError error
; // Ignored
632 void SBThread::StepOut(SBError
&error
) {
633 LLDB_INSTRUMENT_VA(this, error
);
635 std::unique_lock
<std::recursive_mutex
> lock
;
636 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
638 if (!exe_ctx
.HasThreadScope()) {
639 error
.SetErrorString("this SBThread object is invalid");
643 bool abort_other_plans
= false;
644 bool stop_other_threads
= false;
646 Thread
*thread
= exe_ctx
.GetThreadPtr();
648 const LazyBool avoid_no_debug
= eLazyBoolCalculate
;
649 Status new_plan_status
;
650 ThreadPlanSP
new_plan_sp(thread
->QueueThreadPlanForStepOut(
651 abort_other_plans
, nullptr, false, stop_other_threads
, eVoteYes
,
652 eVoteNoOpinion
, 0, new_plan_status
, avoid_no_debug
));
654 if (new_plan_status
.Success())
655 error
= ResumeNewPlan(exe_ctx
, new_plan_sp
.get());
657 error
.SetErrorString(new_plan_status
.AsCString());
660 void SBThread::StepOutOfFrame(SBFrame
&sb_frame
) {
661 LLDB_INSTRUMENT_VA(this, sb_frame
);
663 SBError error
; // Ignored
664 StepOutOfFrame(sb_frame
, error
);
667 void SBThread::StepOutOfFrame(SBFrame
&sb_frame
, SBError
&error
) {
668 LLDB_INSTRUMENT_VA(this, sb_frame
, error
);
670 std::unique_lock
<std::recursive_mutex
> lock
;
671 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
673 if (!sb_frame
.IsValid()) {
674 error
.SetErrorString("passed invalid SBFrame object");
678 StackFrameSP
frame_sp(sb_frame
.GetFrameSP());
680 if (!exe_ctx
.HasThreadScope()) {
681 error
.SetErrorString("this SBThread object is invalid");
685 bool abort_other_plans
= false;
686 bool stop_other_threads
= false;
687 Thread
*thread
= exe_ctx
.GetThreadPtr();
688 if (sb_frame
.GetThread().GetThreadID() != thread
->GetID()) {
689 error
.SetErrorString("passed a frame from another thread");
693 Status new_plan_status
;
694 ThreadPlanSP
new_plan_sp(thread
->QueueThreadPlanForStepOut(
695 abort_other_plans
, nullptr, false, stop_other_threads
, eVoteYes
,
696 eVoteNoOpinion
, frame_sp
->GetFrameIndex(), new_plan_status
));
698 if (new_plan_status
.Success())
699 error
= ResumeNewPlan(exe_ctx
, new_plan_sp
.get());
701 error
.SetErrorString(new_plan_status
.AsCString());
704 void SBThread::StepInstruction(bool step_over
) {
705 LLDB_INSTRUMENT_VA(this, step_over
);
707 SBError error
; // Ignored
708 StepInstruction(step_over
, error
);
711 void SBThread::StepInstruction(bool step_over
, SBError
&error
) {
712 LLDB_INSTRUMENT_VA(this, step_over
, error
);
714 std::unique_lock
<std::recursive_mutex
> lock
;
715 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
717 if (!exe_ctx
.HasThreadScope()) {
718 error
.SetErrorString("this SBThread object is invalid");
722 Thread
*thread
= exe_ctx
.GetThreadPtr();
723 Status new_plan_status
;
724 ThreadPlanSP
new_plan_sp(thread
->QueueThreadPlanForStepSingleInstruction(
725 step_over
, true, true, new_plan_status
));
727 if (new_plan_status
.Success())
728 error
= ResumeNewPlan(exe_ctx
, new_plan_sp
.get());
730 error
.SetErrorString(new_plan_status
.AsCString());
733 void SBThread::RunToAddress(lldb::addr_t addr
) {
734 LLDB_INSTRUMENT_VA(this, addr
);
736 SBError error
; // Ignored
737 RunToAddress(addr
, error
);
740 void SBThread::RunToAddress(lldb::addr_t addr
, SBError
&error
) {
741 LLDB_INSTRUMENT_VA(this, addr
, error
);
743 std::unique_lock
<std::recursive_mutex
> lock
;
744 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
746 if (!exe_ctx
.HasThreadScope()) {
747 error
.SetErrorString("this SBThread object is invalid");
751 bool abort_other_plans
= false;
752 bool stop_other_threads
= true;
754 Address
target_addr(addr
);
756 Thread
*thread
= exe_ctx
.GetThreadPtr();
758 Status new_plan_status
;
759 ThreadPlanSP
new_plan_sp(thread
->QueueThreadPlanForRunToAddress(
760 abort_other_plans
, target_addr
, stop_other_threads
, new_plan_status
));
762 if (new_plan_status
.Success())
763 error
= ResumeNewPlan(exe_ctx
, new_plan_sp
.get());
765 error
.SetErrorString(new_plan_status
.AsCString());
768 SBError
SBThread::StepOverUntil(lldb::SBFrame
&sb_frame
,
769 lldb::SBFileSpec
&sb_file_spec
, uint32_t line
) {
770 LLDB_INSTRUMENT_VA(this, sb_frame
, sb_file_spec
, line
);
775 std::unique_lock
<std::recursive_mutex
> lock
;
776 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
778 StackFrameSP
frame_sp(sb_frame
.GetFrameSP());
780 if (exe_ctx
.HasThreadScope()) {
781 Target
*target
= exe_ctx
.GetTargetPtr();
782 Thread
*thread
= exe_ctx
.GetThreadPtr();
785 sb_error
.SetErrorString("invalid line argument");
790 // We don't want to run SelectMostRelevantFrame here, for instance if
791 // you called a sequence of StepOverUntil's you wouldn't want the
792 // frame changed out from under you because you stepped into a
794 frame_sp
= thread
->GetSelectedFrame(DoNoSelectMostRelevantFrame
);
796 frame_sp
= thread
->GetStackFrameAtIndex(0);
799 SymbolContext frame_sc
;
801 sb_error
.SetErrorString("no valid frames in thread to step");
805 // If we have a frame, get its line
806 frame_sc
= frame_sp
->GetSymbolContext(
807 eSymbolContextCompUnit
| eSymbolContextFunction
|
808 eSymbolContextLineEntry
| eSymbolContextSymbol
);
810 if (frame_sc
.comp_unit
== nullptr) {
811 sb_error
.SetErrorStringWithFormat(
812 "frame %u doesn't have debug information", frame_sp
->GetFrameIndex());
816 FileSpec step_file_spec
;
817 if (sb_file_spec
.IsValid()) {
818 // The file spec passed in was valid, so use it
819 step_file_spec
= sb_file_spec
.ref();
821 if (frame_sc
.line_entry
.IsValid())
822 step_file_spec
= frame_sc
.line_entry
.file
;
824 sb_error
.SetErrorString("invalid file argument or no file for frame");
829 // Grab the current function, then we will make sure the "until" address is
830 // within the function. We discard addresses that are out of the current
831 // function, and then if there are no addresses remaining, give an
832 // appropriate error message.
834 bool all_in_function
= true;
835 AddressRange fun_range
= frame_sc
.function
->GetAddressRange();
837 std::vector
<addr_t
> step_over_until_addrs
;
838 const bool abort_other_plans
= false;
839 const bool stop_other_threads
= false;
840 // TODO: Handle SourceLocationSpec column information
841 SourceLocationSpec
location_spec(
842 step_file_spec
, line
, /*column=*/std::nullopt
, /*check_inlines=*/true,
843 /*exact_match=*/false);
845 SymbolContextList sc_list
;
846 frame_sc
.comp_unit
->ResolveSymbolContext(location_spec
,
847 eSymbolContextLineEntry
, sc_list
);
848 for (const SymbolContext
&sc
: sc_list
) {
850 sc
.line_entry
.range
.GetBaseAddress().GetLoadAddress(target
);
851 if (step_addr
!= LLDB_INVALID_ADDRESS
) {
852 if (fun_range
.ContainsLoadAddress(step_addr
, target
))
853 step_over_until_addrs
.push_back(step_addr
);
855 all_in_function
= false;
859 if (step_over_until_addrs
.empty()) {
860 if (all_in_function
) {
861 step_file_spec
.GetPath(path
, sizeof(path
));
862 sb_error
.SetErrorStringWithFormat("No line entries for %s:%u", path
,
865 sb_error
.SetErrorString("step until target not in current function");
867 Status new_plan_status
;
868 ThreadPlanSP
new_plan_sp(thread
->QueueThreadPlanForStepUntil(
869 abort_other_plans
, &step_over_until_addrs
[0],
870 step_over_until_addrs
.size(), stop_other_threads
,
871 frame_sp
->GetFrameIndex(), new_plan_status
));
873 if (new_plan_status
.Success())
874 sb_error
= ResumeNewPlan(exe_ctx
, new_plan_sp
.get());
876 sb_error
.SetErrorString(new_plan_status
.AsCString());
879 sb_error
.SetErrorString("this SBThread object is invalid");
884 SBError
SBThread::StepUsingScriptedThreadPlan(const char *script_class_name
) {
885 LLDB_INSTRUMENT_VA(this, script_class_name
);
887 return StepUsingScriptedThreadPlan(script_class_name
, true);
890 SBError
SBThread::StepUsingScriptedThreadPlan(const char *script_class_name
,
891 bool resume_immediately
) {
892 LLDB_INSTRUMENT_VA(this, script_class_name
, resume_immediately
);
894 lldb::SBStructuredData no_data
;
895 return StepUsingScriptedThreadPlan(script_class_name
, no_data
,
899 SBError
SBThread::StepUsingScriptedThreadPlan(const char *script_class_name
,
900 SBStructuredData
&args_data
,
901 bool resume_immediately
) {
902 LLDB_INSTRUMENT_VA(this, script_class_name
, args_data
, resume_immediately
);
906 std::unique_lock
<std::recursive_mutex
> lock
;
907 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
909 if (!exe_ctx
.HasThreadScope()) {
910 error
.SetErrorString("this SBThread object is invalid");
914 Thread
*thread
= exe_ctx
.GetThreadPtr();
915 Status new_plan_status
;
916 StructuredData::ObjectSP obj_sp
= args_data
.m_impl_up
->GetObjectSP();
918 ThreadPlanSP new_plan_sp
= thread
->QueueThreadPlanForStepScripted(
919 false, script_class_name
, obj_sp
, false, new_plan_status
);
921 if (new_plan_status
.Fail()) {
922 error
.SetErrorString(new_plan_status
.AsCString());
926 if (!resume_immediately
)
929 if (new_plan_status
.Success())
930 error
= ResumeNewPlan(exe_ctx
, new_plan_sp
.get());
932 error
.SetErrorString(new_plan_status
.AsCString());
937 SBError
SBThread::JumpToLine(lldb::SBFileSpec
&file_spec
, uint32_t line
) {
938 LLDB_INSTRUMENT_VA(this, file_spec
, line
);
942 std::unique_lock
<std::recursive_mutex
> lock
;
943 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
945 if (!exe_ctx
.HasThreadScope()) {
946 sb_error
.SetErrorString("this SBThread object is invalid");
950 Thread
*thread
= exe_ctx
.GetThreadPtr();
952 Status err
= thread
->JumpToLine(file_spec
.ref(), line
, true);
953 sb_error
.SetError(err
);
957 SBError
SBThread::ReturnFromFrame(SBFrame
&frame
, SBValue
&return_value
) {
958 LLDB_INSTRUMENT_VA(this, frame
, return_value
);
962 std::unique_lock
<std::recursive_mutex
> lock
;
963 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
965 if (exe_ctx
.HasThreadScope()) {
966 Thread
*thread
= exe_ctx
.GetThreadPtr();
968 thread
->ReturnFromFrame(frame
.GetFrameSP(), return_value
.GetSP()));
974 SBError
SBThread::UnwindInnermostExpression() {
975 LLDB_INSTRUMENT_VA(this);
979 std::unique_lock
<std::recursive_mutex
> lock
;
980 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
982 if (exe_ctx
.HasThreadScope()) {
983 Thread
*thread
= exe_ctx
.GetThreadPtr();
984 sb_error
.SetError(thread
->UnwindInnermostExpression());
985 if (sb_error
.Success())
986 thread
->SetSelectedFrameByIndex(0, false);
992 bool SBThread::Suspend() {
993 LLDB_INSTRUMENT_VA(this);
995 SBError error
; // Ignored
996 return Suspend(error
);
999 bool SBThread::Suspend(SBError
&error
) {
1000 LLDB_INSTRUMENT_VA(this, error
);
1002 std::unique_lock
<std::recursive_mutex
> lock
;
1003 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1005 bool result
= false;
1006 if (exe_ctx
.HasThreadScope()) {
1007 Process::StopLocker stop_locker
;
1008 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
1009 exe_ctx
.GetThreadPtr()->SetResumeState(eStateSuspended
);
1012 error
.SetErrorString("process is running");
1015 error
.SetErrorString("this SBThread object is invalid");
1019 bool SBThread::Resume() {
1020 LLDB_INSTRUMENT_VA(this);
1022 SBError error
; // Ignored
1023 return Resume(error
);
1026 bool SBThread::Resume(SBError
&error
) {
1027 LLDB_INSTRUMENT_VA(this, error
);
1029 std::unique_lock
<std::recursive_mutex
> lock
;
1030 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1032 bool result
= false;
1033 if (exe_ctx
.HasThreadScope()) {
1034 Process::StopLocker stop_locker
;
1035 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
1036 const bool override_suspend
= true;
1037 exe_ctx
.GetThreadPtr()->SetResumeState(eStateRunning
, override_suspend
);
1040 error
.SetErrorString("process is running");
1043 error
.SetErrorString("this SBThread object is invalid");
1047 bool SBThread::IsSuspended() {
1048 LLDB_INSTRUMENT_VA(this);
1050 std::unique_lock
<std::recursive_mutex
> lock
;
1051 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1053 if (exe_ctx
.HasThreadScope())
1054 return exe_ctx
.GetThreadPtr()->GetResumeState() == eStateSuspended
;
1058 bool SBThread::IsStopped() {
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 StateIsStoppedState(exe_ctx
.GetThreadPtr()->GetState(), true);
1069 SBProcess
SBThread::GetProcess() {
1070 LLDB_INSTRUMENT_VA(this);
1072 SBProcess sb_process
;
1073 std::unique_lock
<std::recursive_mutex
> lock
;
1074 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1076 if (exe_ctx
.HasThreadScope()) {
1077 // Have to go up to the target so we can get a shared pointer to our
1079 sb_process
.SetSP(exe_ctx
.GetProcessSP());
1085 uint32_t SBThread::GetNumFrames() {
1086 LLDB_INSTRUMENT_VA(this);
1088 uint32_t num_frames
= 0;
1089 std::unique_lock
<std::recursive_mutex
> lock
;
1090 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1092 if (exe_ctx
.HasThreadScope()) {
1093 Process::StopLocker stop_locker
;
1094 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
1095 num_frames
= exe_ctx
.GetThreadPtr()->GetStackFrameCount();
1102 SBFrame
SBThread::GetFrameAtIndex(uint32_t idx
) {
1103 LLDB_INSTRUMENT_VA(this, idx
);
1106 StackFrameSP frame_sp
;
1107 std::unique_lock
<std::recursive_mutex
> lock
;
1108 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1110 if (exe_ctx
.HasThreadScope()) {
1111 Process::StopLocker stop_locker
;
1112 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
1113 frame_sp
= exe_ctx
.GetThreadPtr()->GetStackFrameAtIndex(idx
);
1114 sb_frame
.SetFrameSP(frame_sp
);
1121 lldb::SBFrame
SBThread::GetSelectedFrame() {
1122 LLDB_INSTRUMENT_VA(this);
1125 StackFrameSP frame_sp
;
1126 std::unique_lock
<std::recursive_mutex
> lock
;
1127 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1129 if (exe_ctx
.HasThreadScope()) {
1130 Process::StopLocker stop_locker
;
1131 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
1133 exe_ctx
.GetThreadPtr()->GetSelectedFrame(SelectMostRelevantFrame
);
1134 sb_frame
.SetFrameSP(frame_sp
);
1141 lldb::SBFrame
SBThread::SetSelectedFrame(uint32_t idx
) {
1142 LLDB_INSTRUMENT_VA(this, idx
);
1145 StackFrameSP frame_sp
;
1146 std::unique_lock
<std::recursive_mutex
> lock
;
1147 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1149 if (exe_ctx
.HasThreadScope()) {
1150 Process::StopLocker stop_locker
;
1151 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
1152 Thread
*thread
= exe_ctx
.GetThreadPtr();
1153 frame_sp
= thread
->GetStackFrameAtIndex(idx
);
1155 thread
->SetSelectedFrame(frame_sp
.get());
1156 sb_frame
.SetFrameSP(frame_sp
);
1164 bool SBThread::EventIsThreadEvent(const SBEvent
&event
) {
1165 LLDB_INSTRUMENT_VA(event
);
1167 return Thread::ThreadEventData::GetEventDataFromEvent(event
.get()) != nullptr;
1170 SBFrame
SBThread::GetStackFrameFromEvent(const SBEvent
&event
) {
1171 LLDB_INSTRUMENT_VA(event
);
1173 return Thread::ThreadEventData::GetStackFrameFromEvent(event
.get());
1176 SBThread
SBThread::GetThreadFromEvent(const SBEvent
&event
) {
1177 LLDB_INSTRUMENT_VA(event
);
1179 return Thread::ThreadEventData::GetThreadFromEvent(event
.get());
1182 bool SBThread::operator==(const SBThread
&rhs
) const {
1183 LLDB_INSTRUMENT_VA(this, rhs
);
1185 return m_opaque_sp
->GetThreadSP().get() ==
1186 rhs
.m_opaque_sp
->GetThreadSP().get();
1189 bool SBThread::operator!=(const SBThread
&rhs
) const {
1190 LLDB_INSTRUMENT_VA(this, rhs
);
1192 return m_opaque_sp
->GetThreadSP().get() !=
1193 rhs
.m_opaque_sp
->GetThreadSP().get();
1196 bool SBThread::GetStatus(SBStream
&status
) const {
1197 LLDB_INSTRUMENT_VA(this, status
);
1199 Stream
&strm
= status
.ref();
1201 std::unique_lock
<std::recursive_mutex
> lock
;
1202 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1204 if (exe_ctx
.HasThreadScope()) {
1205 exe_ctx
.GetThreadPtr()->GetStatus(strm
, 0, 1, 1, true);
1207 strm
.PutCString("No status");
1212 bool SBThread::GetDescription(SBStream
&description
) const {
1213 LLDB_INSTRUMENT_VA(this, description
);
1215 return GetDescription(description
, false);
1218 bool SBThread::GetDescription(SBStream
&description
, bool stop_format
) const {
1219 LLDB_INSTRUMENT_VA(this, description
, stop_format
);
1221 Stream
&strm
= description
.ref();
1223 std::unique_lock
<std::recursive_mutex
> lock
;
1224 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1226 if (exe_ctx
.HasThreadScope()) {
1227 exe_ctx
.GetThreadPtr()->DumpUsingSettingsFormat(
1228 strm
, LLDB_INVALID_THREAD_ID
, stop_format
);
1230 strm
.PutCString("No value");
1235 SBError
SBThread::GetDescriptionWithFormat(const SBFormat
&format
,
1237 Stream
&strm
= output
.ref();
1241 error
.SetErrorString("The provided SBFormat object is invalid");
1245 std::unique_lock
<std::recursive_mutex
> lock
;
1246 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1248 if (exe_ctx
.HasThreadScope()) {
1249 if (exe_ctx
.GetThreadPtr()->DumpUsingFormat(
1250 strm
, LLDB_INVALID_THREAD_ID
, format
.GetFormatEntrySP().get())) {
1255 error
.SetErrorStringWithFormat(
1256 "It was not possible to generate a thread description with the given "
1257 "format string '%s'",
1258 format
.GetFormatEntrySP()->string
.c_str());
1262 SBThread
SBThread::GetExtendedBacktraceThread(const char *type
) {
1263 LLDB_INSTRUMENT_VA(this, type
);
1265 std::unique_lock
<std::recursive_mutex
> lock
;
1266 ExecutionContext
exe_ctx(m_opaque_sp
.get(), lock
);
1267 SBThread sb_origin_thread
;
1269 Process::StopLocker stop_locker
;
1270 if (stop_locker
.TryLock(&exe_ctx
.GetProcessPtr()->GetRunLock())) {
1271 if (exe_ctx
.HasThreadScope()) {
1272 ThreadSP
real_thread(exe_ctx
.GetThreadSP());
1274 ConstString
type_const(type
);
1275 Process
*process
= exe_ctx
.GetProcessPtr();
1277 SystemRuntime
*runtime
= process
->GetSystemRuntime();
1279 ThreadSP
new_thread_sp(
1280 runtime
->GetExtendedBacktraceThread(real_thread
, type_const
));
1281 if (new_thread_sp
) {
1282 // Save this in the Process' ExtendedThreadList so a strong
1283 // pointer retains the object.
1284 process
->GetExtendedThreadList().AddThread(new_thread_sp
);
1285 sb_origin_thread
.SetThread(new_thread_sp
);
1293 return sb_origin_thread
;
1296 uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
1297 LLDB_INSTRUMENT_VA(this);
1299 ThreadSP
thread_sp(m_opaque_sp
->GetThreadSP());
1301 return thread_sp
->GetExtendedBacktraceOriginatingIndexID();
1302 return LLDB_INVALID_INDEX32
;
1305 SBValue
SBThread::GetCurrentException() {
1306 LLDB_INSTRUMENT_VA(this);
1308 ThreadSP
thread_sp(m_opaque_sp
->GetThreadSP());
1312 return SBValue(thread_sp
->GetCurrentException());
1315 SBThread
SBThread::GetCurrentExceptionBacktrace() {
1316 LLDB_INSTRUMENT_VA(this);
1318 ThreadSP
thread_sp(m_opaque_sp
->GetThreadSP());
1322 return SBThread(thread_sp
->GetCurrentExceptionBacktrace());
1325 bool SBThread::SafeToCallFunctions() {
1326 LLDB_INSTRUMENT_VA(this);
1328 ThreadSP
thread_sp(m_opaque_sp
->GetThreadSP());
1330 return thread_sp
->SafeToCallFunctions();
1334 lldb_private::Thread
*SBThread::operator->() {
1338 lldb_private::Thread
*SBThread::get() {
1339 return m_opaque_sp
->GetThreadSP().get();
1342 SBValue
SBThread::GetSiginfo() {
1343 LLDB_INSTRUMENT_VA(this);
1345 ThreadSP thread_sp
= m_opaque_sp
->GetThreadSP();
1348 return thread_sp
->GetSiginfoValue();