xref: /src/contrib/llvm-project/lldb/source/API/SBThread.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1cfca06d7SDimitry Andric //===-- SBThread.cpp ------------------------------------------------------===//
2f034231aSEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f034231aSEd Maste //
7f034231aSEd Maste //===----------------------------------------------------------------------===//
8f034231aSEd Maste 
9f034231aSEd Maste #include "lldb/API/SBThread.h"
105f29bb8aSDimitry Andric #include "Utils.h"
115f29bb8aSDimitry Andric #include "lldb/API/SBAddress.h"
125f29bb8aSDimitry Andric #include "lldb/API/SBDebugger.h"
135f29bb8aSDimitry Andric #include "lldb/API/SBEvent.h"
14f034231aSEd Maste #include "lldb/API/SBFileSpec.h"
15b1c73532SDimitry Andric #include "lldb/API/SBFormat.h"
165f29bb8aSDimitry Andric #include "lldb/API/SBFrame.h"
175f29bb8aSDimitry Andric #include "lldb/API/SBProcess.h"
18f034231aSEd Maste #include "lldb/API/SBStream.h"
19ead24645SDimitry Andric #include "lldb/API/SBStructuredData.h"
2014f1b3e8SDimitry Andric #include "lldb/API/SBSymbolContext.h"
215f29bb8aSDimitry Andric #include "lldb/API/SBThreadCollection.h"
225f29bb8aSDimitry Andric #include "lldb/API/SBThreadPlan.h"
235f29bb8aSDimitry Andric #include "lldb/API/SBValue.h"
24f034231aSEd Maste #include "lldb/Breakpoint/BreakpointLocation.h"
25f034231aSEd Maste #include "lldb/Core/Debugger.h"
26ead24645SDimitry Andric #include "lldb/Core/StructuredDataImpl.h"
275e95aa85SEd Maste #include "lldb/Core/ValueObject.h"
28f034231aSEd Maste #include "lldb/Interpreter/CommandInterpreter.h"
295e95aa85SEd Maste #include "lldb/Symbol/CompileUnit.h"
3014f1b3e8SDimitry Andric #include "lldb/Symbol/SymbolContext.h"
31f034231aSEd Maste #include "lldb/Target/Process.h"
320cac4ca3SEd Maste #include "lldb/Target/Queue.h"
33f034231aSEd Maste #include "lldb/Target/StopInfo.h"
3414f1b3e8SDimitry Andric #include "lldb/Target/SystemRuntime.h"
35f034231aSEd Maste #include "lldb/Target/Target.h"
3614f1b3e8SDimitry Andric #include "lldb/Target/Thread.h"
37f034231aSEd Maste #include "lldb/Target/ThreadPlan.h"
3814f1b3e8SDimitry Andric #include "lldb/Target/ThreadPlanStepInRange.h"
39f034231aSEd Maste #include "lldb/Target/ThreadPlanStepInstruction.h"
40f034231aSEd Maste #include "lldb/Target/ThreadPlanStepOut.h"
41f034231aSEd Maste #include "lldb/Target/ThreadPlanStepRange.h"
426f8fc217SDimitry Andric #include "lldb/Utility/Instrumentation.h"
4394994d37SDimitry Andric #include "lldb/Utility/State.h"
4474a628f7SDimitry Andric #include "lldb/Utility/Stream.h"
451b306c26SDimitry Andric #include "lldb/Utility/StructuredData.h"
4661b440f5SDimitry Andric #include "lldb/lldb-enumerations.h"
47f034231aSEd Maste 
485f29bb8aSDimitry Andric #include <memory>
495f29bb8aSDimitry Andric 
50f034231aSEd Maste using namespace lldb;
51f034231aSEd Maste using namespace lldb_private;
52f034231aSEd Maste 
GetBroadcasterClassName()5314f1b3e8SDimitry Andric const char *SBThread::GetBroadcasterClassName() {
546f8fc217SDimitry Andric   LLDB_INSTRUMENT();
555f29bb8aSDimitry Andric 
56ac9a064cSDimitry Andric   return ConstString(Thread::GetStaticBroadcasterClass()).AsCString();
57f034231aSEd Maste }
58f034231aSEd Maste 
59f034231aSEd Maste // Constructors
SBThread()605f29bb8aSDimitry Andric SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {
616f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
62f034231aSEd Maste }
63f034231aSEd Maste 
SBThread(const ThreadSP & lldb_object_sp)645f29bb8aSDimitry Andric SBThread::SBThread(const ThreadSP &lldb_object_sp)
655f29bb8aSDimitry Andric     : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {
666f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, lldb_object_sp);
675f29bb8aSDimitry Andric }
685f29bb8aSDimitry Andric 
SBThread(const SBThread & rhs)696f8fc217SDimitry Andric SBThread::SBThread(const SBThread &rhs) {
706f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, rhs);
715f29bb8aSDimitry Andric 
725f29bb8aSDimitry Andric   m_opaque_sp = clone(rhs.m_opaque_sp);
735f29bb8aSDimitry Andric }
745f29bb8aSDimitry Andric 
755f29bb8aSDimitry Andric // Assignment operator
765f29bb8aSDimitry Andric 
operator =(const SBThread & rhs)775f29bb8aSDimitry Andric const lldb::SBThread &SBThread::operator=(const SBThread &rhs) {
786f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, rhs);
795f29bb8aSDimitry Andric 
805f29bb8aSDimitry Andric   if (this != &rhs)
815f29bb8aSDimitry Andric     m_opaque_sp = clone(rhs.m_opaque_sp);
826f8fc217SDimitry Andric   return *this;
835f29bb8aSDimitry Andric }
845f29bb8aSDimitry Andric 
85f034231aSEd Maste // Destructor
86cfca06d7SDimitry Andric SBThread::~SBThread() = default;
87f034231aSEd Maste 
GetQueue() const8814f1b3e8SDimitry Andric lldb::SBQueue SBThread::GetQueue() const {
896f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
905f29bb8aSDimitry Andric 
910cac4ca3SEd Maste   SBQueue sb_queue;
920cac4ca3SEd Maste   QueueSP queue_sp;
93f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
94f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
950cac4ca3SEd Maste 
9614f1b3e8SDimitry Andric   if (exe_ctx.HasThreadScope()) {
970cac4ca3SEd Maste     Process::StopLocker stop_locker;
9814f1b3e8SDimitry Andric     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
990cac4ca3SEd Maste       queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
10014f1b3e8SDimitry Andric       if (queue_sp) {
1010cac4ca3SEd Maste         sb_queue.SetQueue(queue_sp);
1020cac4ca3SEd Maste       }
1030cac4ca3SEd Maste     }
1040cac4ca3SEd Maste   }
1050cac4ca3SEd Maste 
1066f8fc217SDimitry Andric   return sb_queue;
1070cac4ca3SEd Maste }
1080cac4ca3SEd Maste 
IsValid() const10914f1b3e8SDimitry Andric bool SBThread::IsValid() const {
1106f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
1115f29bb8aSDimitry Andric   return this->operator bool();
1125f29bb8aSDimitry Andric }
operator bool() const1135f29bb8aSDimitry Andric SBThread::operator bool() const {
1146f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
1155f29bb8aSDimitry Andric 
116f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
117f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
118f3fbd1c0SDimitry Andric 
119f3fbd1c0SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
120f3fbd1c0SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
12114f1b3e8SDimitry Andric   if (target && process) {
122f3fbd1c0SDimitry Andric     Process::StopLocker stop_locker;
123f3fbd1c0SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock()))
1245f29bb8aSDimitry Andric       return m_opaque_sp->GetThreadSP().get() != nullptr;
125f034231aSEd Maste   }
126f3fbd1c0SDimitry Andric   // Without a valid target & process, this thread can't be valid.
127f3fbd1c0SDimitry Andric   return false;
128f3fbd1c0SDimitry Andric }
129f034231aSEd Maste 
Clear()1305f29bb8aSDimitry Andric void SBThread::Clear() {
1316f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
1325f29bb8aSDimitry Andric 
1335f29bb8aSDimitry Andric   m_opaque_sp->Clear();
1345f29bb8aSDimitry Andric }
135f034231aSEd Maste 
GetStopReason()13614f1b3e8SDimitry Andric StopReason SBThread::GetStopReason() {
1376f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
138f034231aSEd Maste 
139f034231aSEd Maste   StopReason reason = eStopReasonInvalid;
140f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
141f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
142f034231aSEd Maste 
14314f1b3e8SDimitry Andric   if (exe_ctx.HasThreadScope()) {
144f034231aSEd Maste     Process::StopLocker stop_locker;
14514f1b3e8SDimitry Andric     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
146f034231aSEd Maste       return exe_ctx.GetThreadPtr()->GetStopReason();
147f034231aSEd Maste     }
148f034231aSEd Maste   }
149f034231aSEd Maste 
150f034231aSEd Maste   return reason;
151f034231aSEd Maste }
152f034231aSEd Maste 
GetStopReasonDataCount()15314f1b3e8SDimitry Andric size_t SBThread::GetStopReasonDataCount() {
1546f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
1555f29bb8aSDimitry Andric 
156f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
157f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
158f034231aSEd Maste 
15914f1b3e8SDimitry Andric   if (exe_ctx.HasThreadScope()) {
160f034231aSEd Maste     Process::StopLocker stop_locker;
16114f1b3e8SDimitry Andric     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
162f034231aSEd Maste       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
16314f1b3e8SDimitry Andric       if (stop_info_sp) {
164f034231aSEd Maste         StopReason reason = stop_info_sp->GetStopReason();
16514f1b3e8SDimitry Andric         switch (reason) {
166f034231aSEd Maste         case eStopReasonInvalid:
167f034231aSEd Maste         case eStopReasonNone:
168f034231aSEd Maste         case eStopReasonTrace:
169f034231aSEd Maste         case eStopReasonExec:
170f034231aSEd Maste         case eStopReasonPlanComplete:
171f034231aSEd Maste         case eStopReasonThreadExiting:
172205afe67SEd Maste         case eStopReasonInstrumentation:
173344a3780SDimitry Andric         case eStopReasonProcessorTrace:
174344a3780SDimitry Andric         case eStopReasonVForkDone:
175f034231aSEd Maste           // There is no data for these stop reasons.
176f034231aSEd Maste           return 0;
177f034231aSEd Maste 
17814f1b3e8SDimitry Andric         case eStopReasonBreakpoint: {
179f034231aSEd Maste           break_id_t site_id = stop_info_sp->GetValue();
18014f1b3e8SDimitry Andric           lldb::BreakpointSiteSP bp_site_sp(
18114f1b3e8SDimitry Andric               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
18214f1b3e8SDimitry Andric                   site_id));
183f034231aSEd Maste           if (bp_site_sp)
184b1c73532SDimitry Andric             return bp_site_sp->GetNumberOfConstituents() * 2;
185f034231aSEd Maste           else
186f034231aSEd Maste             return 0; // Breakpoint must have cleared itself...
18714f1b3e8SDimitry Andric         } break;
188f034231aSEd Maste 
189f034231aSEd Maste         case eStopReasonWatchpoint:
190f034231aSEd Maste           return 1;
191f034231aSEd Maste 
192f034231aSEd Maste         case eStopReasonSignal:
193f034231aSEd Maste           return 1;
194f034231aSEd Maste 
195f034231aSEd Maste         case eStopReasonException:
196f034231aSEd Maste           return 1;
197344a3780SDimitry Andric 
198344a3780SDimitry Andric         case eStopReasonFork:
199344a3780SDimitry Andric           return 1;
200344a3780SDimitry Andric 
201344a3780SDimitry Andric         case eStopReasonVFork:
202344a3780SDimitry Andric           return 1;
203f034231aSEd Maste         }
204f034231aSEd Maste       }
205f034231aSEd Maste     }
206f034231aSEd Maste   }
207f034231aSEd Maste   return 0;
208f034231aSEd Maste }
209f034231aSEd Maste 
GetStopReasonDataAtIndex(uint32_t idx)21014f1b3e8SDimitry Andric uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
2116f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, idx);
2125f29bb8aSDimitry Andric 
213f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
214f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
215f034231aSEd Maste 
21614f1b3e8SDimitry Andric   if (exe_ctx.HasThreadScope()) {
217f034231aSEd Maste     Process::StopLocker stop_locker;
21814f1b3e8SDimitry Andric     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
219f034231aSEd Maste       Thread *thread = exe_ctx.GetThreadPtr();
220f034231aSEd Maste       StopInfoSP stop_info_sp = thread->GetStopInfo();
22114f1b3e8SDimitry Andric       if (stop_info_sp) {
222f034231aSEd Maste         StopReason reason = stop_info_sp->GetStopReason();
22314f1b3e8SDimitry Andric         switch (reason) {
224f034231aSEd Maste         case eStopReasonInvalid:
225f034231aSEd Maste         case eStopReasonNone:
226f034231aSEd Maste         case eStopReasonTrace:
227f034231aSEd Maste         case eStopReasonExec:
228f034231aSEd Maste         case eStopReasonPlanComplete:
229f034231aSEd Maste         case eStopReasonThreadExiting:
230205afe67SEd Maste         case eStopReasonInstrumentation:
231344a3780SDimitry Andric         case eStopReasonProcessorTrace:
232344a3780SDimitry Andric         case eStopReasonVForkDone:
233f034231aSEd Maste           // There is no data for these stop reasons.
234f034231aSEd Maste           return 0;
235f034231aSEd Maste 
23614f1b3e8SDimitry Andric         case eStopReasonBreakpoint: {
237f034231aSEd Maste           break_id_t site_id = stop_info_sp->GetValue();
23814f1b3e8SDimitry Andric           lldb::BreakpointSiteSP bp_site_sp(
23914f1b3e8SDimitry Andric               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
24014f1b3e8SDimitry Andric                   site_id));
24114f1b3e8SDimitry Andric           if (bp_site_sp) {
242f034231aSEd Maste             uint32_t bp_index = idx / 2;
24314f1b3e8SDimitry Andric             BreakpointLocationSP bp_loc_sp(
244b1c73532SDimitry Andric                 bp_site_sp->GetConstituentAtIndex(bp_index));
24514f1b3e8SDimitry Andric             if (bp_loc_sp) {
24614f1b3e8SDimitry Andric               if (idx & 1) {
247f034231aSEd Maste                 // Odd idx, return the breakpoint location ID
248f034231aSEd Maste                 return bp_loc_sp->GetID();
24914f1b3e8SDimitry Andric               } else {
250f034231aSEd Maste                 // Even idx, return the breakpoint ID
251f034231aSEd Maste                 return bp_loc_sp->GetBreakpoint().GetID();
252f034231aSEd Maste               }
253f034231aSEd Maste             }
254f034231aSEd Maste           }
255f034231aSEd Maste           return LLDB_INVALID_BREAK_ID;
25614f1b3e8SDimitry Andric         } break;
257f034231aSEd Maste 
258f034231aSEd Maste         case eStopReasonWatchpoint:
259f034231aSEd Maste           return stop_info_sp->GetValue();
260f034231aSEd Maste 
261f034231aSEd Maste         case eStopReasonSignal:
262f034231aSEd Maste           return stop_info_sp->GetValue();
263f034231aSEd Maste 
264f034231aSEd Maste         case eStopReasonException:
265f034231aSEd Maste           return stop_info_sp->GetValue();
266344a3780SDimitry Andric 
267344a3780SDimitry Andric         case eStopReasonFork:
268344a3780SDimitry Andric           return stop_info_sp->GetValue();
269344a3780SDimitry Andric 
270344a3780SDimitry Andric         case eStopReasonVFork:
271344a3780SDimitry Andric           return stop_info_sp->GetValue();
272f034231aSEd Maste         }
273f034231aSEd Maste       }
274f034231aSEd Maste     }
275f034231aSEd Maste   }
276f034231aSEd Maste   return 0;
277f034231aSEd Maste }
278f034231aSEd Maste 
GetStopReasonExtendedInfoAsJSON(lldb::SBStream & stream)27914f1b3e8SDimitry Andric bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) {
2806f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, stream);
2815f29bb8aSDimitry Andric 
282205afe67SEd Maste   Stream &strm = stream.ref();
283205afe67SEd Maste 
284f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
285f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
286f3fbd1c0SDimitry Andric 
287205afe67SEd Maste   if (!exe_ctx.HasThreadScope())
288205afe67SEd Maste     return false;
289205afe67SEd Maste 
290205afe67SEd Maste   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
291205afe67SEd Maste   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
292205afe67SEd Maste   if (!info)
293205afe67SEd Maste     return false;
294205afe67SEd Maste 
295205afe67SEd Maste   info->Dump(strm);
296205afe67SEd Maste 
297205afe67SEd Maste   return true;
298205afe67SEd Maste }
299205afe67SEd Maste 
300f3fbd1c0SDimitry Andric SBThreadCollection
GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type)30114f1b3e8SDimitry Andric SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
3026f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, type);
3035f29bb8aSDimitry Andric 
304cfca06d7SDimitry Andric   SBThreadCollection threads;
305f3fbd1c0SDimitry Andric 
306f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
307f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
308f3fbd1c0SDimitry Andric 
309f3fbd1c0SDimitry Andric   if (!exe_ctx.HasThreadScope())
3106f8fc217SDimitry Andric     return SBThreadCollection();
311f3fbd1c0SDimitry Andric 
312f3fbd1c0SDimitry Andric   ProcessSP process_sp = exe_ctx.GetProcessSP();
313f3fbd1c0SDimitry Andric 
314f3fbd1c0SDimitry Andric   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
315f3fbd1c0SDimitry Andric   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
316f3fbd1c0SDimitry Andric   if (!info)
3176f8fc217SDimitry Andric     return threads;
318f3fbd1c0SDimitry Andric 
319cfca06d7SDimitry Andric   threads = process_sp->GetInstrumentationRuntime(type)
320cfca06d7SDimitry Andric                 ->GetBacktracesFromExtendedStopInfo(info);
3216f8fc217SDimitry Andric   return threads;
322f3fbd1c0SDimitry Andric }
323f3fbd1c0SDimitry Andric 
GetStopDescription(char * dst,size_t dst_len)32414f1b3e8SDimitry Andric size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
3256f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, dst, dst_len);
326f034231aSEd Maste 
327f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
328f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
329f034231aSEd Maste 
330f034231aSEd Maste   if (dst)
331f034231aSEd Maste     *dst = 0;
332cfca06d7SDimitry Andric 
333cfca06d7SDimitry Andric   if (!exe_ctx.HasThreadScope())
334f034231aSEd Maste     return 0;
335cfca06d7SDimitry Andric 
336cfca06d7SDimitry Andric   Process::StopLocker stop_locker;
337cfca06d7SDimitry Andric   if (!stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
338cfca06d7SDimitry Andric     return 0;
339cfca06d7SDimitry Andric 
340cfca06d7SDimitry Andric   std::string thread_stop_desc = exe_ctx.GetThreadPtr()->GetStopDescription();
341cfca06d7SDimitry Andric   if (thread_stop_desc.empty())
342cfca06d7SDimitry Andric     return 0;
343cfca06d7SDimitry Andric 
344cfca06d7SDimitry Andric   if (dst)
345cfca06d7SDimitry Andric     return ::snprintf(dst, dst_len, "%s", thread_stop_desc.c_str()) + 1;
346cfca06d7SDimitry Andric 
347cfca06d7SDimitry Andric   // NULL dst passed in, return the length needed to contain the
348cfca06d7SDimitry Andric   // description.
349cfca06d7SDimitry Andric   return thread_stop_desc.size() + 1; // Include the NULL byte for size
350f034231aSEd Maste }
351f034231aSEd Maste 
GetStopReturnValue()35214f1b3e8SDimitry Andric SBValue SBThread::GetStopReturnValue() {
3536f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
3545f29bb8aSDimitry Andric 
355f034231aSEd Maste   ValueObjectSP return_valobj_sp;
356f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
357f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
358f034231aSEd Maste 
35914f1b3e8SDimitry Andric   if (exe_ctx.HasThreadScope()) {
360f034231aSEd Maste     Process::StopLocker stop_locker;
36114f1b3e8SDimitry Andric     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
362f034231aSEd Maste       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
36314f1b3e8SDimitry Andric       if (stop_info_sp) {
364f034231aSEd Maste         return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp);
365f034231aSEd Maste       }
366f034231aSEd Maste     }
367f034231aSEd Maste   }
368f034231aSEd Maste 
3696f8fc217SDimitry Andric   return SBValue(return_valobj_sp);
370f034231aSEd Maste }
371f034231aSEd Maste 
SetThread(const ThreadSP & lldb_object_sp)37214f1b3e8SDimitry Andric void SBThread::SetThread(const ThreadSP &lldb_object_sp) {
373f034231aSEd Maste   m_opaque_sp->SetThreadSP(lldb_object_sp);
374f034231aSEd Maste }
375f034231aSEd Maste 
GetThreadID() const37614f1b3e8SDimitry Andric lldb::tid_t SBThread::GetThreadID() const {
3776f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
3785f29bb8aSDimitry Andric 
379f034231aSEd Maste   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
380f034231aSEd Maste   if (thread_sp)
381f034231aSEd Maste     return thread_sp->GetID();
382f034231aSEd Maste   return LLDB_INVALID_THREAD_ID;
383f034231aSEd Maste }
384f034231aSEd Maste 
GetIndexID() const38514f1b3e8SDimitry Andric uint32_t SBThread::GetIndexID() const {
3866f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
3875f29bb8aSDimitry Andric 
388f034231aSEd Maste   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
389f034231aSEd Maste   if (thread_sp)
390f034231aSEd Maste     return thread_sp->GetIndexID();
391f034231aSEd Maste   return LLDB_INVALID_INDEX32;
392f034231aSEd Maste }
393f034231aSEd Maste 
GetName() const39414f1b3e8SDimitry Andric const char *SBThread::GetName() const {
3956f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
3965f29bb8aSDimitry Andric 
397f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
398f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
399f034231aSEd Maste 
4007fa27ce4SDimitry Andric   if (!exe_ctx.HasThreadScope())
4017fa27ce4SDimitry Andric     return nullptr;
402f034231aSEd Maste 
4037fa27ce4SDimitry Andric   Process::StopLocker stop_locker;
4047fa27ce4SDimitry Andric   if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
4057fa27ce4SDimitry Andric     return ConstString(exe_ctx.GetThreadPtr()->GetName()).GetCString();
4067fa27ce4SDimitry Andric 
4077fa27ce4SDimitry Andric   return nullptr;
408f034231aSEd Maste }
409f034231aSEd Maste 
GetQueueName() const41014f1b3e8SDimitry Andric const char *SBThread::GetQueueName() const {
4116f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
4125f29bb8aSDimitry Andric 
413f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
414f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
415f034231aSEd Maste 
4167fa27ce4SDimitry Andric   if (!exe_ctx.HasThreadScope())
4177fa27ce4SDimitry Andric     return nullptr;
418f034231aSEd Maste 
4197fa27ce4SDimitry Andric   Process::StopLocker stop_locker;
4207fa27ce4SDimitry Andric   if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
4217fa27ce4SDimitry Andric     return ConstString(exe_ctx.GetThreadPtr()->GetQueueName()).GetCString();
4227fa27ce4SDimitry Andric 
4237fa27ce4SDimitry Andric   return nullptr;
424f034231aSEd Maste }
425f034231aSEd Maste 
GetQueueID() const42614f1b3e8SDimitry Andric lldb::queue_id_t SBThread::GetQueueID() const {
4276f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
4285f29bb8aSDimitry Andric 
429f21a844fSEd Maste   queue_id_t id = LLDB_INVALID_QUEUE_ID;
430f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
431f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
432f21a844fSEd Maste 
43314f1b3e8SDimitry Andric   if (exe_ctx.HasThreadScope()) {
434f21a844fSEd Maste     Process::StopLocker stop_locker;
43514f1b3e8SDimitry Andric     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
436f21a844fSEd Maste       id = exe_ctx.GetThreadPtr()->GetQueueID();
437f21a844fSEd Maste     }
438f21a844fSEd Maste   }
439f21a844fSEd Maste 
440f21a844fSEd Maste   return id;
441f21a844fSEd Maste }
442f21a844fSEd Maste 
GetInfoItemByPathAsString(const char * path,SBStream & strm)44314f1b3e8SDimitry Andric bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
4446f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, path, strm);
4455f29bb8aSDimitry Andric 
4460cac4ca3SEd Maste   bool success = false;
447f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
448f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4490cac4ca3SEd Maste 
45014f1b3e8SDimitry Andric   if (exe_ctx.HasThreadScope()) {
4510cac4ca3SEd Maste     Process::StopLocker stop_locker;
45214f1b3e8SDimitry Andric     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4530cac4ca3SEd Maste       Thread *thread = exe_ctx.GetThreadPtr();
4540cac4ca3SEd Maste       StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
45514f1b3e8SDimitry Andric       if (info_root_sp) {
45614f1b3e8SDimitry Andric         StructuredData::ObjectSP node =
45714f1b3e8SDimitry Andric             info_root_sp->GetObjectForDotSeparatedPath(path);
45814f1b3e8SDimitry Andric         if (node) {
45961b440f5SDimitry Andric           if (node->GetType() == eStructuredDataTypeString) {
4607fa27ce4SDimitry Andric             strm.ref() << node->GetAsString()->GetValue();
4610cac4ca3SEd Maste             success = true;
4620cac4ca3SEd Maste           }
46361b440f5SDimitry Andric           if (node->GetType() == eStructuredDataTypeInteger) {
4647fa27ce4SDimitry Andric             strm.Printf("0x%" PRIx64, node->GetUnsignedIntegerValue());
4650cac4ca3SEd Maste             success = true;
4660cac4ca3SEd Maste           }
46761b440f5SDimitry Andric           if (node->GetType() == eStructuredDataTypeFloat) {
4680cac4ca3SEd Maste             strm.Printf("0x%f", node->GetAsFloat()->GetValue());
4690cac4ca3SEd Maste             success = true;
4700cac4ca3SEd Maste           }
47161b440f5SDimitry Andric           if (node->GetType() == eStructuredDataTypeBoolean) {
47294994d37SDimitry Andric             if (node->GetAsBoolean()->GetValue())
4730cac4ca3SEd Maste               strm.Printf("true");
4740cac4ca3SEd Maste             else
4750cac4ca3SEd Maste               strm.Printf("false");
4760cac4ca3SEd Maste             success = true;
4770cac4ca3SEd Maste           }
47861b440f5SDimitry Andric           if (node->GetType() == eStructuredDataTypeNull) {
4790cac4ca3SEd Maste             strm.Printf("null");
4800cac4ca3SEd Maste             success = true;
4810cac4ca3SEd Maste           }
4820cac4ca3SEd Maste         }
4830cac4ca3SEd Maste       }
4840cac4ca3SEd Maste     }
4850cac4ca3SEd Maste   }
4860cac4ca3SEd Maste 
4870cac4ca3SEd Maste   return success;
4880cac4ca3SEd Maste }
4890cac4ca3SEd Maste 
ResumeNewPlan(ExecutionContext & exe_ctx,ThreadPlan * new_plan)49014f1b3e8SDimitry Andric SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
49114f1b3e8SDimitry Andric                                 ThreadPlan *new_plan) {
492f034231aSEd Maste   SBError sb_error;
493f034231aSEd Maste 
494f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
49514f1b3e8SDimitry Andric   if (!process) {
496f034231aSEd Maste     sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
497f034231aSEd Maste     return sb_error;
498f034231aSEd Maste   }
499f034231aSEd Maste 
500f034231aSEd Maste   Thread *thread = exe_ctx.GetThreadPtr();
50114f1b3e8SDimitry Andric   if (!thread) {
502f034231aSEd Maste     sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
503f034231aSEd Maste     return sb_error;
504f034231aSEd Maste   }
505f034231aSEd Maste 
506c0981da4SDimitry Andric   // User level plans should be Controlling Plans so they can be interrupted,
507c0981da4SDimitry Andric   // other plans executed, and then a "continue" will resume the plan.
5085f29bb8aSDimitry Andric   if (new_plan != nullptr) {
509c0981da4SDimitry Andric     new_plan->SetIsControllingPlan(true);
510f034231aSEd Maste     new_plan->SetOkayToDiscard(false);
511f034231aSEd Maste   }
512f034231aSEd Maste 
513f034231aSEd Maste   // Why do we need to set the current thread by ID here???
514f034231aSEd Maste   process->GetThreadList().SetSelectedThreadByID(thread->GetID());
515f034231aSEd Maste 
516205afe67SEd Maste   if (process->GetTarget().GetDebugger().GetAsyncExecution())
517205afe67SEd Maste     sb_error.ref() = process->Resume();
518205afe67SEd Maste   else
5195f29bb8aSDimitry Andric     sb_error.ref() = process->ResumeSynchronous(nullptr);
520f034231aSEd Maste 
521f034231aSEd Maste   return sb_error;
522f034231aSEd Maste }
523f034231aSEd Maste 
StepOver(lldb::RunMode stop_other_threads)52414f1b3e8SDimitry Andric void SBThread::StepOver(lldb::RunMode stop_other_threads) {
5256f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, stop_other_threads);
5265f29bb8aSDimitry Andric 
527f73363f1SDimitry Andric   SBError error; // Ignored
528f73363f1SDimitry Andric   StepOver(stop_other_threads, error);
529f73363f1SDimitry Andric }
530f73363f1SDimitry Andric 
StepOver(lldb::RunMode stop_other_threads,SBError & error)531f73363f1SDimitry Andric void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
5326f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, stop_other_threads, error);
533f034231aSEd Maste 
534f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
535f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
536f034231aSEd Maste 
537f73363f1SDimitry Andric   if (!exe_ctx.HasThreadScope()) {
538f73363f1SDimitry Andric     error.SetErrorString("this SBThread object is invalid");
539f73363f1SDimitry Andric     return;
540f73363f1SDimitry Andric   }
541f73363f1SDimitry Andric 
542f034231aSEd Maste   Thread *thread = exe_ctx.GetThreadPtr();
543f034231aSEd Maste   bool abort_other_plans = false;
544f034231aSEd Maste   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
545f034231aSEd Maste 
54694994d37SDimitry Andric   Status new_plan_status;
547f034231aSEd Maste   ThreadPlanSP new_plan_sp;
54814f1b3e8SDimitry Andric   if (frame_sp) {
54914f1b3e8SDimitry Andric     if (frame_sp->HasDebugInformation()) {
5500cac4ca3SEd Maste       const LazyBool avoid_no_debug = eLazyBoolCalculate;
551f034231aSEd Maste       SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
55214f1b3e8SDimitry Andric       new_plan_sp = thread->QueueThreadPlanForStepOverRange(
55314f1b3e8SDimitry Andric           abort_other_plans, sc.line_entry, sc, stop_other_threads,
55494994d37SDimitry Andric           new_plan_status, avoid_no_debug);
55514f1b3e8SDimitry Andric     } else {
55614f1b3e8SDimitry Andric       new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
55794994d37SDimitry Andric           true, abort_other_plans, stop_other_threads, new_plan_status);
558f034231aSEd Maste     }
559f034231aSEd Maste   }
560f73363f1SDimitry Andric   error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
561f034231aSEd Maste }
562f034231aSEd Maste 
StepInto(lldb::RunMode stop_other_threads)56314f1b3e8SDimitry Andric void SBThread::StepInto(lldb::RunMode stop_other_threads) {
5646f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, stop_other_threads);
5655f29bb8aSDimitry Andric 
5665f29bb8aSDimitry Andric   StepInto(nullptr, stop_other_threads);
567f034231aSEd Maste }
568f034231aSEd Maste 
StepInto(const char * target_name,lldb::RunMode stop_other_threads)56914f1b3e8SDimitry Andric void SBThread::StepInto(const char *target_name,
57014f1b3e8SDimitry Andric                         lldb::RunMode stop_other_threads) {
5716f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, target_name, stop_other_threads);
5725f29bb8aSDimitry Andric 
573f73363f1SDimitry Andric   SBError error; // Ignored
574f3fbd1c0SDimitry Andric   StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
575f3fbd1c0SDimitry Andric }
576f3fbd1c0SDimitry Andric 
StepInto(const char * target_name,uint32_t end_line,SBError & error,lldb::RunMode stop_other_threads)57714f1b3e8SDimitry Andric void SBThread::StepInto(const char *target_name, uint32_t end_line,
57814f1b3e8SDimitry Andric                         SBError &error, lldb::RunMode stop_other_threads) {
5796f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, target_name, end_line, error, stop_other_threads);
580f034231aSEd Maste 
581f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
582f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
583f034231aSEd Maste 
584f73363f1SDimitry Andric   if (!exe_ctx.HasThreadScope()) {
585f73363f1SDimitry Andric     error.SetErrorString("this SBThread object is invalid");
586f73363f1SDimitry Andric     return;
587f73363f1SDimitry Andric   }
588f73363f1SDimitry Andric 
589f034231aSEd Maste   bool abort_other_plans = false;
590f034231aSEd Maste 
591f034231aSEd Maste   Thread *thread = exe_ctx.GetThreadPtr();
592f034231aSEd Maste   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
593f034231aSEd Maste   ThreadPlanSP new_plan_sp;
59494994d37SDimitry Andric   Status new_plan_status;
595f034231aSEd Maste 
59614f1b3e8SDimitry Andric   if (frame_sp && frame_sp->HasDebugInformation()) {
597f3fbd1c0SDimitry Andric     SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
598f3fbd1c0SDimitry Andric     AddressRange range;
599f3fbd1c0SDimitry Andric     if (end_line == LLDB_INVALID_LINE_NUMBER)
600f3fbd1c0SDimitry Andric       range = sc.line_entry.range;
60114f1b3e8SDimitry Andric     else {
602f3fbd1c0SDimitry Andric       if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
603f3fbd1c0SDimitry Andric         return;
604f3fbd1c0SDimitry Andric     }
605f3fbd1c0SDimitry Andric 
60614f1b3e8SDimitry Andric     const LazyBool step_out_avoids_code_without_debug_info =
60714f1b3e8SDimitry Andric         eLazyBoolCalculate;
60814f1b3e8SDimitry Andric     const LazyBool step_in_avoids_code_without_debug_info =
60914f1b3e8SDimitry Andric         eLazyBoolCalculate;
61014f1b3e8SDimitry Andric     new_plan_sp = thread->QueueThreadPlanForStepInRange(
61114f1b3e8SDimitry Andric         abort_other_plans, range, sc, target_name, stop_other_threads,
61294994d37SDimitry Andric         new_plan_status, step_in_avoids_code_without_debug_info,
6130cac4ca3SEd Maste         step_out_avoids_code_without_debug_info);
61414f1b3e8SDimitry Andric   } else {
61514f1b3e8SDimitry Andric     new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
61694994d37SDimitry Andric         false, abort_other_plans, stop_other_threads, new_plan_status);
617f034231aSEd Maste   }
61894994d37SDimitry Andric 
61994994d37SDimitry Andric   if (new_plan_status.Success())
620f3fbd1c0SDimitry Andric     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
62194994d37SDimitry Andric   else
62294994d37SDimitry Andric     error.SetErrorString(new_plan_status.AsCString());
623f034231aSEd Maste }
624f034231aSEd Maste 
StepOut()62514f1b3e8SDimitry Andric void SBThread::StepOut() {
6266f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
6275f29bb8aSDimitry Andric 
628f73363f1SDimitry Andric   SBError error; // Ignored
629f73363f1SDimitry Andric   StepOut(error);
630f73363f1SDimitry Andric }
631f73363f1SDimitry Andric 
StepOut(SBError & error)632f73363f1SDimitry Andric void SBThread::StepOut(SBError &error) {
6336f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, error);
634f034231aSEd Maste 
635f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
636f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
637f034231aSEd Maste 
638f73363f1SDimitry Andric   if (!exe_ctx.HasThreadScope()) {
639f73363f1SDimitry Andric     error.SetErrorString("this SBThread object is invalid");
640f73363f1SDimitry Andric     return;
641f73363f1SDimitry Andric   }
642f73363f1SDimitry Andric 
643f034231aSEd Maste   bool abort_other_plans = false;
644f034231aSEd Maste   bool stop_other_threads = false;
645f034231aSEd Maste 
646f034231aSEd Maste   Thread *thread = exe_ctx.GetThreadPtr();
647f034231aSEd Maste 
6480cac4ca3SEd Maste   const LazyBool avoid_no_debug = eLazyBoolCalculate;
64994994d37SDimitry Andric   Status new_plan_status;
65014f1b3e8SDimitry Andric   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
6515f29bb8aSDimitry Andric       abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
65294994d37SDimitry Andric       eVoteNoOpinion, 0, new_plan_status, avoid_no_debug));
653f034231aSEd Maste 
65494994d37SDimitry Andric   if (new_plan_status.Success())
655f73363f1SDimitry Andric     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
65694994d37SDimitry Andric   else
65794994d37SDimitry Andric     error.SetErrorString(new_plan_status.AsCString());
658f034231aSEd Maste }
659f034231aSEd Maste 
StepOutOfFrame(SBFrame & sb_frame)660f73363f1SDimitry Andric void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
6616f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, sb_frame);
6625f29bb8aSDimitry Andric 
663f73363f1SDimitry Andric   SBError error; // Ignored
664f73363f1SDimitry Andric   StepOutOfFrame(sb_frame, error);
665f73363f1SDimitry Andric }
666f73363f1SDimitry Andric 
StepOutOfFrame(SBFrame & sb_frame,SBError & error)667f73363f1SDimitry Andric void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
6686f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, sb_frame, error);
669f034231aSEd Maste 
670f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
671f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
672f034231aSEd Maste 
67314f1b3e8SDimitry Andric   if (!sb_frame.IsValid()) {
674f73363f1SDimitry Andric     error.SetErrorString("passed invalid SBFrame object");
675e81d9d49SDimitry Andric     return;
676e81d9d49SDimitry Andric   }
677e81d9d49SDimitry Andric 
678f034231aSEd Maste   StackFrameSP frame_sp(sb_frame.GetFrameSP());
679f034231aSEd Maste 
680f73363f1SDimitry Andric   if (!exe_ctx.HasThreadScope()) {
681f73363f1SDimitry Andric     error.SetErrorString("this SBThread object is invalid");
682f73363f1SDimitry Andric     return;
683f73363f1SDimitry Andric   }
684f73363f1SDimitry Andric 
685f034231aSEd Maste   bool abort_other_plans = false;
686f034231aSEd Maste   bool stop_other_threads = false;
687f034231aSEd Maste   Thread *thread = exe_ctx.GetThreadPtr();
68814f1b3e8SDimitry Andric   if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
689f73363f1SDimitry Andric     error.SetErrorString("passed a frame from another thread");
690f73363f1SDimitry Andric     return;
691e81d9d49SDimitry Andric   }
692f034231aSEd Maste 
69394994d37SDimitry Andric   Status new_plan_status;
69414f1b3e8SDimitry Andric   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
6955f29bb8aSDimitry Andric       abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
69694994d37SDimitry Andric       eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status));
697f034231aSEd Maste 
69894994d37SDimitry Andric   if (new_plan_status.Success())
699f73363f1SDimitry Andric     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
70094994d37SDimitry Andric   else
70194994d37SDimitry Andric     error.SetErrorString(new_plan_status.AsCString());
702f034231aSEd Maste }
703f034231aSEd Maste 
StepInstruction(bool step_over)70414f1b3e8SDimitry Andric void SBThread::StepInstruction(bool step_over) {
7056f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, step_over);
7065f29bb8aSDimitry Andric 
707f73363f1SDimitry Andric   SBError error; // Ignored
708f73363f1SDimitry Andric   StepInstruction(step_over, error);
709f73363f1SDimitry Andric }
710f73363f1SDimitry Andric 
StepInstruction(bool step_over,SBError & error)711f73363f1SDimitry Andric void SBThread::StepInstruction(bool step_over, SBError &error) {
7126f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, step_over, error);
713f034231aSEd Maste 
714f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
715f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
716f034231aSEd Maste 
717f73363f1SDimitry Andric   if (!exe_ctx.HasThreadScope()) {
718f73363f1SDimitry Andric     error.SetErrorString("this SBThread object is invalid");
719f73363f1SDimitry Andric     return;
720f73363f1SDimitry Andric   }
721f73363f1SDimitry Andric 
722f034231aSEd Maste   Thread *thread = exe_ctx.GetThreadPtr();
72394994d37SDimitry Andric   Status new_plan_status;
72494994d37SDimitry Andric   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction(
725ac9a064cSDimitry Andric       step_over, false, true, new_plan_status));
726f034231aSEd Maste 
72794994d37SDimitry Andric   if (new_plan_status.Success())
728f73363f1SDimitry Andric     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
72994994d37SDimitry Andric   else
73094994d37SDimitry Andric     error.SetErrorString(new_plan_status.AsCString());
731f034231aSEd Maste }
732f034231aSEd Maste 
RunToAddress(lldb::addr_t addr)73314f1b3e8SDimitry Andric void SBThread::RunToAddress(lldb::addr_t addr) {
7346f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, addr);
7355f29bb8aSDimitry Andric 
736f73363f1SDimitry Andric   SBError error; // Ignored
737f73363f1SDimitry Andric   RunToAddress(addr, error);
738f73363f1SDimitry Andric }
739f73363f1SDimitry Andric 
RunToAddress(lldb::addr_t addr,SBError & error)740f73363f1SDimitry Andric void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
7416f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, addr, error);
742f034231aSEd Maste 
743f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
744f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
745f034231aSEd Maste 
746f73363f1SDimitry Andric   if (!exe_ctx.HasThreadScope()) {
747f73363f1SDimitry Andric     error.SetErrorString("this SBThread object is invalid");
748f73363f1SDimitry Andric     return;
749f73363f1SDimitry Andric   }
750f73363f1SDimitry Andric 
751f034231aSEd Maste   bool abort_other_plans = false;
752f034231aSEd Maste   bool stop_other_threads = true;
753f034231aSEd Maste 
754f034231aSEd Maste   Address target_addr(addr);
755f034231aSEd Maste 
756f034231aSEd Maste   Thread *thread = exe_ctx.GetThreadPtr();
757f034231aSEd Maste 
75894994d37SDimitry Andric   Status new_plan_status;
75914f1b3e8SDimitry Andric   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
76094994d37SDimitry Andric       abort_other_plans, target_addr, stop_other_threads, new_plan_status));
761f034231aSEd Maste 
76294994d37SDimitry Andric   if (new_plan_status.Success())
763f73363f1SDimitry Andric     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
76494994d37SDimitry Andric   else
76594994d37SDimitry Andric     error.SetErrorString(new_plan_status.AsCString());
766f034231aSEd Maste }
767f034231aSEd Maste 
StepOverUntil(lldb::SBFrame & sb_frame,lldb::SBFileSpec & sb_file_spec,uint32_t line)76814f1b3e8SDimitry Andric SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
76914f1b3e8SDimitry Andric                                 lldb::SBFileSpec &sb_file_spec, uint32_t line) {
7706f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, sb_frame, sb_file_spec, line);
7715f29bb8aSDimitry Andric 
772f034231aSEd Maste   SBError sb_error;
773f034231aSEd Maste   char path[PATH_MAX];
774f034231aSEd Maste 
775f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
776f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
777f034231aSEd Maste 
778f034231aSEd Maste   StackFrameSP frame_sp(sb_frame.GetFrameSP());
779f034231aSEd Maste 
78014f1b3e8SDimitry Andric   if (exe_ctx.HasThreadScope()) {
781f034231aSEd Maste     Target *target = exe_ctx.GetTargetPtr();
782f034231aSEd Maste     Thread *thread = exe_ctx.GetThreadPtr();
783f034231aSEd Maste 
78414f1b3e8SDimitry Andric     if (line == 0) {
785f034231aSEd Maste       sb_error.SetErrorString("invalid line argument");
7866f8fc217SDimitry Andric       return sb_error;
787f034231aSEd Maste     }
788f034231aSEd Maste 
78914f1b3e8SDimitry Andric     if (!frame_sp) {
7907fa27ce4SDimitry Andric       // We don't want to run SelectMostRelevantFrame here, for instance if
7917fa27ce4SDimitry Andric       // you called a sequence of StepOverUntil's you wouldn't want the
7927fa27ce4SDimitry Andric       // frame changed out from under you because you stepped into a
7937fa27ce4SDimitry Andric       // recognized frame.
7947fa27ce4SDimitry Andric       frame_sp = thread->GetSelectedFrame(DoNoSelectMostRelevantFrame);
795f034231aSEd Maste       if (!frame_sp)
796f034231aSEd Maste         frame_sp = thread->GetStackFrameAtIndex(0);
797f034231aSEd Maste     }
798f034231aSEd Maste 
799f034231aSEd Maste     SymbolContext frame_sc;
80014f1b3e8SDimitry Andric     if (!frame_sp) {
801f034231aSEd Maste       sb_error.SetErrorString("no valid frames in thread to step");
8026f8fc217SDimitry Andric       return sb_error;
803f034231aSEd Maste     }
804f034231aSEd Maste 
805f034231aSEd Maste     // If we have a frame, get its line
80614f1b3e8SDimitry Andric     frame_sc = frame_sp->GetSymbolContext(
80714f1b3e8SDimitry Andric         eSymbolContextCompUnit | eSymbolContextFunction |
80814f1b3e8SDimitry Andric         eSymbolContextLineEntry | eSymbolContextSymbol);
809f034231aSEd Maste 
8105f29bb8aSDimitry Andric     if (frame_sc.comp_unit == nullptr) {
81114f1b3e8SDimitry Andric       sb_error.SetErrorStringWithFormat(
81214f1b3e8SDimitry Andric           "frame %u doesn't have debug information", frame_sp->GetFrameIndex());
8136f8fc217SDimitry Andric       return sb_error;
814f034231aSEd Maste     }
815f034231aSEd Maste 
816f034231aSEd Maste     FileSpec step_file_spec;
81714f1b3e8SDimitry Andric     if (sb_file_spec.IsValid()) {
818f034231aSEd Maste       // The file spec passed in was valid, so use it
819f034231aSEd Maste       step_file_spec = sb_file_spec.ref();
82014f1b3e8SDimitry Andric     } else {
821f034231aSEd Maste       if (frame_sc.line_entry.IsValid())
822ac9a064cSDimitry Andric         step_file_spec = frame_sc.line_entry.GetFile();
82314f1b3e8SDimitry Andric       else {
824f034231aSEd Maste         sb_error.SetErrorString("invalid file argument or no file for frame");
8256f8fc217SDimitry Andric         return sb_error;
826f034231aSEd Maste       }
827f034231aSEd Maste     }
828f034231aSEd Maste 
829f034231aSEd Maste     // Grab the current function, then we will make sure the "until" address is
830f034231aSEd Maste     // within the function.  We discard addresses that are out of the current
83114f1b3e8SDimitry Andric     // function, and then if there are no addresses remaining, give an
832f73363f1SDimitry Andric     // appropriate error message.
833f034231aSEd Maste 
834f034231aSEd Maste     bool all_in_function = true;
835f034231aSEd Maste     AddressRange fun_range = frame_sc.function->GetAddressRange();
836f034231aSEd Maste 
837f034231aSEd Maste     std::vector<addr_t> step_over_until_addrs;
838f034231aSEd Maste     const bool abort_other_plans = false;
839f034231aSEd Maste     const bool stop_other_threads = false;
840344a3780SDimitry Andric     // TODO: Handle SourceLocationSpec column information
841344a3780SDimitry Andric     SourceLocationSpec location_spec(
842e3b55780SDimitry Andric         step_file_spec, line, /*column=*/std::nullopt, /*check_inlines=*/true,
843344a3780SDimitry Andric         /*exact_match=*/false);
844f034231aSEd Maste 
845f034231aSEd Maste     SymbolContextList sc_list;
846344a3780SDimitry Andric     frame_sc.comp_unit->ResolveSymbolContext(location_spec,
847706b4fc4SDimitry Andric                                              eSymbolContextLineEntry, sc_list);
8487fa27ce4SDimitry Andric     for (const SymbolContext &sc : sc_list) {
84914f1b3e8SDimitry Andric       addr_t step_addr =
85014f1b3e8SDimitry Andric           sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
85114f1b3e8SDimitry Andric       if (step_addr != LLDB_INVALID_ADDRESS) {
852f034231aSEd Maste         if (fun_range.ContainsLoadAddress(step_addr, target))
853f034231aSEd Maste           step_over_until_addrs.push_back(step_addr);
854f034231aSEd Maste         else
855f034231aSEd Maste           all_in_function = false;
856f034231aSEd Maste       }
857f034231aSEd Maste     }
858f034231aSEd Maste 
85914f1b3e8SDimitry Andric     if (step_over_until_addrs.empty()) {
86014f1b3e8SDimitry Andric       if (all_in_function) {
861f034231aSEd Maste         step_file_spec.GetPath(path, sizeof(path));
86214f1b3e8SDimitry Andric         sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path,
86314f1b3e8SDimitry Andric                                           line);
86414f1b3e8SDimitry Andric       } else
865f034231aSEd Maste         sb_error.SetErrorString("step until target not in current function");
86614f1b3e8SDimitry Andric     } else {
86794994d37SDimitry Andric       Status new_plan_status;
86814f1b3e8SDimitry Andric       ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil(
86914f1b3e8SDimitry Andric           abort_other_plans, &step_over_until_addrs[0],
87014f1b3e8SDimitry Andric           step_over_until_addrs.size(), stop_other_threads,
87194994d37SDimitry Andric           frame_sp->GetFrameIndex(), new_plan_status));
872f034231aSEd Maste 
87394994d37SDimitry Andric       if (new_plan_status.Success())
874f034231aSEd Maste         sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
87594994d37SDimitry Andric       else
87694994d37SDimitry Andric         sb_error.SetErrorString(new_plan_status.AsCString());
877f034231aSEd Maste     }
87814f1b3e8SDimitry Andric   } else {
879f034231aSEd Maste     sb_error.SetErrorString("this SBThread object is invalid");
880f034231aSEd Maste   }
8816f8fc217SDimitry Andric   return sb_error;
882f034231aSEd Maste }
883f034231aSEd Maste 
StepUsingScriptedThreadPlan(const char * script_class_name)88414f1b3e8SDimitry Andric SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) {
8856f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, script_class_name);
8865f29bb8aSDimitry Andric 
8876f8fc217SDimitry Andric   return StepUsingScriptedThreadPlan(script_class_name, true);
88814f1b3e8SDimitry Andric }
88914f1b3e8SDimitry Andric 
StepUsingScriptedThreadPlan(const char * script_class_name,bool resume_immediately)89014f1b3e8SDimitry Andric SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
89114f1b3e8SDimitry Andric                                             bool resume_immediately) {
8926f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, script_class_name, resume_immediately);
8935f29bb8aSDimitry Andric 
894ead24645SDimitry Andric   lldb::SBStructuredData no_data;
8956f8fc217SDimitry Andric   return StepUsingScriptedThreadPlan(script_class_name, no_data,
8966f8fc217SDimitry Andric                                      resume_immediately);
897ead24645SDimitry Andric }
898ead24645SDimitry Andric 
StepUsingScriptedThreadPlan(const char * script_class_name,SBStructuredData & args_data,bool resume_immediately)899ead24645SDimitry Andric SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
900ead24645SDimitry Andric                                               SBStructuredData &args_data,
901ead24645SDimitry Andric                                               bool resume_immediately) {
9026f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, script_class_name, args_data, resume_immediately);
903ead24645SDimitry Andric 
90494994d37SDimitry Andric   SBError error;
905205afe67SEd Maste 
906f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
907f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
908205afe67SEd Maste 
90914f1b3e8SDimitry Andric   if (!exe_ctx.HasThreadScope()) {
91094994d37SDimitry Andric     error.SetErrorString("this SBThread object is invalid");
9116f8fc217SDimitry Andric     return error;
912205afe67SEd Maste   }
913205afe67SEd Maste 
914205afe67SEd Maste   Thread *thread = exe_ctx.GetThreadPtr();
91594994d37SDimitry Andric   Status new_plan_status;
916ead24645SDimitry Andric   StructuredData::ObjectSP obj_sp = args_data.m_impl_up->GetObjectSP();
917ead24645SDimitry Andric 
91894994d37SDimitry Andric   ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted(
919ead24645SDimitry Andric       false, script_class_name, obj_sp, false, new_plan_status);
92014f1b3e8SDimitry Andric 
92194994d37SDimitry Andric   if (new_plan_status.Fail()) {
92294994d37SDimitry Andric     error.SetErrorString(new_plan_status.AsCString());
9236f8fc217SDimitry Andric     return error;
92414f1b3e8SDimitry Andric   }
92514f1b3e8SDimitry Andric 
92694994d37SDimitry Andric   if (!resume_immediately)
9276f8fc217SDimitry Andric     return error;
928205afe67SEd Maste 
92994994d37SDimitry Andric   if (new_plan_status.Success())
93094994d37SDimitry Andric     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
93194994d37SDimitry Andric   else
93294994d37SDimitry Andric     error.SetErrorString(new_plan_status.AsCString());
933205afe67SEd Maste 
9346f8fc217SDimitry Andric   return error;
935205afe67SEd Maste }
936205afe67SEd Maste 
JumpToLine(lldb::SBFileSpec & file_spec,uint32_t line)93714f1b3e8SDimitry Andric SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
9386f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, file_spec, line);
9395f29bb8aSDimitry Andric 
940f21a844fSEd Maste   SBError sb_error;
941f21a844fSEd Maste 
942f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
943f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
944f21a844fSEd Maste 
94514f1b3e8SDimitry Andric   if (!exe_ctx.HasThreadScope()) {
946f21a844fSEd Maste     sb_error.SetErrorString("this SBThread object is invalid");
9476f8fc217SDimitry Andric     return sb_error;
948f21a844fSEd Maste   }
949f21a844fSEd Maste 
950f21a844fSEd Maste   Thread *thread = exe_ctx.GetThreadPtr();
951f21a844fSEd Maste 
952706b4fc4SDimitry Andric   Status err = thread->JumpToLine(file_spec.ref(), line, true);
953f21a844fSEd Maste   sb_error.SetError(err);
9546f8fc217SDimitry Andric   return sb_error;
955f21a844fSEd Maste }
956f21a844fSEd Maste 
ReturnFromFrame(SBFrame & frame,SBValue & return_value)95714f1b3e8SDimitry Andric SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
9586f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, frame, return_value);
959f034231aSEd Maste 
9605f29bb8aSDimitry Andric   SBError sb_error;
961f034231aSEd Maste 
962f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
963f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
964f034231aSEd Maste 
96514f1b3e8SDimitry Andric   if (exe_ctx.HasThreadScope()) {
966f034231aSEd Maste     Thread *thread = exe_ctx.GetThreadPtr();
96714f1b3e8SDimitry Andric     sb_error.SetError(
96814f1b3e8SDimitry Andric         thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
969f034231aSEd Maste   }
970f034231aSEd Maste 
9716f8fc217SDimitry Andric   return sb_error;
972f034231aSEd Maste }
973f034231aSEd Maste 
UnwindInnermostExpression()97414f1b3e8SDimitry Andric SBError SBThread::UnwindInnermostExpression() {
9756f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
976f3fbd1c0SDimitry Andric 
9775f29bb8aSDimitry Andric   SBError sb_error;
978f3fbd1c0SDimitry Andric 
979f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
980f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
981f3fbd1c0SDimitry Andric 
98214f1b3e8SDimitry Andric   if (exe_ctx.HasThreadScope()) {
983f3fbd1c0SDimitry Andric     Thread *thread = exe_ctx.GetThreadPtr();
984f3fbd1c0SDimitry Andric     sb_error.SetError(thread->UnwindInnermostExpression());
985f3fbd1c0SDimitry Andric     if (sb_error.Success())
986f3fbd1c0SDimitry Andric       thread->SetSelectedFrameByIndex(0, false);
987f3fbd1c0SDimitry Andric   }
988f3fbd1c0SDimitry Andric 
9896f8fc217SDimitry Andric   return sb_error;
990f3fbd1c0SDimitry Andric }
991f034231aSEd Maste 
Suspend()99214f1b3e8SDimitry Andric bool SBThread::Suspend() {
9936f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
9945f29bb8aSDimitry Andric 
995f73363f1SDimitry Andric   SBError error; // Ignored
996f73363f1SDimitry Andric   return Suspend(error);
997f73363f1SDimitry Andric }
998f73363f1SDimitry Andric 
Suspend(SBError & error)999f73363f1SDimitry Andric bool SBThread::Suspend(SBError &error) {
10006f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, error);
10015f29bb8aSDimitry Andric 
1002f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1003f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1004f3fbd1c0SDimitry Andric 
1005f034231aSEd Maste   bool result = false;
100614f1b3e8SDimitry Andric   if (exe_ctx.HasThreadScope()) {
1007f034231aSEd Maste     Process::StopLocker stop_locker;
100814f1b3e8SDimitry Andric     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1009f034231aSEd Maste       exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
1010f034231aSEd Maste       result = true;
101114f1b3e8SDimitry Andric     } else {
1012f73363f1SDimitry Andric       error.SetErrorString("process is running");
1013f034231aSEd Maste     }
1014f73363f1SDimitry Andric   } else
1015f73363f1SDimitry Andric     error.SetErrorString("this SBThread object is invalid");
1016f034231aSEd Maste   return result;
1017f034231aSEd Maste }
1018f034231aSEd Maste 
Resume()101914f1b3e8SDimitry Andric bool SBThread::Resume() {
10206f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
10215f29bb8aSDimitry Andric 
1022f73363f1SDimitry Andric   SBError error; // Ignored
1023f73363f1SDimitry Andric   return Resume(error);
1024f73363f1SDimitry Andric }
1025f73363f1SDimitry Andric 
Resume(SBError & error)1026f73363f1SDimitry Andric bool SBThread::Resume(SBError &error) {
10276f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, error);
10285f29bb8aSDimitry Andric 
1029f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1030f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1031f3fbd1c0SDimitry Andric 
1032f034231aSEd Maste   bool result = false;
103314f1b3e8SDimitry Andric   if (exe_ctx.HasThreadScope()) {
1034f034231aSEd Maste     Process::StopLocker stop_locker;
103514f1b3e8SDimitry Andric     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
10360cac4ca3SEd Maste       const bool override_suspend = true;
10370cac4ca3SEd Maste       exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
1038f034231aSEd Maste       result = true;
103914f1b3e8SDimitry Andric     } else {
1040f73363f1SDimitry Andric       error.SetErrorString("process is running");
1041f034231aSEd Maste     }
1042f73363f1SDimitry Andric   } else
1043f73363f1SDimitry Andric     error.SetErrorString("this SBThread object is invalid");
1044f034231aSEd Maste   return result;
1045f034231aSEd Maste }
1046f034231aSEd Maste 
IsSuspended()104714f1b3e8SDimitry Andric bool SBThread::IsSuspended() {
10486f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
10495f29bb8aSDimitry Andric 
1050f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1051f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1052f3fbd1c0SDimitry Andric 
1053f034231aSEd Maste   if (exe_ctx.HasThreadScope())
1054f034231aSEd Maste     return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
1055f034231aSEd Maste   return false;
1056f034231aSEd Maste }
1057f034231aSEd Maste 
IsStopped()105814f1b3e8SDimitry Andric bool SBThread::IsStopped() {
10596f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
10605f29bb8aSDimitry Andric 
1061f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1062f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1063f3fbd1c0SDimitry Andric 
1064f034231aSEd Maste   if (exe_ctx.HasThreadScope())
1065f034231aSEd Maste     return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1066f034231aSEd Maste   return false;
1067f034231aSEd Maste }
1068f034231aSEd Maste 
GetProcess()106914f1b3e8SDimitry Andric SBProcess SBThread::GetProcess() {
10706f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
10715f29bb8aSDimitry Andric 
1072f034231aSEd Maste   SBProcess sb_process;
1073f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1074f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1075f3fbd1c0SDimitry Andric 
107614f1b3e8SDimitry Andric   if (exe_ctx.HasThreadScope()) {
107714f1b3e8SDimitry Andric     // Have to go up to the target so we can get a shared pointer to our
107814f1b3e8SDimitry Andric     // process...
1079f034231aSEd Maste     sb_process.SetSP(exe_ctx.GetProcessSP());
1080f034231aSEd Maste   }
1081f034231aSEd Maste 
10826f8fc217SDimitry Andric   return sb_process;
1083f034231aSEd Maste }
1084f034231aSEd Maste 
GetNumFrames()108514f1b3e8SDimitry Andric uint32_t SBThread::GetNumFrames() {
10866f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
1087f034231aSEd Maste 
1088f034231aSEd Maste   uint32_t num_frames = 0;
1089f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1090f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1091f034231aSEd Maste 
109214f1b3e8SDimitry Andric   if (exe_ctx.HasThreadScope()) {
1093f034231aSEd Maste     Process::StopLocker stop_locker;
109414f1b3e8SDimitry Andric     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1095f034231aSEd Maste       num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1096f034231aSEd Maste     }
1097f034231aSEd Maste   }
1098f034231aSEd Maste 
1099f034231aSEd Maste   return num_frames;
1100f034231aSEd Maste }
1101f034231aSEd Maste 
GetFrameAtIndex(uint32_t idx)110214f1b3e8SDimitry Andric SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
11036f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, idx);
1104f034231aSEd Maste 
1105f034231aSEd Maste   SBFrame sb_frame;
1106f034231aSEd Maste   StackFrameSP frame_sp;
1107f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1108f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1109f034231aSEd Maste 
111014f1b3e8SDimitry Andric   if (exe_ctx.HasThreadScope()) {
1111f034231aSEd Maste     Process::StopLocker stop_locker;
111214f1b3e8SDimitry Andric     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1113f034231aSEd Maste       frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
1114f034231aSEd Maste       sb_frame.SetFrameSP(frame_sp);
1115f034231aSEd Maste     }
1116f034231aSEd Maste   }
1117f034231aSEd Maste 
11186f8fc217SDimitry Andric   return sb_frame;
1119f034231aSEd Maste }
1120f034231aSEd Maste 
GetSelectedFrame()112114f1b3e8SDimitry Andric lldb::SBFrame SBThread::GetSelectedFrame() {
11226f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
1123f034231aSEd Maste 
1124f034231aSEd Maste   SBFrame sb_frame;
1125f034231aSEd Maste   StackFrameSP frame_sp;
1126f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1127f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1128f034231aSEd Maste 
112914f1b3e8SDimitry Andric   if (exe_ctx.HasThreadScope()) {
1130f034231aSEd Maste     Process::StopLocker stop_locker;
113114f1b3e8SDimitry Andric     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11327fa27ce4SDimitry Andric       frame_sp =
11337fa27ce4SDimitry Andric           exe_ctx.GetThreadPtr()->GetSelectedFrame(SelectMostRelevantFrame);
1134f034231aSEd Maste       sb_frame.SetFrameSP(frame_sp);
1135f034231aSEd Maste     }
1136f034231aSEd Maste   }
1137f034231aSEd Maste 
11386f8fc217SDimitry Andric   return sb_frame;
1139f034231aSEd Maste }
1140f034231aSEd Maste 
SetSelectedFrame(uint32_t idx)114114f1b3e8SDimitry Andric lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
11426f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, idx);
1143f034231aSEd Maste 
1144f034231aSEd Maste   SBFrame sb_frame;
1145f034231aSEd Maste   StackFrameSP frame_sp;
1146f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1147f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1148f034231aSEd Maste 
114914f1b3e8SDimitry Andric   if (exe_ctx.HasThreadScope()) {
1150f034231aSEd Maste     Process::StopLocker stop_locker;
115114f1b3e8SDimitry Andric     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1152f034231aSEd Maste       Thread *thread = exe_ctx.GetThreadPtr();
1153f034231aSEd Maste       frame_sp = thread->GetStackFrameAtIndex(idx);
115414f1b3e8SDimitry Andric       if (frame_sp) {
1155f034231aSEd Maste         thread->SetSelectedFrame(frame_sp.get());
1156f034231aSEd Maste         sb_frame.SetFrameSP(frame_sp);
1157f034231aSEd Maste       }
1158f034231aSEd Maste     }
1159f034231aSEd Maste   }
1160f034231aSEd Maste 
11616f8fc217SDimitry Andric   return sb_frame;
1162f034231aSEd Maste }
1163f034231aSEd Maste 
EventIsThreadEvent(const SBEvent & event)116414f1b3e8SDimitry Andric bool SBThread::EventIsThreadEvent(const SBEvent &event) {
11656f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(event);
11665f29bb8aSDimitry Andric 
11675f29bb8aSDimitry Andric   return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != nullptr;
1168f034231aSEd Maste }
1169f034231aSEd Maste 
GetStackFrameFromEvent(const SBEvent & event)117014f1b3e8SDimitry Andric SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) {
11716f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(event);
11725f29bb8aSDimitry Andric 
11736f8fc217SDimitry Andric   return Thread::ThreadEventData::GetStackFrameFromEvent(event.get());
1174f034231aSEd Maste }
1175f034231aSEd Maste 
GetThreadFromEvent(const SBEvent & event)117614f1b3e8SDimitry Andric SBThread SBThread::GetThreadFromEvent(const SBEvent &event) {
11776f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(event);
11785f29bb8aSDimitry Andric 
11796f8fc217SDimitry Andric   return Thread::ThreadEventData::GetThreadFromEvent(event.get());
1180f034231aSEd Maste }
1181f034231aSEd Maste 
operator ==(const SBThread & rhs) const118214f1b3e8SDimitry Andric bool SBThread::operator==(const SBThread &rhs) const {
11836f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, rhs);
11845f29bb8aSDimitry Andric 
118514f1b3e8SDimitry Andric   return m_opaque_sp->GetThreadSP().get() ==
118614f1b3e8SDimitry Andric          rhs.m_opaque_sp->GetThreadSP().get();
1187f034231aSEd Maste }
1188f034231aSEd Maste 
operator !=(const SBThread & rhs) const118914f1b3e8SDimitry Andric bool SBThread::operator!=(const SBThread &rhs) const {
11906f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, rhs);
11915f29bb8aSDimitry Andric 
119214f1b3e8SDimitry Andric   return m_opaque_sp->GetThreadSP().get() !=
119314f1b3e8SDimitry Andric          rhs.m_opaque_sp->GetThreadSP().get();
1194f034231aSEd Maste }
1195f034231aSEd Maste 
GetStatus(SBStream & status) const119614f1b3e8SDimitry Andric bool SBThread::GetStatus(SBStream &status) const {
11976f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, status);
11985f29bb8aSDimitry Andric 
1199f034231aSEd Maste   Stream &strm = status.ref();
1200f034231aSEd Maste 
1201f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1202f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1203f3fbd1c0SDimitry Andric 
120414f1b3e8SDimitry Andric   if (exe_ctx.HasThreadScope()) {
120514f1b3e8SDimitry Andric     exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true);
120614f1b3e8SDimitry Andric   } else
1207f034231aSEd Maste     strm.PutCString("No status");
1208f034231aSEd Maste 
1209f034231aSEd Maste   return true;
1210f034231aSEd Maste }
1211f034231aSEd Maste 
GetDescription(SBStream & description) const121214f1b3e8SDimitry Andric bool SBThread::GetDescription(SBStream &description) const {
12136f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, description);
12145f29bb8aSDimitry Andric 
121514f1b3e8SDimitry Andric   return GetDescription(description, false);
121614f1b3e8SDimitry Andric }
121714f1b3e8SDimitry Andric 
GetDescription(SBStream & description,bool stop_format) const121814f1b3e8SDimitry Andric bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
12196f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, description, stop_format);
12205f29bb8aSDimitry Andric 
1221f034231aSEd Maste   Stream &strm = description.ref();
1222f034231aSEd Maste 
1223f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1224f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1225f3fbd1c0SDimitry Andric 
122614f1b3e8SDimitry Andric   if (exe_ctx.HasThreadScope()) {
1227b1c73532SDimitry Andric     exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(
1228b1c73532SDimitry Andric         strm, LLDB_INVALID_THREAD_ID, stop_format);
122914f1b3e8SDimitry Andric   } else
1230f034231aSEd Maste     strm.PutCString("No value");
1231f034231aSEd Maste 
1232f034231aSEd Maste   return true;
1233f034231aSEd Maste }
1234f21a844fSEd Maste 
GetDescriptionWithFormat(const SBFormat & format,SBStream & output)1235b1c73532SDimitry Andric SBError SBThread::GetDescriptionWithFormat(const SBFormat &format,
1236b1c73532SDimitry Andric                                            SBStream &output) {
1237b1c73532SDimitry Andric   Stream &strm = output.ref();
1238b1c73532SDimitry Andric 
1239b1c73532SDimitry Andric   SBError error;
1240b1c73532SDimitry Andric   if (!format) {
1241b1c73532SDimitry Andric     error.SetErrorString("The provided SBFormat object is invalid");
1242b1c73532SDimitry Andric     return error;
1243b1c73532SDimitry Andric   }
1244b1c73532SDimitry Andric 
1245b1c73532SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1246b1c73532SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1247b1c73532SDimitry Andric 
1248b1c73532SDimitry Andric   if (exe_ctx.HasThreadScope()) {
1249b1c73532SDimitry Andric     if (exe_ctx.GetThreadPtr()->DumpUsingFormat(
1250b1c73532SDimitry Andric             strm, LLDB_INVALID_THREAD_ID, format.GetFormatEntrySP().get())) {
1251b1c73532SDimitry Andric       return error;
1252b1c73532SDimitry Andric     }
1253b1c73532SDimitry Andric   }
1254b1c73532SDimitry Andric 
1255b1c73532SDimitry Andric   error.SetErrorStringWithFormat(
1256b1c73532SDimitry Andric       "It was not possible to generate a thread description with the given "
1257b1c73532SDimitry Andric       "format string '%s'",
1258b1c73532SDimitry Andric       format.GetFormatEntrySP()->string.c_str());
1259b1c73532SDimitry Andric   return error;
1260b1c73532SDimitry Andric }
1261b1c73532SDimitry Andric 
GetExtendedBacktraceThread(const char * type)126214f1b3e8SDimitry Andric SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
12636f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, type);
12645f29bb8aSDimitry Andric 
1265f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1266f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1267f21a844fSEd Maste   SBThread sb_origin_thread;
1268f21a844fSEd Maste 
1269f21a844fSEd Maste   Process::StopLocker stop_locker;
127014f1b3e8SDimitry Andric   if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
12715f29bb8aSDimitry Andric     if (exe_ctx.HasThreadScope()) {
127286758c71SEd Maste       ThreadSP real_thread(exe_ctx.GetThreadSP());
127314f1b3e8SDimitry Andric       if (real_thread) {
1274f21a844fSEd Maste         ConstString type_const(type);
127586758c71SEd Maste         Process *process = exe_ctx.GetProcessPtr();
127614f1b3e8SDimitry Andric         if (process) {
127786758c71SEd Maste           SystemRuntime *runtime = process->GetSystemRuntime();
127814f1b3e8SDimitry Andric           if (runtime) {
127914f1b3e8SDimitry Andric             ThreadSP new_thread_sp(
128014f1b3e8SDimitry Andric                 runtime->GetExtendedBacktraceThread(real_thread, type_const));
128114f1b3e8SDimitry Andric             if (new_thread_sp) {
128214f1b3e8SDimitry Andric               // Save this in the Process' ExtendedThreadList so a strong
1283f73363f1SDimitry Andric               // pointer retains the object.
128486758c71SEd Maste               process->GetExtendedThreadList().AddThread(new_thread_sp);
128586758c71SEd Maste               sb_origin_thread.SetThread(new_thread_sp);
128686758c71SEd Maste             }
128786758c71SEd Maste           }
128886758c71SEd Maste         }
1289f21a844fSEd Maste       }
1290f21a844fSEd Maste     }
1291f21a844fSEd Maste   }
1292f21a844fSEd Maste 
12936f8fc217SDimitry Andric   return sb_origin_thread;
1294f21a844fSEd Maste }
129586758c71SEd Maste 
GetExtendedBacktraceOriginatingIndexID()129614f1b3e8SDimitry Andric uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
12976f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
12985f29bb8aSDimitry Andric 
129986758c71SEd Maste   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
130086758c71SEd Maste   if (thread_sp)
130186758c71SEd Maste     return thread_sp->GetExtendedBacktraceOriginatingIndexID();
130286758c71SEd Maste   return LLDB_INVALID_INDEX32;
130386758c71SEd Maste }
13040cac4ca3SEd Maste 
GetCurrentException()130594994d37SDimitry Andric SBValue SBThread::GetCurrentException() {
13066f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
130794994d37SDimitry Andric 
13085f29bb8aSDimitry Andric   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
13095f29bb8aSDimitry Andric   if (!thread_sp)
13106f8fc217SDimitry Andric     return SBValue();
13115f29bb8aSDimitry Andric 
13126f8fc217SDimitry Andric   return SBValue(thread_sp->GetCurrentException());
131394994d37SDimitry Andric }
131494994d37SDimitry Andric 
GetCurrentExceptionBacktrace()131594994d37SDimitry Andric SBThread SBThread::GetCurrentExceptionBacktrace() {
13166f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
131794994d37SDimitry Andric 
13185f29bb8aSDimitry Andric   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
13195f29bb8aSDimitry Andric   if (!thread_sp)
13206f8fc217SDimitry Andric     return SBThread();
13215f29bb8aSDimitry Andric 
13226f8fc217SDimitry Andric   return SBThread(thread_sp->GetCurrentExceptionBacktrace());
132394994d37SDimitry Andric }
132494994d37SDimitry Andric 
SafeToCallFunctions()132514f1b3e8SDimitry Andric bool SBThread::SafeToCallFunctions() {
13266f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
13275f29bb8aSDimitry Andric 
13280cac4ca3SEd Maste   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
13290cac4ca3SEd Maste   if (thread_sp)
13300cac4ca3SEd Maste     return thread_sp->SafeToCallFunctions();
13310cac4ca3SEd Maste   return true;
13320cac4ca3SEd Maste }
1333205afe67SEd Maste 
operator ->()133414f1b3e8SDimitry Andric lldb_private::Thread *SBThread::operator->() {
13355f29bb8aSDimitry Andric   return get();
1336205afe67SEd Maste }
1337205afe67SEd Maste 
get()133814f1b3e8SDimitry Andric lldb_private::Thread *SBThread::get() {
13395f29bb8aSDimitry Andric   return m_opaque_sp->GetThreadSP().get();
13405f29bb8aSDimitry Andric }
13415f29bb8aSDimitry Andric 
GetSiginfo()1342ecbca9f5SDimitry Andric SBValue SBThread::GetSiginfo() {
1343ecbca9f5SDimitry Andric   LLDB_INSTRUMENT_VA(this);
13445f29bb8aSDimitry Andric 
13456f8fc217SDimitry Andric   ThreadSP thread_sp = m_opaque_sp->GetThreadSP();
1346ecbca9f5SDimitry Andric   if (!thread_sp)
1347ecbca9f5SDimitry Andric     return SBValue();
1348ecbca9f5SDimitry Andric   return thread_sp->GetSiginfoValue();
1349205afe67SEd Maste }
1350