Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / lldb / source / API / SBThread.cpp
blob15c909b0b46008f2cee9b4d2e539f34bbfddbac1
1 //===-- SBThread.cpp ------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "lldb/API/SBThread.h"
10 #include "Utils.h"
11 #include "lldb/API/SBAddress.h"
12 #include "lldb/API/SBDebugger.h"
13 #include "lldb/API/SBEvent.h"
14 #include "lldb/API/SBFileSpec.h"
15 #include "lldb/API/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"
47 #include <memory>
49 using namespace lldb;
50 using namespace lldb_private;
52 const char *SBThread::GetBroadcasterClassName() {
53 LLDB_INSTRUMENT();
55 return Thread::GetStaticBroadcasterClass().AsCString();
58 // Constructors
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);
79 if (this != &rhs)
80 m_opaque_sp = clone(rhs.m_opaque_sp);
81 return *this;
84 // Destructor
85 SBThread::~SBThread() = default;
87 lldb::SBQueue SBThread::GetQueue() const {
88 LLDB_INSTRUMENT_VA(this);
90 SBQueue sb_queue;
91 QueueSP queue_sp;
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();
99 if (queue_sp) {
100 sb_queue.SetQueue(queue_sp);
105 return sb_queue;
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.
126 return false;
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();
149 return reason;
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();
162 if (stop_info_sp) {
163 StopReason reason = stop_info_sp->GetStopReason();
164 switch (reason) {
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.
175 return 0;
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(
181 site_id));
182 if (bp_site_sp)
183 return bp_site_sp->GetNumberOfOwners() * 2;
184 else
185 return 0; // Breakpoint must have cleared itself...
186 } break;
188 case eStopReasonWatchpoint:
189 return 1;
191 case eStopReasonSignal:
192 return 1;
194 case eStopReasonException:
195 return 1;
197 case eStopReasonFork:
198 return 1;
200 case eStopReasonVFork:
201 return 1;
206 return 0;
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();
220 if (stop_info_sp) {
221 StopReason reason = stop_info_sp->GetStopReason();
222 switch (reason) {
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.
233 return 0;
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(
239 site_id));
240 if (bp_site_sp) {
241 uint32_t bp_index = idx / 2;
242 BreakpointLocationSP bp_loc_sp(
243 bp_site_sp->GetOwnerAtIndex(bp_index));
244 if (bp_loc_sp) {
245 if (idx & 1) {
246 // Odd idx, return the breakpoint location ID
247 return bp_loc_sp->GetID();
248 } else {
249 // Even idx, return the breakpoint ID
250 return bp_loc_sp->GetBreakpoint().GetID();
254 return LLDB_INVALID_BREAK_ID;
255 } break;
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();
275 return 0;
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())
287 return false;
289 StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
290 StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
291 if (!info)
292 return false;
294 info->Dump(strm);
296 return true;
299 SBThreadCollection
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();
315 if (!info)
316 return threads;
318 threads = process_sp->GetInstrumentationRuntime(type)
319 ->GetBacktracesFromExtendedStopInfo(info);
320 return threads;
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);
329 if (dst)
330 *dst = 0;
332 if (!exe_ctx.HasThreadScope())
333 return 0;
335 Process::StopLocker stop_locker;
336 if (!stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
337 return 0;
339 std::string thread_stop_desc = exe_ctx.GetThreadPtr()->GetStopDescription();
340 if (thread_stop_desc.empty())
341 return 0;
343 if (dst)
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
347 // description.
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();
362 if (stop_info_sp) {
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());
379 if (thread_sp)
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());
388 if (thread_sp)
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())
400 return nullptr;
402 Process::StopLocker stop_locker;
403 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
404 return ConstString(exe_ctx.GetThreadPtr()->GetName()).GetCString();
406 return nullptr;
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())
416 return nullptr;
418 Process::StopLocker stop_locker;
419 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
420 return ConstString(exe_ctx.GetThreadPtr()->GetQueueName()).GetCString();
422 return nullptr;
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();
439 return id;
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();
454 if (info_root_sp) {
455 StructuredData::ObjectSP node =
456 info_root_sp->GetObjectForDotSeparatedPath(path);
457 if (node) {
458 if (node->GetType() == eStructuredDataTypeString) {
459 strm.ref() << node->GetAsString()->GetValue();
460 success = true;
462 if (node->GetType() == eStructuredDataTypeInteger) {
463 strm.Printf("0x%" PRIx64, node->GetUnsignedIntegerValue());
464 success = true;
466 if (node->GetType() == eStructuredDataTypeFloat) {
467 strm.Printf("0x%f", node->GetAsFloat()->GetValue());
468 success = true;
470 if (node->GetType() == eStructuredDataTypeBoolean) {
471 if (node->GetAsBoolean()->GetValue())
472 strm.Printf("true");
473 else
474 strm.Printf("false");
475 success = true;
477 if (node->GetType() == eStructuredDataTypeNull) {
478 strm.Printf("null");
479 success = true;
486 return success;
489 SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
490 ThreadPlan *new_plan) {
491 SBError sb_error;
493 Process *process = exe_ctx.GetProcessPtr();
494 if (!process) {
495 sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
496 return sb_error;
499 Thread *thread = exe_ctx.GetThreadPtr();
500 if (!thread) {
501 sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
502 return sb_error;
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();
517 else
518 sb_error.ref() = process->ResumeSynchronous(nullptr);
520 return sb_error;
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");
538 return;
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;
547 if (frame_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);
554 } else {
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");
585 return;
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));
597 AddressRange range;
598 if (end_line == LLDB_INVALID_LINE_NUMBER)
599 range = sc.line_entry.range;
600 else {
601 if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
602 return;
605 const LazyBool step_out_avoids_code_without_debug_info =
606 eLazyBoolCalculate;
607 const LazyBool step_in_avoids_code_without_debug_info =
608 eLazyBoolCalculate;
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);
613 } else {
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());
620 else
621 error.SetErrorString(new_plan_status.AsCString());
624 void SBThread::StepOut() {
625 LLDB_INSTRUMENT_VA(this);
627 SBError error; // Ignored
628 StepOut(error);
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");
639 return;
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());
655 else
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");
674 return;
677 StackFrameSP frame_sp(sb_frame.GetFrameSP());
679 if (!exe_ctx.HasThreadScope()) {
680 error.SetErrorString("this SBThread object is invalid");
681 return;
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");
689 return;
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());
699 else
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");
718 return;
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());
728 else
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");
747 return;
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());
763 else
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);
771 SBError sb_error;
772 char path[PATH_MAX];
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();
783 if (line == 0) {
784 sb_error.SetErrorString("invalid line argument");
785 return sb_error;
788 if (!frame_sp) {
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
792 // recognized frame.
793 frame_sp = thread->GetSelectedFrame(DoNoSelectMostRelevantFrame);
794 if (!frame_sp)
795 frame_sp = thread->GetStackFrameAtIndex(0);
798 SymbolContext frame_sc;
799 if (!frame_sp) {
800 sb_error.SetErrorString("no valid frames in thread to step");
801 return sb_error;
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());
812 return sb_error;
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();
819 } else {
820 if (frame_sc.line_entry.IsValid())
821 step_file_spec = frame_sc.line_entry.file;
822 else {
823 sb_error.SetErrorString("invalid file argument or no file for frame");
824 return sb_error;
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) {
848 addr_t step_addr =
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);
853 else
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,
862 line);
863 } else
864 sb_error.SetErrorString("step until target not in current function");
865 } else {
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());
874 else
875 sb_error.SetErrorString(new_plan_status.AsCString());
877 } else {
878 sb_error.SetErrorString("this SBThread object is invalid");
880 return sb_error;
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,
895 resume_immediately);
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);
903 SBError error;
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");
910 return error;
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());
922 return error;
925 if (!resume_immediately)
926 return error;
928 if (new_plan_status.Success())
929 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
930 else
931 error.SetErrorString(new_plan_status.AsCString());
933 return error;
936 SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
937 LLDB_INSTRUMENT_VA(this, file_spec, line);
939 SBError sb_error;
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");
946 return sb_error;
949 Thread *thread = exe_ctx.GetThreadPtr();
951 Status err = thread->JumpToLine(file_spec.ref(), line, true);
952 sb_error.SetError(err);
953 return sb_error;
956 SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
957 LLDB_INSTRUMENT_VA(this, frame, return_value);
959 SBError sb_error;
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();
966 sb_error.SetError(
967 thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
970 return sb_error;
973 SBError SBThread::UnwindInnermostExpression() {
974 LLDB_INSTRUMENT_VA(this);
976 SBError sb_error;
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);
988 return sb_error;
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);
1009 result = true;
1010 } else {
1011 error.SetErrorString("process is running");
1013 } else
1014 error.SetErrorString("this SBThread object is invalid");
1015 return result;
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);
1037 result = true;
1038 } else {
1039 error.SetErrorString("process is running");
1041 } else
1042 error.SetErrorString("this SBThread object is invalid");
1043 return result;
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;
1054 return false;
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);
1065 return false;
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
1077 // process...
1078 sb_process.SetSP(exe_ctx.GetProcessSP());
1081 return sb_process;
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();
1098 return num_frames;
1101 SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
1102 LLDB_INSTRUMENT_VA(this, idx);
1104 SBFrame sb_frame;
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);
1117 return sb_frame;
1120 lldb::SBFrame SBThread::GetSelectedFrame() {
1121 LLDB_INSTRUMENT_VA(this);
1123 SBFrame sb_frame;
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())) {
1131 frame_sp =
1132 exe_ctx.GetThreadPtr()->GetSelectedFrame(SelectMostRelevantFrame);
1133 sb_frame.SetFrameSP(frame_sp);
1137 return sb_frame;
1140 lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
1141 LLDB_INSTRUMENT_VA(this, idx);
1143 SBFrame sb_frame;
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);
1153 if (frame_sp) {
1154 thread->SetSelectedFrame(frame_sp.get());
1155 sb_frame.SetFrameSP(frame_sp);
1160 return sb_frame;
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);
1205 } else
1206 strm.PutCString("No status");
1208 return true;
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,
1228 stop_format);
1229 // strm.Printf("SBThread: tid = 0x%4.4" PRIx64,
1230 // exe_ctx.GetThreadPtr()->GetID());
1231 } else
1232 strm.PutCString("No value");
1234 return true;
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());
1248 if (real_thread) {
1249 ConstString type_const(type);
1250 Process *process = exe_ctx.GetProcessPtr();
1251 if (process) {
1252 SystemRuntime *runtime = process->GetSystemRuntime();
1253 if (runtime) {
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());
1275 if (thread_sp)
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());
1284 if (!thread_sp)
1285 return SBValue();
1287 return SBValue(thread_sp->GetCurrentException());
1290 SBThread SBThread::GetCurrentExceptionBacktrace() {
1291 LLDB_INSTRUMENT_VA(this);
1293 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1294 if (!thread_sp)
1295 return SBThread();
1297 return SBThread(thread_sp->GetCurrentExceptionBacktrace());
1300 bool SBThread::SafeToCallFunctions() {
1301 LLDB_INSTRUMENT_VA(this);
1303 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1304 if (thread_sp)
1305 return thread_sp->SafeToCallFunctions();
1306 return true;
1309 lldb_private::Thread *SBThread::operator->() {
1310 return get();
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();
1321 if (!thread_sp)
1322 return SBValue();
1323 return thread_sp->GetSiginfoValue();