130fdc8d8SChris Lattner //===-- SBThread.cpp --------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner 
94c5de699SEli Friedman #include "lldb/API/SBThread.h"
10baf5664fSJonas Devlieghere #include "SBReproducerPrivate.h"
11bd4bf82aSJonas Devlieghere #include "Utils.h"
12bd4bf82aSJonas Devlieghere #include "lldb/API/SBAddress.h"
13bd4bf82aSJonas Devlieghere #include "lldb/API/SBDebugger.h"
14bd4bf82aSJonas Devlieghere #include "lldb/API/SBEvent.h"
1530fdc8d8SChris Lattner #include "lldb/API/SBFileSpec.h"
16bd4bf82aSJonas Devlieghere #include "lldb/API/SBFrame.h"
17bd4bf82aSJonas Devlieghere #include "lldb/API/SBProcess.h"
18dde9cff3SCaroline Tice #include "lldb/API/SBStream.h"
19b9c1b51eSKate Stone #include "lldb/API/SBSymbolContext.h"
20bd4bf82aSJonas Devlieghere #include "lldb/API/SBThreadCollection.h"
21bd4bf82aSJonas Devlieghere #include "lldb/API/SBThreadPlan.h"
22bd4bf82aSJonas Devlieghere #include "lldb/API/SBValue.h"
234e78f606SGreg Clayton #include "lldb/Breakpoint/BreakpointLocation.h"
246611103cSGreg Clayton #include "lldb/Core/Debugger.h"
2530fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h"
26a78bd7ffSZachary Turner #include "lldb/Core/ValueObject.h"
276611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
2893749ab3SZachary Turner #include "lldb/Symbol/CompileUnit.h"
29b9c1b51eSKate Stone #include "lldb/Symbol/SymbolContext.h"
3030fdc8d8SChris Lattner #include "lldb/Target/Process.h"
31b9ffa98cSJason Molenda #include "lldb/Target/Queue.h"
32f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h"
33b9c1b51eSKate Stone #include "lldb/Target/SystemRuntime.h"
3430fdc8d8SChris Lattner #include "lldb/Target/Target.h"
35b9c1b51eSKate Stone #include "lldb/Target/Thread.h"
3630fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h"
37b9c1b51eSKate Stone #include "lldb/Target/ThreadPlanStepInRange.h"
3830fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h"
3930fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h"
4030fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h"
41b9c1b51eSKate Stone #include "lldb/Target/UnixSignals.h"
42d821c997SPavel Labath #include "lldb/Utility/State.h"
43bf9a7730SZachary Turner #include "lldb/Utility/Stream.h"
44f2a8bccfSPavel Labath #include "lldb/Utility/StructuredData.h"
455bfee5f1SAbhishek Aggarwal #include "lldb/lldb-enumerations.h"
4630fdc8d8SChris Lattner 
47796ac80bSJonas Devlieghere #include <memory>
48796ac80bSJonas Devlieghere 
4930fdc8d8SChris Lattner using namespace lldb;
5030fdc8d8SChris Lattner using namespace lldb_private;
5130fdc8d8SChris Lattner 
52b9c1b51eSKate Stone const char *SBThread::GetBroadcasterClassName() {
53baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBThread,
54baf5664fSJonas Devlieghere                                     GetBroadcasterClassName);
55baf5664fSJonas Devlieghere 
564f465cffSJim Ingham   return Thread::GetStaticBroadcasterClass().AsCString();
574f465cffSJim Ingham }
584f465cffSJim Ingham 
59cfd1acedSGreg Clayton // Constructors
60baf5664fSJonas Devlieghere SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {
61baf5664fSJonas Devlieghere   LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBThread);
62baf5664fSJonas Devlieghere }
6330fdc8d8SChris Lattner 
64b9c1b51eSKate Stone SBThread::SBThread(const ThreadSP &lldb_object_sp)
65baf5664fSJonas Devlieghere     : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {
66baf5664fSJonas Devlieghere   LLDB_RECORD_CONSTRUCTOR(SBThread, (const lldb::ThreadSP &), lldb_object_sp);
67baf5664fSJonas Devlieghere }
6830fdc8d8SChris Lattner 
69bd4bf82aSJonas Devlieghere SBThread::SBThread(const SBThread &rhs) : m_opaque_sp() {
70baf5664fSJonas Devlieghere   LLDB_RECORD_CONSTRUCTOR(SBThread, (const lldb::SBThread &), rhs);
71baf5664fSJonas Devlieghere 
72bd4bf82aSJonas Devlieghere   m_opaque_sp = clone(rhs.m_opaque_sp);
73bd4bf82aSJonas Devlieghere }
7430fdc8d8SChris Lattner 
75cfd1acedSGreg Clayton // Assignment operator
76cfd1acedSGreg Clayton 
77b9c1b51eSKate Stone const lldb::SBThread &SBThread::operator=(const SBThread &rhs) {
78baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(const lldb::SBThread &,
79baf5664fSJonas Devlieghere                      SBThread, operator=,(const lldb::SBThread &), rhs);
80baf5664fSJonas Devlieghere 
81cfd1acedSGreg Clayton   if (this != &rhs)
82bd4bf82aSJonas Devlieghere     m_opaque_sp = clone(rhs.m_opaque_sp);
83306809f2SJonas Devlieghere   return LLDB_RECORD_RESULT(*this);
84cfd1acedSGreg Clayton }
85cfd1acedSGreg Clayton 
8630fdc8d8SChris Lattner // Destructor
87b9c1b51eSKate Stone SBThread::~SBThread() {}
8830fdc8d8SChris Lattner 
89b9c1b51eSKate Stone lldb::SBQueue SBThread::GetQueue() const {
90baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBQueue, SBThread, GetQueue);
91baf5664fSJonas Devlieghere 
92b9ffa98cSJason Molenda   SBQueue sb_queue;
93b9ffa98cSJason Molenda   QueueSP queue_sp;
94bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
95bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
96b9ffa98cSJason Molenda 
97b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
98b9ffa98cSJason Molenda     Process::StopLocker stop_locker;
99b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
100b9ffa98cSJason Molenda       queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
101b9c1b51eSKate Stone       if (queue_sp) {
102b9ffa98cSJason Molenda         sb_queue.SetQueue(queue_sp);
103b9ffa98cSJason Molenda       }
104b9ffa98cSJason Molenda     }
105b9ffa98cSJason Molenda   }
106b9ffa98cSJason Molenda 
107baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_queue);
108b9ffa98cSJason Molenda }
109b9ffa98cSJason Molenda 
110b9c1b51eSKate Stone bool SBThread::IsValid() const {
111baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThread, IsValid);
1127f5237bcSPavel Labath   return this->operator bool();
1137f5237bcSPavel Labath }
1147f5237bcSPavel Labath SBThread::operator bool() const {
1157f5237bcSPavel Labath   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThread, operator bool);
116baf5664fSJonas Devlieghere 
117bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
118bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1197fa7dc36SJim Ingham 
1207fa7dc36SJim Ingham   Target *target = exe_ctx.GetTargetPtr();
1217fa7dc36SJim Ingham   Process *process = exe_ctx.GetProcessPtr();
122b9c1b51eSKate Stone   if (target && process) {
1237fa7dc36SJim Ingham     Process::StopLocker stop_locker;
1247fa7dc36SJim Ingham     if (stop_locker.TryLock(&process->GetRunLock()))
125*248a1305SKonrad Kleine       return m_opaque_sp->GetThreadSP().get() != nullptr;
12630fdc8d8SChris Lattner   }
1277fa7dc36SJim Ingham   // Without a valid target & process, this thread can't be valid.
1287fa7dc36SJim Ingham   return false;
1297fa7dc36SJim Ingham }
13030fdc8d8SChris Lattner 
131baf5664fSJonas Devlieghere void SBThread::Clear() {
132baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(void, SBThread, Clear);
133baf5664fSJonas Devlieghere 
134baf5664fSJonas Devlieghere   m_opaque_sp->Clear();
135baf5664fSJonas Devlieghere }
13648e42549SGreg Clayton 
137b9c1b51eSKate Stone StopReason SBThread::GetStopReason() {
138baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::StopReason, SBThread, GetStopReason);
139baf5664fSJonas Devlieghere 
140ceb6b139SCaroline Tice   StopReason reason = eStopReasonInvalid;
141bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
142bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1434fc6cb9cSJim Ingham 
144b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1457fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
146b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
14797d5cf05SGreg Clayton       return exe_ctx.GetThreadPtr()->GetStopReason();
148c9858e4dSGreg Clayton     }
1497fdf9ef1SGreg Clayton   }
150ceb6b139SCaroline Tice 
151ceb6b139SCaroline Tice   return reason;
15230fdc8d8SChris Lattner }
15330fdc8d8SChris Lattner 
154b9c1b51eSKate Stone size_t SBThread::GetStopReasonDataCount() {
155baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(size_t, SBThread, GetStopReasonDataCount);
156baf5664fSJonas Devlieghere 
157bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
158bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1594fc6cb9cSJim Ingham 
160b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1617fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
162b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1631ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
164b9c1b51eSKate Stone       if (stop_info_sp) {
1654e78f606SGreg Clayton         StopReason reason = stop_info_sp->GetStopReason();
166b9c1b51eSKate Stone         switch (reason) {
1674e78f606SGreg Clayton         case eStopReasonInvalid:
1684e78f606SGreg Clayton         case eStopReasonNone:
1694e78f606SGreg Clayton         case eStopReasonTrace:
17090ba8115SGreg Clayton         case eStopReasonExec:
1714e78f606SGreg Clayton         case eStopReasonPlanComplete:
172f85defaeSAndrew Kaylor         case eStopReasonThreadExiting:
173afdf842bSKuba Brecka         case eStopReasonInstrumentation:
1744e78f606SGreg Clayton           // There is no data for these stop reasons.
1754e78f606SGreg Clayton           return 0;
1764e78f606SGreg Clayton 
177b9c1b51eSKate Stone         case eStopReasonBreakpoint: {
1784e78f606SGreg Clayton           break_id_t site_id = stop_info_sp->GetValue();
179b9c1b51eSKate Stone           lldb::BreakpointSiteSP bp_site_sp(
180b9c1b51eSKate Stone               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
181b9c1b51eSKate Stone                   site_id));
1824e78f606SGreg Clayton           if (bp_site_sp)
1834e78f606SGreg Clayton             return bp_site_sp->GetNumberOfOwners() * 2;
1844e78f606SGreg Clayton           else
1854e78f606SGreg Clayton             return 0; // Breakpoint must have cleared itself...
186b9c1b51eSKate Stone         } break;
1874e78f606SGreg Clayton 
1884e78f606SGreg Clayton         case eStopReasonWatchpoint:
189290fa41bSJohnny Chen           return 1;
1904e78f606SGreg Clayton 
1914e78f606SGreg Clayton         case eStopReasonSignal:
1924e78f606SGreg Clayton           return 1;
1934e78f606SGreg Clayton 
1944e78f606SGreg Clayton         case eStopReasonException:
1954e78f606SGreg Clayton           return 1;
1964e78f606SGreg Clayton         }
1974e78f606SGreg Clayton       }
198c9858e4dSGreg Clayton     }
1997fdf9ef1SGreg Clayton   }
2004e78f606SGreg Clayton   return 0;
2014e78f606SGreg Clayton }
2024e78f606SGreg Clayton 
203b9c1b51eSKate Stone uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
204baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(uint64_t, SBThread, GetStopReasonDataAtIndex, (uint32_t),
205baf5664fSJonas Devlieghere                      idx);
206baf5664fSJonas Devlieghere 
207bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
208bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
2094fc6cb9cSJim Ingham 
210b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
2117fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
212b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
2131ac04c30SGreg Clayton       Thread *thread = exe_ctx.GetThreadPtr();
2141ac04c30SGreg Clayton       StopInfoSP stop_info_sp = thread->GetStopInfo();
215b9c1b51eSKate Stone       if (stop_info_sp) {
2164e78f606SGreg Clayton         StopReason reason = stop_info_sp->GetStopReason();
217b9c1b51eSKate Stone         switch (reason) {
2184e78f606SGreg Clayton         case eStopReasonInvalid:
2194e78f606SGreg Clayton         case eStopReasonNone:
2204e78f606SGreg Clayton         case eStopReasonTrace:
22190ba8115SGreg Clayton         case eStopReasonExec:
2224e78f606SGreg Clayton         case eStopReasonPlanComplete:
223f85defaeSAndrew Kaylor         case eStopReasonThreadExiting:
224afdf842bSKuba Brecka         case eStopReasonInstrumentation:
2254e78f606SGreg Clayton           // There is no data for these stop reasons.
2264e78f606SGreg Clayton           return 0;
2274e78f606SGreg Clayton 
228b9c1b51eSKate Stone         case eStopReasonBreakpoint: {
2294e78f606SGreg Clayton           break_id_t site_id = stop_info_sp->GetValue();
230b9c1b51eSKate Stone           lldb::BreakpointSiteSP bp_site_sp(
231b9c1b51eSKate Stone               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
232b9c1b51eSKate Stone                   site_id));
233b9c1b51eSKate Stone           if (bp_site_sp) {
2344e78f606SGreg Clayton             uint32_t bp_index = idx / 2;
235b9c1b51eSKate Stone             BreakpointLocationSP bp_loc_sp(
236b9c1b51eSKate Stone                 bp_site_sp->GetOwnerAtIndex(bp_index));
237b9c1b51eSKate Stone             if (bp_loc_sp) {
238b9c1b51eSKate Stone               if (idx & 1) {
2394e78f606SGreg Clayton                 // Odd idx, return the breakpoint location ID
2404e78f606SGreg Clayton                 return bp_loc_sp->GetID();
241b9c1b51eSKate Stone               } else {
2424e78f606SGreg Clayton                 // Even idx, return the breakpoint ID
2434e78f606SGreg Clayton                 return bp_loc_sp->GetBreakpoint().GetID();
2444e78f606SGreg Clayton               }
2454e78f606SGreg Clayton             }
2464e78f606SGreg Clayton           }
2474e78f606SGreg Clayton           return LLDB_INVALID_BREAK_ID;
248b9c1b51eSKate Stone         } break;
2494e78f606SGreg Clayton 
2504e78f606SGreg Clayton         case eStopReasonWatchpoint:
251290fa41bSJohnny Chen           return stop_info_sp->GetValue();
2524e78f606SGreg Clayton 
2534e78f606SGreg Clayton         case eStopReasonSignal:
2544e78f606SGreg Clayton           return stop_info_sp->GetValue();
2554e78f606SGreg Clayton 
2564e78f606SGreg Clayton         case eStopReasonException:
2574e78f606SGreg Clayton           return stop_info_sp->GetValue();
2584e78f606SGreg Clayton         }
2594e78f606SGreg Clayton       }
260c9858e4dSGreg Clayton     }
2617fdf9ef1SGreg Clayton   }
2624e78f606SGreg Clayton   return 0;
2634e78f606SGreg Clayton }
2644e78f606SGreg Clayton 
265b9c1b51eSKate Stone bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) {
266baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, GetStopReasonExtendedInfoAsJSON,
267baf5664fSJonas Devlieghere                      (lldb::SBStream &), stream);
268baf5664fSJonas Devlieghere 
269afdf842bSKuba Brecka   Stream &strm = stream.ref();
270afdf842bSKuba Brecka 
271b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
272b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
273b2e7d28eSJim Ingham 
274afdf842bSKuba Brecka   if (!exe_ctx.HasThreadScope())
275afdf842bSKuba Brecka     return false;
276afdf842bSKuba Brecka 
277afdf842bSKuba Brecka   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
278afdf842bSKuba Brecka   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
279afdf842bSKuba Brecka   if (!info)
280afdf842bSKuba Brecka     return false;
281afdf842bSKuba Brecka 
282afdf842bSKuba Brecka   info->Dump(strm);
283afdf842bSKuba Brecka 
284afdf842bSKuba Brecka   return true;
285afdf842bSKuba Brecka }
286afdf842bSKuba Brecka 
2876a831436SKuba Brecka SBThreadCollection
288b9c1b51eSKate Stone SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
289baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBThreadCollection, SBThread,
290baf5664fSJonas Devlieghere                      GetStopReasonExtendedBacktraces,
291baf5664fSJonas Devlieghere                      (lldb::InstrumentationRuntimeType), type);
292baf5664fSJonas Devlieghere 
2936a831436SKuba Brecka   ThreadCollectionSP threads;
294796ac80bSJonas Devlieghere   threads = std::make_shared<ThreadCollection>();
2956a831436SKuba Brecka 
296b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
297b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
298b2e7d28eSJim Ingham 
2996a831436SKuba Brecka   if (!exe_ctx.HasThreadScope())
300baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(threads);
3016a831436SKuba Brecka 
3026a831436SKuba Brecka   ProcessSP process_sp = exe_ctx.GetProcessSP();
3036a831436SKuba Brecka 
3046a831436SKuba Brecka   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
3056a831436SKuba Brecka   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
3066a831436SKuba Brecka   if (!info)
307baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(threads);
3086a831436SKuba Brecka 
309baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(process_sp->GetInstrumentationRuntime(type)
310baf5664fSJonas Devlieghere                                 ->GetBacktracesFromExtendedStopInfo(info));
3116a831436SKuba Brecka }
3126a831436SKuba Brecka 
313b9c1b51eSKate Stone size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
314baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(size_t, SBThread, GetStopDescription, (char *, size_t),
315baf5664fSJonas Devlieghere                      dst, dst_len);
316baf5664fSJonas Devlieghere 
317bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
318bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3194fc6cb9cSJim Ingham 
320b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
3217fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
322b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
3237fdf9ef1SGreg Clayton 
3241ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
325b9c1b51eSKate Stone       if (stop_info_sp) {
326b15bfc75SJim Ingham         const char *stop_desc = stop_info_sp->GetDescription();
327b9c1b51eSKate Stone         if (stop_desc) {
32830fdc8d8SChris Lattner           if (dst)
32930fdc8d8SChris Lattner             return ::snprintf(dst, dst_len, "%s", stop_desc);
330b9c1b51eSKate Stone           else {
331b9c1b51eSKate Stone             // NULL dst passed in, return the length needed to contain the
332b9c1b51eSKate Stone             // description
33330fdc8d8SChris Lattner             return ::strlen(stop_desc) + 1; // Include the NULL byte for size
33430fdc8d8SChris Lattner           }
335b9c1b51eSKate Stone         } else {
33630fdc8d8SChris Lattner           size_t stop_desc_len = 0;
337b9c1b51eSKate Stone           switch (stop_info_sp->GetStopReason()) {
33830fdc8d8SChris Lattner           case eStopReasonTrace:
339b9c1b51eSKate Stone           case eStopReasonPlanComplete: {
34030fdc8d8SChris Lattner             static char trace_desc[] = "step";
34130fdc8d8SChris Lattner             stop_desc = trace_desc;
342b9c1b51eSKate Stone             stop_desc_len =
343b9c1b51eSKate Stone                 sizeof(trace_desc); // Include the NULL byte for size
344b9c1b51eSKate Stone           } break;
34530fdc8d8SChris Lattner 
346b9c1b51eSKate Stone           case eStopReasonBreakpoint: {
34730fdc8d8SChris Lattner             static char bp_desc[] = "breakpoint hit";
34830fdc8d8SChris Lattner             stop_desc = bp_desc;
34930fdc8d8SChris Lattner             stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
350b9c1b51eSKate Stone           } break;
35130fdc8d8SChris Lattner 
352b9c1b51eSKate Stone           case eStopReasonWatchpoint: {
35330fdc8d8SChris Lattner             static char wp_desc[] = "watchpoint hit";
35430fdc8d8SChris Lattner             stop_desc = wp_desc;
35530fdc8d8SChris Lattner             stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
356b9c1b51eSKate Stone           } break;
35730fdc8d8SChris Lattner 
358b9c1b51eSKate Stone           case eStopReasonSignal: {
359b9c1b51eSKate Stone             stop_desc =
360b9c1b51eSKate Stone                 exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString(
361b9c1b51eSKate Stone                     stop_info_sp->GetValue());
362*248a1305SKonrad Kleine             if (stop_desc == nullptr || stop_desc[0] == '\0') {
36330fdc8d8SChris Lattner               static char signal_desc[] = "signal";
36430fdc8d8SChris Lattner               stop_desc = signal_desc;
365b9c1b51eSKate Stone               stop_desc_len =
366b9c1b51eSKate Stone                   sizeof(signal_desc); // Include the NULL byte for size
36730fdc8d8SChris Lattner             }
368b9c1b51eSKate Stone           } break;
36930fdc8d8SChris Lattner 
370b9c1b51eSKate Stone           case eStopReasonException: {
37130fdc8d8SChris Lattner             char exc_desc[] = "exception";
37230fdc8d8SChris Lattner             stop_desc = exc_desc;
37330fdc8d8SChris Lattner             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
374b9c1b51eSKate Stone           } break;
375c982c768SGreg Clayton 
376b9c1b51eSKate Stone           case eStopReasonExec: {
37790ba8115SGreg Clayton             char exc_desc[] = "exec";
37890ba8115SGreg Clayton             stop_desc = exc_desc;
37990ba8115SGreg Clayton             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
380b9c1b51eSKate Stone           } break;
38190ba8115SGreg Clayton 
382b9c1b51eSKate Stone           case eStopReasonThreadExiting: {
383f85defaeSAndrew Kaylor             char limbo_desc[] = "thread exiting";
384f85defaeSAndrew Kaylor             stop_desc = limbo_desc;
385f85defaeSAndrew Kaylor             stop_desc_len = sizeof(limbo_desc);
386b9c1b51eSKate Stone           } break;
387c982c768SGreg Clayton           default:
388c982c768SGreg Clayton             break;
38930fdc8d8SChris Lattner           }
39030fdc8d8SChris Lattner 
391b9c1b51eSKate Stone           if (stop_desc && stop_desc[0]) {
39230fdc8d8SChris Lattner             if (dst)
393b9c1b51eSKate Stone               return ::snprintf(dst, dst_len, "%s", stop_desc) +
394b9c1b51eSKate Stone                      1; // Include the NULL byte
39530fdc8d8SChris Lattner 
39630fdc8d8SChris Lattner             if (stop_desc_len == 0)
39730fdc8d8SChris Lattner               stop_desc_len = ::strlen(stop_desc) + 1; // Include the NULL byte
39830fdc8d8SChris Lattner 
39930fdc8d8SChris Lattner             return stop_desc_len;
40030fdc8d8SChris Lattner           }
40130fdc8d8SChris Lattner         }
40230fdc8d8SChris Lattner       }
403c9858e4dSGreg Clayton     }
4047fdf9ef1SGreg Clayton   }
40530fdc8d8SChris Lattner   if (dst)
40630fdc8d8SChris Lattner     *dst = 0;
40730fdc8d8SChris Lattner   return 0;
40830fdc8d8SChris Lattner }
40930fdc8d8SChris Lattner 
410b9c1b51eSKate Stone SBValue SBThread::GetStopReturnValue() {
411baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBValue, SBThread, GetStopReturnValue);
412baf5664fSJonas Devlieghere 
41373ca05a2SJim Ingham   ValueObjectSP return_valobj_sp;
414bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
415bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4164fc6cb9cSJim Ingham 
417b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4187fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
419b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4201ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
421b9c1b51eSKate Stone       if (stop_info_sp) {
42273ca05a2SJim Ingham         return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp);
42373ca05a2SJim Ingham       }
424c9858e4dSGreg Clayton     }
4257fdf9ef1SGreg Clayton   }
42673ca05a2SJim Ingham 
427baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(SBValue(return_valobj_sp));
42873ca05a2SJim Ingham }
42973ca05a2SJim Ingham 
430b9c1b51eSKate Stone void SBThread::SetThread(const ThreadSP &lldb_object_sp) {
4317fdf9ef1SGreg Clayton   m_opaque_sp->SetThreadSP(lldb_object_sp);
43230fdc8d8SChris Lattner }
43330fdc8d8SChris Lattner 
434b9c1b51eSKate Stone lldb::tid_t SBThread::GetThreadID() const {
435baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::tid_t, SBThread, GetThreadID);
436baf5664fSJonas Devlieghere 
4377fdf9ef1SGreg Clayton   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
43817a6ad05SGreg Clayton   if (thread_sp)
4391ac04c30SGreg Clayton     return thread_sp->GetID();
4401ac04c30SGreg Clayton   return LLDB_INVALID_THREAD_ID;
44130fdc8d8SChris Lattner }
44230fdc8d8SChris Lattner 
443b9c1b51eSKate Stone uint32_t SBThread::GetIndexID() const {
444baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBThread, GetIndexID);
445baf5664fSJonas Devlieghere 
4467fdf9ef1SGreg Clayton   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
44717a6ad05SGreg Clayton   if (thread_sp)
44817a6ad05SGreg Clayton     return thread_sp->GetIndexID();
44930fdc8d8SChris Lattner   return LLDB_INVALID_INDEX32;
45030fdc8d8SChris Lattner }
4511ac04c30SGreg Clayton 
452b9c1b51eSKate Stone const char *SBThread::GetName() const {
453baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBThread, GetName);
454baf5664fSJonas Devlieghere 
455*248a1305SKonrad Kleine   const char *name = nullptr;
456bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
457bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4584fc6cb9cSJim Ingham 
459b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4607fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
461b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4621ac04c30SGreg Clayton       name = exe_ctx.GetThreadPtr()->GetName();
463c9858e4dSGreg Clayton     }
4647fdf9ef1SGreg Clayton   }
465ceb6b139SCaroline Tice 
4664838131bSGreg Clayton   return name;
46730fdc8d8SChris Lattner }
46830fdc8d8SChris Lattner 
469b9c1b51eSKate Stone const char *SBThread::GetQueueName() const {
470baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBThread, GetQueueName);
471baf5664fSJonas Devlieghere 
472*248a1305SKonrad Kleine   const char *name = nullptr;
473bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
474bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4754fc6cb9cSJim Ingham 
476b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4777fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
478b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4791ac04c30SGreg Clayton       name = exe_ctx.GetThreadPtr()->GetQueueName();
480c9858e4dSGreg Clayton     }
4817fdf9ef1SGreg Clayton   }
482ceb6b139SCaroline Tice 
4834838131bSGreg Clayton   return name;
48430fdc8d8SChris Lattner }
48530fdc8d8SChris Lattner 
486b9c1b51eSKate Stone lldb::queue_id_t SBThread::GetQueueID() const {
487baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::queue_id_t, SBThread, GetQueueID);
488baf5664fSJonas Devlieghere 
4894fdb5863SJason Molenda   queue_id_t id = LLDB_INVALID_QUEUE_ID;
490bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
491bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4924fdb5863SJason Molenda 
493b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4944fdb5863SJason Molenda     Process::StopLocker stop_locker;
495b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4964fdb5863SJason Molenda       id = exe_ctx.GetThreadPtr()->GetQueueID();
4974fdb5863SJason Molenda     }
4984fdb5863SJason Molenda   }
4994fdb5863SJason Molenda 
5004fdb5863SJason Molenda   return id;
5014fdb5863SJason Molenda }
5024fdb5863SJason Molenda 
503b9c1b51eSKate Stone bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
504baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, GetInfoItemByPathAsString,
505baf5664fSJonas Devlieghere                      (const char *, lldb::SBStream &), path, strm);
506baf5664fSJonas Devlieghere 
507705b1809SJason Molenda   bool success = false;
508bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
509bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
510705b1809SJason Molenda 
511b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
512705b1809SJason Molenda     Process::StopLocker stop_locker;
513b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
514705b1809SJason Molenda       Thread *thread = exe_ctx.GetThreadPtr();
515705b1809SJason Molenda       StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
516b9c1b51eSKate Stone       if (info_root_sp) {
517b9c1b51eSKate Stone         StructuredData::ObjectSP node =
518b9c1b51eSKate Stone             info_root_sp->GetObjectForDotSeparatedPath(path);
519b9c1b51eSKate Stone         if (node) {
5205bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeString) {
5212833321fSZachary Turner             strm.Printf("%s", node->GetAsString()->GetValue().str().c_str());
522705b1809SJason Molenda             success = true;
523705b1809SJason Molenda           }
5245bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeInteger) {
525705b1809SJason Molenda             strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue());
526705b1809SJason Molenda             success = true;
527705b1809SJason Molenda           }
5285bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeFloat) {
529705b1809SJason Molenda             strm.Printf("0x%f", node->GetAsFloat()->GetValue());
530705b1809SJason Molenda             success = true;
531705b1809SJason Molenda           }
5325bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeBoolean) {
533a6682a41SJonas Devlieghere             if (node->GetAsBoolean()->GetValue())
534705b1809SJason Molenda               strm.Printf("true");
535705b1809SJason Molenda             else
536705b1809SJason Molenda               strm.Printf("false");
537705b1809SJason Molenda             success = true;
538705b1809SJason Molenda           }
5395bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeNull) {
540705b1809SJason Molenda             strm.Printf("null");
541705b1809SJason Molenda             success = true;
542705b1809SJason Molenda           }
543705b1809SJason Molenda         }
544705b1809SJason Molenda       }
545705b1809SJason Molenda     }
546705b1809SJason Molenda   }
547705b1809SJason Molenda 
548705b1809SJason Molenda   return success;
549705b1809SJason Molenda }
550705b1809SJason Molenda 
551b9c1b51eSKate Stone SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
552b9c1b51eSKate Stone                                 ThreadPlan *new_plan) {
55364e7ead1SJim Ingham   SBError sb_error;
55464e7ead1SJim Ingham 
55564e7ead1SJim Ingham   Process *process = exe_ctx.GetProcessPtr();
556b9c1b51eSKate Stone   if (!process) {
55764e7ead1SJim Ingham     sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
55864e7ead1SJim Ingham     return sb_error;
55964e7ead1SJim Ingham   }
56064e7ead1SJim Ingham 
56164e7ead1SJim Ingham   Thread *thread = exe_ctx.GetThreadPtr();
562b9c1b51eSKate Stone   if (!thread) {
56364e7ead1SJim Ingham     sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
56464e7ead1SJim Ingham     return sb_error;
56564e7ead1SJim Ingham   }
56664e7ead1SJim Ingham 
567b9c1b51eSKate Stone   // User level plans should be Master Plans so they can be interrupted, other
56805097246SAdrian Prantl   // plans executed, and then a "continue" will resume the plan.
569*248a1305SKonrad Kleine   if (new_plan != nullptr) {
57064e7ead1SJim Ingham     new_plan->SetIsMasterPlan(true);
57164e7ead1SJim Ingham     new_plan->SetOkayToDiscard(false);
57264e7ead1SJim Ingham   }
57364e7ead1SJim Ingham 
57464e7ead1SJim Ingham   // Why do we need to set the current thread by ID here???
57564e7ead1SJim Ingham   process->GetThreadList().SetSelectedThreadByID(thread->GetID());
57664e7ead1SJim Ingham 
577dc6224e0SGreg Clayton   if (process->GetTarget().GetDebugger().GetAsyncExecution())
578dc6224e0SGreg Clayton     sb_error.ref() = process->Resume();
579dc6224e0SGreg Clayton   else
580*248a1305SKonrad Kleine     sb_error.ref() = process->ResumeSynchronous(nullptr);
58164e7ead1SJim Ingham 
58264e7ead1SJim Ingham   return sb_error;
58364e7ead1SJim Ingham }
58430fdc8d8SChris Lattner 
585b9c1b51eSKate Stone void SBThread::StepOver(lldb::RunMode stop_other_threads) {
586baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOver, (lldb::RunMode),
587baf5664fSJonas Devlieghere                      stop_other_threads);
588baf5664fSJonas Devlieghere 
589859f54b3SAlexander Polyakov   SBError error; // Ignored
590859f54b3SAlexander Polyakov   StepOver(stop_other_threads, error);
591859f54b3SAlexander Polyakov }
592859f54b3SAlexander Polyakov 
593859f54b3SAlexander Polyakov void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
594baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOver, (lldb::RunMode, lldb::SBError &),
595baf5664fSJonas Devlieghere                      stop_other_threads, error);
596baf5664fSJonas Devlieghere 
597bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
598bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
59917a6ad05SGreg Clayton 
600859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
601859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
602859f54b3SAlexander Polyakov     return;
603859f54b3SAlexander Polyakov   }
604859f54b3SAlexander Polyakov 
6051ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
6067ba6e991SJim Ingham   bool abort_other_plans = false;
607b57e4a1bSJason Molenda   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
60830fdc8d8SChris Lattner 
609e103ae92SJonas Devlieghere   Status new_plan_status;
6104d56e9c1SJim Ingham   ThreadPlanSP new_plan_sp;
611b9c1b51eSKate Stone   if (frame_sp) {
612b9c1b51eSKate Stone     if (frame_sp->HasDebugInformation()) {
6134b4b2478SJim Ingham       const LazyBool avoid_no_debug = eLazyBoolCalculate;
61430fdc8d8SChris Lattner       SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
615b9c1b51eSKate Stone       new_plan_sp = thread->QueueThreadPlanForStepOverRange(
616b9c1b51eSKate Stone           abort_other_plans, sc.line_entry, sc, stop_other_threads,
617e103ae92SJonas Devlieghere           new_plan_status, avoid_no_debug);
618b9c1b51eSKate Stone     } else {
619b9c1b51eSKate Stone       new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
620e103ae92SJonas Devlieghere           true, abort_other_plans, stop_other_threads, new_plan_status);
62130fdc8d8SChris Lattner     }
62230fdc8d8SChris Lattner   }
623859f54b3SAlexander Polyakov   error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
62430fdc8d8SChris Lattner }
62530fdc8d8SChris Lattner 
626b9c1b51eSKate Stone void SBThread::StepInto(lldb::RunMode stop_other_threads) {
627baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInto, (lldb::RunMode),
628baf5664fSJonas Devlieghere                      stop_other_threads);
629baf5664fSJonas Devlieghere 
630*248a1305SKonrad Kleine   StepInto(nullptr, stop_other_threads);
631c627682eSJim Ingham }
632c627682eSJim Ingham 
633b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name,
634b9c1b51eSKate Stone                         lldb::RunMode stop_other_threads) {
635baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInto, (const char *, lldb::RunMode),
636baf5664fSJonas Devlieghere                      target_name, stop_other_threads);
637baf5664fSJonas Devlieghere 
638859f54b3SAlexander Polyakov   SBError error; // Ignored
639cbf6f9b2SJim Ingham   StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
640cbf6f9b2SJim Ingham }
641cbf6f9b2SJim Ingham 
642b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name, uint32_t end_line,
643b9c1b51eSKate Stone                         SBError &error, lldb::RunMode stop_other_threads) {
644baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInto,
645baf5664fSJonas Devlieghere                      (const char *, uint32_t, lldb::SBError &, lldb::RunMode),
646baf5664fSJonas Devlieghere                      target_name, end_line, error, stop_other_threads);
647baf5664fSJonas Devlieghere 
648ceb6b139SCaroline Tice 
649bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
650bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
65117a6ad05SGreg Clayton 
652859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
653859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
654859f54b3SAlexander Polyakov     return;
655859f54b3SAlexander Polyakov   }
656859f54b3SAlexander Polyakov 
6577ba6e991SJim Ingham   bool abort_other_plans = false;
65830fdc8d8SChris Lattner 
6591ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
660b57e4a1bSJason Molenda   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
6614d56e9c1SJim Ingham   ThreadPlanSP new_plan_sp;
662e103ae92SJonas Devlieghere   Status new_plan_status;
66330fdc8d8SChris Lattner 
664b9c1b51eSKate Stone   if (frame_sp && frame_sp->HasDebugInformation()) {
665cbf6f9b2SJim Ingham     SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
666cbf6f9b2SJim Ingham     AddressRange range;
667cbf6f9b2SJim Ingham     if (end_line == LLDB_INVALID_LINE_NUMBER)
668cbf6f9b2SJim Ingham       range = sc.line_entry.range;
669b9c1b51eSKate Stone     else {
670cbf6f9b2SJim Ingham       if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
671cbf6f9b2SJim Ingham         return;
672cbf6f9b2SJim Ingham     }
673cbf6f9b2SJim Ingham 
674b9c1b51eSKate Stone     const LazyBool step_out_avoids_code_without_debug_info =
675b9c1b51eSKate Stone         eLazyBoolCalculate;
676b9c1b51eSKate Stone     const LazyBool step_in_avoids_code_without_debug_info =
677b9c1b51eSKate Stone         eLazyBoolCalculate;
678b9c1b51eSKate Stone     new_plan_sp = thread->QueueThreadPlanForStepInRange(
679b9c1b51eSKate Stone         abort_other_plans, range, sc, target_name, stop_other_threads,
680e103ae92SJonas Devlieghere         new_plan_status, step_in_avoids_code_without_debug_info,
6814b4b2478SJim Ingham         step_out_avoids_code_without_debug_info);
682b9c1b51eSKate Stone   } else {
683b9c1b51eSKate Stone     new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
684e103ae92SJonas Devlieghere         false, abort_other_plans, stop_other_threads, new_plan_status);
68530fdc8d8SChris Lattner   }
686e103ae92SJonas Devlieghere 
687e103ae92SJonas Devlieghere   if (new_plan_status.Success())
688cbf6f9b2SJim Ingham     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
689e103ae92SJonas Devlieghere   else
690e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
69130fdc8d8SChris Lattner }
69230fdc8d8SChris Lattner 
693b9c1b51eSKate Stone void SBThread::StepOut() {
694baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(void, SBThread, StepOut);
695baf5664fSJonas Devlieghere 
696859f54b3SAlexander Polyakov   SBError error; // Ignored
697859f54b3SAlexander Polyakov   StepOut(error);
698859f54b3SAlexander Polyakov }
699859f54b3SAlexander Polyakov 
700859f54b3SAlexander Polyakov void SBThread::StepOut(SBError &error) {
701baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOut, (lldb::SBError &), error);
702baf5664fSJonas Devlieghere 
703bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
704bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
7054fc6cb9cSJim Ingham 
706859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
707859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
708859f54b3SAlexander Polyakov     return;
709859f54b3SAlexander Polyakov   }
710859f54b3SAlexander Polyakov 
7117ba6e991SJim Ingham   bool abort_other_plans = false;
71294b09246SJim Ingham   bool stop_other_threads = false;
71330fdc8d8SChris Lattner 
7141ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
7151ac04c30SGreg Clayton 
7164b4b2478SJim Ingham   const LazyBool avoid_no_debug = eLazyBoolCalculate;
717e103ae92SJonas Devlieghere   Status new_plan_status;
718b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
719*248a1305SKonrad Kleine       abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
720e103ae92SJonas Devlieghere       eVoteNoOpinion, 0, new_plan_status, avoid_no_debug));
721481cef25SGreg Clayton 
722e103ae92SJonas Devlieghere   if (new_plan_status.Success())
723859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
724e103ae92SJonas Devlieghere   else
725e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
726481cef25SGreg Clayton }
727481cef25SGreg Clayton 
728859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
729baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOutOfFrame, (lldb::SBFrame &),
730baf5664fSJonas Devlieghere                      sb_frame);
731baf5664fSJonas Devlieghere 
732859f54b3SAlexander Polyakov   SBError error; // Ignored
733859f54b3SAlexander Polyakov   StepOutOfFrame(sb_frame, error);
734859f54b3SAlexander Polyakov }
735859f54b3SAlexander Polyakov 
736859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
737baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOutOfFrame,
738baf5664fSJonas Devlieghere                      (lldb::SBFrame &, lldb::SBError &), sb_frame, error);
739baf5664fSJonas Devlieghere 
740481cef25SGreg Clayton 
741bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
742bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
7434fc6cb9cSJim Ingham 
744b9c1b51eSKate Stone   if (!sb_frame.IsValid()) {
745859f54b3SAlexander Polyakov     error.SetErrorString("passed invalid SBFrame object");
746989a7558SJim Ingham     return;
747989a7558SJim Ingham   }
748989a7558SJim Ingham 
749b57e4a1bSJason Molenda   StackFrameSP frame_sp(sb_frame.GetFrameSP());
750481cef25SGreg Clayton 
751859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
752859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
753859f54b3SAlexander Polyakov     return;
754859f54b3SAlexander Polyakov   }
755859f54b3SAlexander Polyakov 
7567ba6e991SJim Ingham   bool abort_other_plans = false;
75794b09246SJim Ingham   bool stop_other_threads = false;
7581ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
759b9c1b51eSKate Stone   if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
760859f54b3SAlexander Polyakov     error.SetErrorString("passed a frame from another thread");
761859f54b3SAlexander Polyakov     return;
762989a7558SJim Ingham   }
763481cef25SGreg Clayton 
764e103ae92SJonas Devlieghere   Status new_plan_status;
765b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
766*248a1305SKonrad Kleine       abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
767e103ae92SJonas Devlieghere       eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status));
76830fdc8d8SChris Lattner 
769e103ae92SJonas Devlieghere   if (new_plan_status.Success())
770859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
771e103ae92SJonas Devlieghere   else
772e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
77330fdc8d8SChris Lattner }
77430fdc8d8SChris Lattner 
775b9c1b51eSKate Stone void SBThread::StepInstruction(bool step_over) {
776baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInstruction, (bool), step_over);
777baf5664fSJonas Devlieghere 
778859f54b3SAlexander Polyakov   SBError error; // Ignored
779859f54b3SAlexander Polyakov   StepInstruction(step_over, error);
780859f54b3SAlexander Polyakov }
781859f54b3SAlexander Polyakov 
782859f54b3SAlexander Polyakov void SBThread::StepInstruction(bool step_over, SBError &error) {
783baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInstruction, (bool, lldb::SBError &),
784baf5664fSJonas Devlieghere                      step_over, error);
785baf5664fSJonas Devlieghere 
786bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
787bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
788ceb6b139SCaroline Tice 
789859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
790859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
791859f54b3SAlexander Polyakov     return;
792859f54b3SAlexander Polyakov   }
793859f54b3SAlexander Polyakov 
7941ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
795e103ae92SJonas Devlieghere   Status new_plan_status;
796e103ae92SJonas Devlieghere   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction(
797e103ae92SJonas Devlieghere       step_over, true, true, new_plan_status));
79864e7ead1SJim Ingham 
799e103ae92SJonas Devlieghere   if (new_plan_status.Success())
800859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
801e103ae92SJonas Devlieghere   else
802e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
80330fdc8d8SChris Lattner }
80430fdc8d8SChris Lattner 
805b9c1b51eSKate Stone void SBThread::RunToAddress(lldb::addr_t addr) {
806baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, RunToAddress, (lldb::addr_t), addr);
807baf5664fSJonas Devlieghere 
808859f54b3SAlexander Polyakov   SBError error; // Ignored
809859f54b3SAlexander Polyakov   RunToAddress(addr, error);
810859f54b3SAlexander Polyakov }
811859f54b3SAlexander Polyakov 
812859f54b3SAlexander Polyakov void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
813baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, RunToAddress,
814baf5664fSJonas Devlieghere                      (lldb::addr_t, lldb::SBError &), addr, error);
815baf5664fSJonas Devlieghere 
816bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
817bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
818ceb6b139SCaroline Tice 
819859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
820859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
821859f54b3SAlexander Polyakov     return;
822859f54b3SAlexander Polyakov   }
823859f54b3SAlexander Polyakov 
8247ba6e991SJim Ingham   bool abort_other_plans = false;
82530fdc8d8SChris Lattner   bool stop_other_threads = true;
82630fdc8d8SChris Lattner 
827e72dfb32SGreg Clayton   Address target_addr(addr);
82830fdc8d8SChris Lattner 
8291ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
8301ac04c30SGreg Clayton 
831e103ae92SJonas Devlieghere   Status new_plan_status;
832b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
833e103ae92SJonas Devlieghere       abort_other_plans, target_addr, stop_other_threads, new_plan_status));
83464e7ead1SJim Ingham 
835e103ae92SJonas Devlieghere   if (new_plan_status.Success())
836859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
837e103ae92SJonas Devlieghere   else
838e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
83930fdc8d8SChris Lattner }
84030fdc8d8SChris Lattner 
841b9c1b51eSKate Stone SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
842b9c1b51eSKate Stone                                 lldb::SBFileSpec &sb_file_spec, uint32_t line) {
843baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepOverUntil,
844baf5664fSJonas Devlieghere                      (lldb::SBFrame &, lldb::SBFileSpec &, uint32_t), sb_frame,
845baf5664fSJonas Devlieghere                      sb_file_spec, line);
846baf5664fSJonas Devlieghere 
847481cef25SGreg Clayton   SBError sb_error;
848481cef25SGreg Clayton   char path[PATH_MAX];
849481cef25SGreg Clayton 
850bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
851bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
8524fc6cb9cSJim Ingham 
853b57e4a1bSJason Molenda   StackFrameSP frame_sp(sb_frame.GetFrameSP());
85417a6ad05SGreg Clayton 
855b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
8561ac04c30SGreg Clayton     Target *target = exe_ctx.GetTargetPtr();
8571ac04c30SGreg Clayton     Thread *thread = exe_ctx.GetThreadPtr();
858481cef25SGreg Clayton 
859b9c1b51eSKate Stone     if (line == 0) {
860481cef25SGreg Clayton       sb_error.SetErrorString("invalid line argument");
861baf5664fSJonas Devlieghere       return LLDB_RECORD_RESULT(sb_error);
862481cef25SGreg Clayton     }
863481cef25SGreg Clayton 
864b9c1b51eSKate Stone     if (!frame_sp) {
8651ac04c30SGreg Clayton       frame_sp = thread->GetSelectedFrame();
866481cef25SGreg Clayton       if (!frame_sp)
8671ac04c30SGreg Clayton         frame_sp = thread->GetStackFrameAtIndex(0);
868481cef25SGreg Clayton     }
869481cef25SGreg Clayton 
870481cef25SGreg Clayton     SymbolContext frame_sc;
871b9c1b51eSKate Stone     if (!frame_sp) {
872481cef25SGreg Clayton       sb_error.SetErrorString("no valid frames in thread to step");
873baf5664fSJonas Devlieghere       return LLDB_RECORD_RESULT(sb_error);
874481cef25SGreg Clayton     }
875481cef25SGreg Clayton 
876481cef25SGreg Clayton     // If we have a frame, get its line
877b9c1b51eSKate Stone     frame_sc = frame_sp->GetSymbolContext(
878b9c1b51eSKate Stone         eSymbolContextCompUnit | eSymbolContextFunction |
879b9c1b51eSKate Stone         eSymbolContextLineEntry | eSymbolContextSymbol);
880481cef25SGreg Clayton 
881*248a1305SKonrad Kleine     if (frame_sc.comp_unit == nullptr) {
882b9c1b51eSKate Stone       sb_error.SetErrorStringWithFormat(
883b9c1b51eSKate Stone           "frame %u doesn't have debug information", frame_sp->GetFrameIndex());
884baf5664fSJonas Devlieghere       return LLDB_RECORD_RESULT(sb_error);
885481cef25SGreg Clayton     }
886481cef25SGreg Clayton 
887481cef25SGreg Clayton     FileSpec step_file_spec;
888b9c1b51eSKate Stone     if (sb_file_spec.IsValid()) {
889481cef25SGreg Clayton       // The file spec passed in was valid, so use it
890481cef25SGreg Clayton       step_file_spec = sb_file_spec.ref();
891b9c1b51eSKate Stone     } else {
892481cef25SGreg Clayton       if (frame_sc.line_entry.IsValid())
893481cef25SGreg Clayton         step_file_spec = frame_sc.line_entry.file;
894b9c1b51eSKate Stone       else {
895481cef25SGreg Clayton         sb_error.SetErrorString("invalid file argument or no file for frame");
896baf5664fSJonas Devlieghere         return LLDB_RECORD_RESULT(sb_error);
897481cef25SGreg Clayton       }
898481cef25SGreg Clayton     }
899481cef25SGreg Clayton 
9009b70ddb3SJim Ingham     // Grab the current function, then we will make sure the "until" address is
9019b70ddb3SJim Ingham     // within the function.  We discard addresses that are out of the current
902b9c1b51eSKate Stone     // function, and then if there are no addresses remaining, give an
90305097246SAdrian Prantl     // appropriate error message.
9049b70ddb3SJim Ingham 
9059b70ddb3SJim Ingham     bool all_in_function = true;
9069b70ddb3SJim Ingham     AddressRange fun_range = frame_sc.function->GetAddressRange();
9079b70ddb3SJim Ingham 
908481cef25SGreg Clayton     std::vector<addr_t> step_over_until_addrs;
9097ba6e991SJim Ingham     const bool abort_other_plans = false;
910c02e3344SJim Ingham     const bool stop_other_threads = false;
911481cef25SGreg Clayton     const bool check_inlines = true;
912481cef25SGreg Clayton     const bool exact = false;
913481cef25SGreg Clayton 
914481cef25SGreg Clayton     SymbolContextList sc_list;
915b9c1b51eSKate Stone     const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext(
916b9c1b51eSKate Stone         step_file_spec, line, check_inlines, exact, eSymbolContextLineEntry,
9179b70ddb3SJim Ingham         sc_list);
918b9c1b51eSKate Stone     if (num_matches > 0) {
919481cef25SGreg Clayton       SymbolContext sc;
920b9c1b51eSKate Stone       for (uint32_t i = 0; i < num_matches; ++i) {
921b9c1b51eSKate Stone         if (sc_list.GetContextAtIndex(i, sc)) {
922b9c1b51eSKate Stone           addr_t step_addr =
923b9c1b51eSKate Stone               sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
924b9c1b51eSKate Stone           if (step_addr != LLDB_INVALID_ADDRESS) {
9259b70ddb3SJim Ingham             if (fun_range.ContainsLoadAddress(step_addr, target))
926481cef25SGreg Clayton               step_over_until_addrs.push_back(step_addr);
9279b70ddb3SJim Ingham             else
9289b70ddb3SJim Ingham               all_in_function = false;
929481cef25SGreg Clayton           }
930481cef25SGreg Clayton         }
931481cef25SGreg Clayton       }
932481cef25SGreg Clayton     }
933481cef25SGreg Clayton 
934b9c1b51eSKate Stone     if (step_over_until_addrs.empty()) {
935b9c1b51eSKate Stone       if (all_in_function) {
936481cef25SGreg Clayton         step_file_spec.GetPath(path, sizeof(path));
937b9c1b51eSKate Stone         sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path,
938b9c1b51eSKate Stone                                           line);
939b9c1b51eSKate Stone       } else
94086edbf41SGreg Clayton         sb_error.SetErrorString("step until target not in current function");
941b9c1b51eSKate Stone     } else {
942e103ae92SJonas Devlieghere       Status new_plan_status;
943b9c1b51eSKate Stone       ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil(
944b9c1b51eSKate Stone           abort_other_plans, &step_over_until_addrs[0],
945b9c1b51eSKate Stone           step_over_until_addrs.size(), stop_other_threads,
946e103ae92SJonas Devlieghere           frame_sp->GetFrameIndex(), new_plan_status));
947481cef25SGreg Clayton 
948e103ae92SJonas Devlieghere       if (new_plan_status.Success())
9494d56e9c1SJim Ingham         sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
950e103ae92SJonas Devlieghere       else
951e103ae92SJonas Devlieghere         sb_error.SetErrorString(new_plan_status.AsCString());
952481cef25SGreg Clayton     }
953b9c1b51eSKate Stone   } else {
954481cef25SGreg Clayton     sb_error.SetErrorString("this SBThread object is invalid");
955481cef25SGreg Clayton   }
956baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
957481cef25SGreg Clayton }
958481cef25SGreg Clayton 
959b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) {
960baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
961baf5664fSJonas Devlieghere                      (const char *), script_class_name);
962baf5664fSJonas Devlieghere 
963baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
964baf5664fSJonas Devlieghere       StepUsingScriptedThreadPlan(script_class_name, true));
965c915a7d2SJim Ingham }
966c915a7d2SJim Ingham 
967b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
968b9c1b51eSKate Stone                                               bool resume_immediately) {
969baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
970baf5664fSJonas Devlieghere                      (const char *, bool), script_class_name,
971baf5664fSJonas Devlieghere                      resume_immediately);
972baf5664fSJonas Devlieghere 
973e103ae92SJonas Devlieghere   SBError error;
9742bdbfd50SJim Ingham 
975bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
976bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
9772bdbfd50SJim Ingham 
978b9c1b51eSKate Stone   if (!exe_ctx.HasThreadScope()) {
979e103ae92SJonas Devlieghere     error.SetErrorString("this SBThread object is invalid");
980baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(error);
9812bdbfd50SJim Ingham   }
9822bdbfd50SJim Ingham 
9832bdbfd50SJim Ingham   Thread *thread = exe_ctx.GetThreadPtr();
984e103ae92SJonas Devlieghere   Status new_plan_status;
985e103ae92SJonas Devlieghere   ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted(
986e103ae92SJonas Devlieghere       false, script_class_name, false, new_plan_status);
9872bdbfd50SJim Ingham 
988e103ae92SJonas Devlieghere   if (new_plan_status.Fail()) {
989e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
990baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(error);
991c915a7d2SJim Ingham   }
992c915a7d2SJim Ingham 
993e103ae92SJonas Devlieghere   if (!resume_immediately)
994baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(error);
995c915a7d2SJim Ingham 
996e103ae92SJonas Devlieghere   if (new_plan_status.Success())
997e103ae92SJonas Devlieghere     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
998e103ae92SJonas Devlieghere   else
999e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
10002bdbfd50SJim Ingham 
1001baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(error);
10022bdbfd50SJim Ingham }
10032bdbfd50SJim Ingham 
1004b9c1b51eSKate Stone SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
1005baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, JumpToLine,
1006baf5664fSJonas Devlieghere                      (lldb::SBFileSpec &, uint32_t), file_spec, line);
1007baf5664fSJonas Devlieghere 
1008f86248d9SRichard Mitton   SBError sb_error;
1009f86248d9SRichard Mitton 
1010bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1011bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1012f86248d9SRichard Mitton 
1013b9c1b51eSKate Stone   if (!exe_ctx.HasThreadScope()) {
1014f86248d9SRichard Mitton     sb_error.SetErrorString("this SBThread object is invalid");
1015baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(sb_error);
1016f86248d9SRichard Mitton   }
1017f86248d9SRichard Mitton 
1018f86248d9SRichard Mitton   Thread *thread = exe_ctx.GetThreadPtr();
1019f86248d9SRichard Mitton 
102097206d57SZachary Turner   Status err = thread->JumpToLine(file_spec.get(), line, true);
1021f86248d9SRichard Mitton   sb_error.SetError(err);
1022baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
1023f86248d9SRichard Mitton }
1024f86248d9SRichard Mitton 
1025b9c1b51eSKate Stone SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
1026baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, ReturnFromFrame,
1027baf5664fSJonas Devlieghere                      (lldb::SBFrame &, lldb::SBValue &), frame, return_value);
1028baf5664fSJonas Devlieghere 
10294413758cSJim Ingham   SBError sb_error;
10304413758cSJim Ingham 
1031bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1032bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
10334413758cSJim Ingham 
1034b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
10354413758cSJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
1036b9c1b51eSKate Stone     sb_error.SetError(
1037b9c1b51eSKate Stone         thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
10384413758cSJim Ingham   }
10394413758cSJim Ingham 
1040baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
10414413758cSJim Ingham }
10424413758cSJim Ingham 
1043b9c1b51eSKate Stone SBError SBThread::UnwindInnermostExpression() {
1044baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBError, SBThread,
1045baf5664fSJonas Devlieghere                              UnwindInnermostExpression);
1046baf5664fSJonas Devlieghere 
10474ac8e93aSJim Ingham   SBError sb_error;
10484ac8e93aSJim Ingham 
10494ac8e93aSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
10504ac8e93aSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
10514ac8e93aSJim Ingham 
1052b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
10534ac8e93aSJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
10544ac8e93aSJim Ingham     sb_error.SetError(thread->UnwindInnermostExpression());
10554ac8e93aSJim Ingham     if (sb_error.Success())
10564ac8e93aSJim Ingham       thread->SetSelectedFrameByIndex(0, false);
10574ac8e93aSJim Ingham   }
10584ac8e93aSJim Ingham 
1059baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
10604ac8e93aSJim Ingham }
1061481cef25SGreg Clayton 
1062b9c1b51eSKate Stone bool SBThread::Suspend() {
1063baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, Suspend);
1064baf5664fSJonas Devlieghere 
1065859f54b3SAlexander Polyakov   SBError error; // Ignored
1066859f54b3SAlexander Polyakov   return Suspend(error);
1067859f54b3SAlexander Polyakov }
1068859f54b3SAlexander Polyakov 
1069859f54b3SAlexander Polyakov bool SBThread::Suspend(SBError &error) {
1070baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, Suspend, (lldb::SBError &), error);
1071baf5664fSJonas Devlieghere 
1072b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1073b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1074b2e7d28eSJim Ingham 
1075c9858e4dSGreg Clayton   bool result = false;
1076b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1077c9858e4dSGreg Clayton     Process::StopLocker stop_locker;
1078b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
10791ac04c30SGreg Clayton       exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
1080c9858e4dSGreg Clayton       result = true;
1081b9c1b51eSKate Stone     } else {
1082859f54b3SAlexander Polyakov       error.SetErrorString("process is running");
1083c9858e4dSGreg Clayton     }
1084859f54b3SAlexander Polyakov   } else
1085859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
1086c9858e4dSGreg Clayton   return result;
1087722a0cdcSGreg Clayton }
1088722a0cdcSGreg Clayton 
1089b9c1b51eSKate Stone bool SBThread::Resume() {
1090baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, Resume);
1091baf5664fSJonas Devlieghere 
1092859f54b3SAlexander Polyakov   SBError error; // Ignored
1093859f54b3SAlexander Polyakov   return Resume(error);
1094859f54b3SAlexander Polyakov }
1095859f54b3SAlexander Polyakov 
1096859f54b3SAlexander Polyakov bool SBThread::Resume(SBError &error) {
1097baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, Resume, (lldb::SBError &), error);
1098baf5664fSJonas Devlieghere 
1099b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1100b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1101b2e7d28eSJim Ingham 
1102c9858e4dSGreg Clayton   bool result = false;
1103b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1104c9858e4dSGreg Clayton     Process::StopLocker stop_locker;
1105b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11066c9ed91cSJim Ingham       const bool override_suspend = true;
11076c9ed91cSJim Ingham       exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
1108c9858e4dSGreg Clayton       result = true;
1109b9c1b51eSKate Stone     } else {
1110859f54b3SAlexander Polyakov       error.SetErrorString("process is running");
1111c9858e4dSGreg Clayton     }
1112859f54b3SAlexander Polyakov   } else
1113859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
1114c9858e4dSGreg Clayton   return result;
1115722a0cdcSGreg Clayton }
1116722a0cdcSGreg Clayton 
1117b9c1b51eSKate Stone bool SBThread::IsSuspended() {
1118baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, IsSuspended);
1119baf5664fSJonas Devlieghere 
1120b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1121b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1122b2e7d28eSJim Ingham 
11231ac04c30SGreg Clayton   if (exe_ctx.HasThreadScope())
11241ac04c30SGreg Clayton     return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
1125722a0cdcSGreg Clayton   return false;
1126722a0cdcSGreg Clayton }
1127722a0cdcSGreg Clayton 
1128b9c1b51eSKate Stone bool SBThread::IsStopped() {
1129baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, IsStopped);
1130baf5664fSJonas Devlieghere 
1131b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1132b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1133b2e7d28eSJim Ingham 
1134a75418dbSAndrew Kaylor   if (exe_ctx.HasThreadScope())
1135a75418dbSAndrew Kaylor     return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1136a75418dbSAndrew Kaylor   return false;
1137a75418dbSAndrew Kaylor }
1138a75418dbSAndrew Kaylor 
1139b9c1b51eSKate Stone SBProcess SBThread::GetProcess() {
1140baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBProcess, SBThread, GetProcess);
1141baf5664fSJonas Devlieghere 
1142b9556accSGreg Clayton   SBProcess sb_process;
1143b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1144b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1145b2e7d28eSJim Ingham 
1146b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1147b9c1b51eSKate Stone     // Have to go up to the target so we can get a shared pointer to our
1148b9c1b51eSKate Stone     // process...
11491ac04c30SGreg Clayton     sb_process.SetSP(exe_ctx.GetProcessSP());
115030fdc8d8SChris Lattner   }
1151ceb6b139SCaroline Tice 
1152baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_process);
115330fdc8d8SChris Lattner }
115430fdc8d8SChris Lattner 
1155b9c1b51eSKate Stone uint32_t SBThread::GetNumFrames() {
1156baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBThread, GetNumFrames);
1157baf5664fSJonas Devlieghere 
1158ceb6b139SCaroline Tice   uint32_t num_frames = 0;
1159bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1160bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11614fc6cb9cSJim Ingham 
1162b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11637fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1164b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11651ac04c30SGreg Clayton       num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1166c9858e4dSGreg Clayton     }
11677fdf9ef1SGreg Clayton   }
1168ceb6b139SCaroline Tice 
1169ceb6b139SCaroline Tice   return num_frames;
117030fdc8d8SChris Lattner }
117130fdc8d8SChris Lattner 
1172b9c1b51eSKate Stone SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
1173baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBFrame, SBThread, GetFrameAtIndex, (uint32_t), idx);
1174baf5664fSJonas Devlieghere 
117530fdc8d8SChris Lattner   SBFrame sb_frame;
1176b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1177bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1178bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11794fc6cb9cSJim Ingham 
1180b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11817fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1182b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11831ac04c30SGreg Clayton       frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
1184b9556accSGreg Clayton       sb_frame.SetFrameSP(frame_sp);
1185c9858e4dSGreg Clayton     }
11867fdf9ef1SGreg Clayton   }
1187ceb6b139SCaroline Tice 
1188baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_frame);
118930fdc8d8SChris Lattner }
119030fdc8d8SChris Lattner 
1191b9c1b51eSKate Stone lldb::SBFrame SBThread::GetSelectedFrame() {
1192baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBFrame, SBThread, GetSelectedFrame);
1193baf5664fSJonas Devlieghere 
1194f028a1fbSGreg Clayton   SBFrame sb_frame;
1195b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1196bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1197bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11984fc6cb9cSJim Ingham 
1199b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
12007fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1201b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
12021ac04c30SGreg Clayton       frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame();
1203b9556accSGreg Clayton       sb_frame.SetFrameSP(frame_sp);
1204c9858e4dSGreg Clayton     }
12057fdf9ef1SGreg Clayton   }
1206f028a1fbSGreg Clayton 
1207baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_frame);
1208f028a1fbSGreg Clayton }
1209f028a1fbSGreg Clayton 
1210b9c1b51eSKate Stone lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
1211baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBFrame, SBThread, SetSelectedFrame, (uint32_t),
1212baf5664fSJonas Devlieghere                      idx);
1213baf5664fSJonas Devlieghere 
1214f028a1fbSGreg Clayton   SBFrame sb_frame;
1215b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1216bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1217bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12184fc6cb9cSJim Ingham 
1219b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
12207fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1221b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
12221ac04c30SGreg Clayton       Thread *thread = exe_ctx.GetThreadPtr();
12231ac04c30SGreg Clayton       frame_sp = thread->GetStackFrameAtIndex(idx);
1224b9c1b51eSKate Stone       if (frame_sp) {
12251ac04c30SGreg Clayton         thread->SetSelectedFrame(frame_sp.get());
1226b9556accSGreg Clayton         sb_frame.SetFrameSP(frame_sp);
1227f028a1fbSGreg Clayton       }
1228c9858e4dSGreg Clayton     }
12297fdf9ef1SGreg Clayton   }
1230f028a1fbSGreg Clayton 
1231baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_frame);
1232f028a1fbSGreg Clayton }
1233f028a1fbSGreg Clayton 
1234b9c1b51eSKate Stone bool SBThread::EventIsThreadEvent(const SBEvent &event) {
1235baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(bool, SBThread, EventIsThreadEvent,
1236baf5664fSJonas Devlieghere                             (const lldb::SBEvent &), event);
1237baf5664fSJonas Devlieghere 
1238*248a1305SKonrad Kleine   return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != nullptr;
12394f465cffSJim Ingham }
12404f465cffSJim Ingham 
1241b9c1b51eSKate Stone SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) {
1242baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(lldb::SBFrame, SBThread, GetStackFrameFromEvent,
1243baf5664fSJonas Devlieghere                             (const lldb::SBEvent &), event);
1244baf5664fSJonas Devlieghere 
1245baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
1246baf5664fSJonas Devlieghere       Thread::ThreadEventData::GetStackFrameFromEvent(event.get()));
12474f465cffSJim Ingham }
12484f465cffSJim Ingham 
1249b9c1b51eSKate Stone SBThread SBThread::GetThreadFromEvent(const SBEvent &event) {
1250baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(lldb::SBThread, SBThread, GetThreadFromEvent,
1251baf5664fSJonas Devlieghere                             (const lldb::SBEvent &), event);
1252baf5664fSJonas Devlieghere 
1253baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
1254baf5664fSJonas Devlieghere       Thread::ThreadEventData::GetThreadFromEvent(event.get()));
12554f465cffSJim Ingham }
1256f028a1fbSGreg Clayton 
1257b9c1b51eSKate Stone bool SBThread::operator==(const SBThread &rhs) const {
1258baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, operator==,(const lldb::SBThread &),
1259baf5664fSJonas Devlieghere                            rhs);
1260baf5664fSJonas Devlieghere 
1261b9c1b51eSKate Stone   return m_opaque_sp->GetThreadSP().get() ==
1262b9c1b51eSKate Stone          rhs.m_opaque_sp->GetThreadSP().get();
126330fdc8d8SChris Lattner }
126430fdc8d8SChris Lattner 
1265b9c1b51eSKate Stone bool SBThread::operator!=(const SBThread &rhs) const {
1266baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, operator!=,(const lldb::SBThread &),
1267baf5664fSJonas Devlieghere                            rhs);
1268baf5664fSJonas Devlieghere 
1269b9c1b51eSKate Stone   return m_opaque_sp->GetThreadSP().get() !=
1270b9c1b51eSKate Stone          rhs.m_opaque_sp->GetThreadSP().get();
127130fdc8d8SChris Lattner }
1272dde9cff3SCaroline Tice 
1273b9c1b51eSKate Stone bool SBThread::GetStatus(SBStream &status) const {
1274baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetStatus, (lldb::SBStream &),
1275baf5664fSJonas Devlieghere                            status);
1276baf5664fSJonas Devlieghere 
12774f465cffSJim Ingham   Stream &strm = status.ref();
12784f465cffSJim Ingham 
1279b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1280b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1281b2e7d28eSJim Ingham 
1282b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
12836a9767c7SJim Ingham     exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true);
1284b9c1b51eSKate Stone   } else
12854f465cffSJim Ingham     strm.PutCString("No status");
12864f465cffSJim Ingham 
12874f465cffSJim Ingham   return true;
12884f465cffSJim Ingham }
12894f465cffSJim Ingham 
1290b9c1b51eSKate Stone bool SBThread::GetDescription(SBStream &description) const {
1291baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetDescription, (lldb::SBStream &),
1292baf5664fSJonas Devlieghere                            description);
1293baf5664fSJonas Devlieghere 
12946a9767c7SJim Ingham   return GetDescription(description, false);
12956a9767c7SJim Ingham }
12966a9767c7SJim Ingham 
12976a9767c7SJim Ingham bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
1298baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetDescription,
1299baf5664fSJonas Devlieghere                            (lldb::SBStream &, bool), description, stop_format);
1300baf5664fSJonas Devlieghere 
1301da7bc7d0SGreg Clayton   Stream &strm = description.ref();
1302da7bc7d0SGreg Clayton 
1303b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1304b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1305b2e7d28eSJim Ingham 
1306b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1307b9c1b51eSKate Stone     exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm,
13086a9767c7SJim Ingham                                                     LLDB_INVALID_THREAD_ID,
13096a9767c7SJim Ingham                                                     stop_format);
1310b9c1b51eSKate Stone     // strm.Printf("SBThread: tid = 0x%4.4" PRIx64,
1311b9c1b51eSKate Stone     // exe_ctx.GetThreadPtr()->GetID());
1312b9c1b51eSKate Stone   } else
1313da7bc7d0SGreg Clayton     strm.PutCString("No value");
1314ceb6b139SCaroline Tice 
1315ceb6b139SCaroline Tice   return true;
1316ceb6b139SCaroline Tice }
13175dd4916fSJason Molenda 
1318b9c1b51eSKate Stone SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
1319baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBThread, SBThread, GetExtendedBacktraceThread,
1320baf5664fSJonas Devlieghere                      (const char *), type);
1321baf5664fSJonas Devlieghere 
1322bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1323bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
13245dd4916fSJason Molenda   SBThread sb_origin_thread;
13255dd4916fSJason Molenda 
13265dd4916fSJason Molenda   Process::StopLocker stop_locker;
1327b9c1b51eSKate Stone   if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1328b78094abSJim Ingham     if (exe_ctx.HasThreadScope()) {
13297a2f7904SJason Molenda       ThreadSP real_thread(exe_ctx.GetThreadSP());
1330b9c1b51eSKate Stone       if (real_thread) {
13315dd4916fSJason Molenda         ConstString type_const(type);
13327a2f7904SJason Molenda         Process *process = exe_ctx.GetProcessPtr();
1333b9c1b51eSKate Stone         if (process) {
13347a2f7904SJason Molenda           SystemRuntime *runtime = process->GetSystemRuntime();
1335b9c1b51eSKate Stone           if (runtime) {
1336b9c1b51eSKate Stone             ThreadSP new_thread_sp(
1337b9c1b51eSKate Stone                 runtime->GetExtendedBacktraceThread(real_thread, type_const));
1338b9c1b51eSKate Stone             if (new_thread_sp) {
1339b9c1b51eSKate Stone               // Save this in the Process' ExtendedThreadList so a strong
134005097246SAdrian Prantl               // pointer retains the object.
13417a2f7904SJason Molenda               process->GetExtendedThreadList().AddThread(new_thread_sp);
13427a2f7904SJason Molenda               sb_origin_thread.SetThread(new_thread_sp);
1343a6e9130dSJason Molenda             }
1344a6e9130dSJason Molenda           }
13457a2f7904SJason Molenda         }
13465dd4916fSJason Molenda       }
13475dd4916fSJason Molenda     }
13485dd4916fSJason Molenda   }
13495dd4916fSJason Molenda 
1350baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_origin_thread);
13515dd4916fSJason Molenda }
13528ee9cb58SJason Molenda 
1353b9c1b51eSKate Stone uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
1354baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBThread,
1355baf5664fSJonas Devlieghere                              GetExtendedBacktraceOriginatingIndexID);
1356baf5664fSJonas Devlieghere 
13578ee9cb58SJason Molenda   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
13588ee9cb58SJason Molenda   if (thread_sp)
13598ee9cb58SJason Molenda     return thread_sp->GetExtendedBacktraceOriginatingIndexID();
13608ee9cb58SJason Molenda   return LLDB_INVALID_INDEX32;
13618ee9cb58SJason Molenda }
1362b4892cd2SJason Molenda 
1363e60bc53bSKuba Mracek SBValue SBThread::GetCurrentException() {
1364baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBValue, SBThread, GetCurrentException);
1365e60bc53bSKuba Mracek 
1366baf5664fSJonas Devlieghere   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1367baf5664fSJonas Devlieghere   if (!thread_sp)
1368baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(SBValue());
1369baf5664fSJonas Devlieghere 
1370baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(SBValue(thread_sp->GetCurrentException()));
1371e60bc53bSKuba Mracek }
1372e60bc53bSKuba Mracek 
1373e60bc53bSKuba Mracek SBThread SBThread::GetCurrentExceptionBacktrace() {
1374baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBThread, SBThread,
1375baf5664fSJonas Devlieghere                              GetCurrentExceptionBacktrace);
1376e60bc53bSKuba Mracek 
1377baf5664fSJonas Devlieghere   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1378baf5664fSJonas Devlieghere   if (!thread_sp)
1379baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(SBThread());
1380baf5664fSJonas Devlieghere 
1381baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
1382baf5664fSJonas Devlieghere       SBThread(thread_sp->GetCurrentExceptionBacktrace()));
1383c9e1190aSKuba Mracek }
1384e60bc53bSKuba Mracek 
1385b9c1b51eSKate Stone bool SBThread::SafeToCallFunctions() {
1386baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, SafeToCallFunctions);
1387baf5664fSJonas Devlieghere 
1388b4892cd2SJason Molenda   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1389b4892cd2SJason Molenda   if (thread_sp)
1390b4892cd2SJason Molenda     return thread_sp->SafeToCallFunctions();
1391b4892cd2SJason Molenda   return true;
1392b4892cd2SJason Molenda }
13932bdbfd50SJim Ingham 
1394b9c1b51eSKate Stone lldb_private::Thread *SBThread::operator->() {
139526ca5a57SPavel Labath   return get();
13962bdbfd50SJim Ingham }
13972bdbfd50SJim Ingham 
1398b9c1b51eSKate Stone lldb_private::Thread *SBThread::get() {
139926ca5a57SPavel Labath   return m_opaque_sp->GetThreadSP().get();
14002bdbfd50SJim Ingham }
1401ae211eceSMichal Gorny 
1402ae211eceSMichal Gorny namespace lldb_private {
1403ae211eceSMichal Gorny namespace repro {
1404ae211eceSMichal Gorny 
1405ae211eceSMichal Gorny template <>
1406ae211eceSMichal Gorny void RegisterMethods<SBThread>(Registry &R) {
1407ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(const char *, SBThread, GetBroadcasterClassName,
1408ae211eceSMichal Gorny                               ());
1409ae211eceSMichal Gorny   LLDB_REGISTER_CONSTRUCTOR(SBThread, ());
1410ae211eceSMichal Gorny   LLDB_REGISTER_CONSTRUCTOR(SBThread, (const lldb::ThreadSP &));
1411ae211eceSMichal Gorny   LLDB_REGISTER_CONSTRUCTOR(SBThread, (const lldb::SBThread &));
1412ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(const lldb::SBThread &,
1413ae211eceSMichal Gorny                        SBThread, operator=,(const lldb::SBThread &));
1414ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(lldb::SBQueue, SBThread, GetQueue, ());
1415ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, IsValid, ());
1416ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, operator bool, ());
1417ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, Clear, ());
1418ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::StopReason, SBThread, GetStopReason, ());
1419ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(size_t, SBThread, GetStopReasonDataCount, ());
1420ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(uint64_t, SBThread, GetStopReasonDataAtIndex,
1421ae211eceSMichal Gorny                        (uint32_t));
1422ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, GetStopReasonExtendedInfoAsJSON,
1423ae211eceSMichal Gorny                        (lldb::SBStream &));
1424ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBThreadCollection, SBThread,
1425ae211eceSMichal Gorny                        GetStopReasonExtendedBacktraces,
1426ae211eceSMichal Gorny                        (lldb::InstrumentationRuntimeType));
1427ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(size_t, SBThread, GetStopDescription,
1428ae211eceSMichal Gorny                        (char *, size_t));
1429ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBValue, SBThread, GetStopReturnValue, ());
1430ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(lldb::tid_t, SBThread, GetThreadID, ());
1431ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(uint32_t, SBThread, GetIndexID, ());
1432ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(const char *, SBThread, GetName, ());
1433ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(const char *, SBThread, GetQueueName, ());
1434ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(lldb::queue_id_t, SBThread, GetQueueID, ());
1435ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, GetInfoItemByPathAsString,
1436ae211eceSMichal Gorny                        (const char *, lldb::SBStream &));
1437ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOver, (lldb::RunMode));
1438ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOver,
1439ae211eceSMichal Gorny                        (lldb::RunMode, lldb::SBError &));
1440ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInto, (lldb::RunMode));
1441ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInto,
1442ae211eceSMichal Gorny                        (const char *, lldb::RunMode));
1443ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(
1444ae211eceSMichal Gorny       void, SBThread, StepInto,
1445ae211eceSMichal Gorny       (const char *, uint32_t, lldb::SBError &, lldb::RunMode));
1446ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOut, ());
1447ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOut, (lldb::SBError &));
1448ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOutOfFrame, (lldb::SBFrame &));
1449ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOutOfFrame,
1450ae211eceSMichal Gorny                        (lldb::SBFrame &, lldb::SBError &));
1451ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInstruction, (bool));
1452ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInstruction,
1453ae211eceSMichal Gorny                        (bool, lldb::SBError &));
1454ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, RunToAddress, (lldb::addr_t));
1455ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, RunToAddress,
1456ae211eceSMichal Gorny                        (lldb::addr_t, lldb::SBError &));
1457ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepOverUntil,
1458ae211eceSMichal Gorny                        (lldb::SBFrame &, lldb::SBFileSpec &, uint32_t));
1459ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
1460ae211eceSMichal Gorny                        (const char *));
1461ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
1462ae211eceSMichal Gorny                        (const char *, bool));
1463ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, JumpToLine,
1464ae211eceSMichal Gorny                        (lldb::SBFileSpec &, uint32_t));
1465ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, ReturnFromFrame,
1466ae211eceSMichal Gorny                        (lldb::SBFrame &, lldb::SBValue &));
1467ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, UnwindInnermostExpression,
1468ae211eceSMichal Gorny                        ());
1469ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Suspend, ());
1470ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Suspend, (lldb::SBError &));
1471ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Resume, ());
1472ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Resume, (lldb::SBError &));
1473ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, IsSuspended, ());
1474ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, IsStopped, ());
1475ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBProcess, SBThread, GetProcess, ());
1476ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(uint32_t, SBThread, GetNumFrames, ());
1477ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, GetFrameAtIndex, (uint32_t));
1478ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, GetSelectedFrame, ());
1479ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, SetSelectedFrame, (uint32_t));
1480ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(bool, SBThread, EventIsThreadEvent,
1481ae211eceSMichal Gorny                               (const lldb::SBEvent &));
1482ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(lldb::SBFrame, SBThread, GetStackFrameFromEvent,
1483ae211eceSMichal Gorny                               (const lldb::SBEvent &));
1484ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(lldb::SBThread, SBThread, GetThreadFromEvent,
1485ae211eceSMichal Gorny                               (const lldb::SBEvent &));
1486ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool,
1487ae211eceSMichal Gorny                              SBThread, operator==,(const lldb::SBThread &));
1488ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool,
1489ae211eceSMichal Gorny                              SBThread, operator!=,(const lldb::SBThread &));
1490ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetStatus, (lldb::SBStream &));
1491ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetDescription,
1492ae211eceSMichal Gorny                              (lldb::SBStream &));
1493ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetDescription,
1494ae211eceSMichal Gorny                              (lldb::SBStream &, bool));
1495ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBThread, SBThread, GetExtendedBacktraceThread,
1496ae211eceSMichal Gorny                        (const char *));
1497ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(uint32_t, SBThread,
1498ae211eceSMichal Gorny                        GetExtendedBacktraceOriginatingIndexID, ());
1499ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBValue, SBThread, GetCurrentException, ());
1500ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBThread, SBThread, GetCurrentExceptionBacktrace,
1501ae211eceSMichal Gorny                        ());
1502ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, SafeToCallFunctions, ());
1503ae211eceSMichal Gorny }
1504ae211eceSMichal Gorny 
1505ae211eceSMichal Gorny }
1506ae211eceSMichal Gorny }
1507