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"
10*baf5664fSJonas 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() {
53*baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBThread,
54*baf5664fSJonas Devlieghere                                     GetBroadcasterClassName);
55*baf5664fSJonas Devlieghere 
564f465cffSJim Ingham   return Thread::GetStaticBroadcasterClass().AsCString();
574f465cffSJim Ingham }
584f465cffSJim Ingham 
59cfd1acedSGreg Clayton //----------------------------------------------------------------------
60cfd1acedSGreg Clayton // Constructors
61cfd1acedSGreg Clayton //----------------------------------------------------------------------
62*baf5664fSJonas Devlieghere SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {
63*baf5664fSJonas Devlieghere   LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBThread);
64*baf5664fSJonas Devlieghere }
6530fdc8d8SChris Lattner 
66b9c1b51eSKate Stone SBThread::SBThread(const ThreadSP &lldb_object_sp)
67*baf5664fSJonas Devlieghere     : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {
68*baf5664fSJonas Devlieghere   LLDB_RECORD_CONSTRUCTOR(SBThread, (const lldb::ThreadSP &), lldb_object_sp);
69*baf5664fSJonas Devlieghere }
7030fdc8d8SChris Lattner 
71bd4bf82aSJonas Devlieghere SBThread::SBThread(const SBThread &rhs) : m_opaque_sp() {
72*baf5664fSJonas Devlieghere   LLDB_RECORD_CONSTRUCTOR(SBThread, (const lldb::SBThread &), rhs);
73*baf5664fSJonas Devlieghere 
74bd4bf82aSJonas Devlieghere   m_opaque_sp = clone(rhs.m_opaque_sp);
75bd4bf82aSJonas Devlieghere }
7630fdc8d8SChris Lattner 
7730fdc8d8SChris Lattner //----------------------------------------------------------------------
78cfd1acedSGreg Clayton // Assignment operator
79cfd1acedSGreg Clayton //----------------------------------------------------------------------
80cfd1acedSGreg Clayton 
81b9c1b51eSKate Stone const lldb::SBThread &SBThread::operator=(const SBThread &rhs) {
82*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(const lldb::SBThread &,
83*baf5664fSJonas Devlieghere                      SBThread, operator=,(const lldb::SBThread &), rhs);
84*baf5664fSJonas Devlieghere 
85cfd1acedSGreg Clayton   if (this != &rhs)
86bd4bf82aSJonas Devlieghere     m_opaque_sp = clone(rhs.m_opaque_sp);
87cfd1acedSGreg Clayton   return *this;
88cfd1acedSGreg Clayton }
89cfd1acedSGreg Clayton 
90cfd1acedSGreg Clayton //----------------------------------------------------------------------
9130fdc8d8SChris Lattner // Destructor
9230fdc8d8SChris Lattner //----------------------------------------------------------------------
93b9c1b51eSKate Stone SBThread::~SBThread() {}
9430fdc8d8SChris Lattner 
95b9c1b51eSKate Stone lldb::SBQueue SBThread::GetQueue() const {
96*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBQueue, SBThread, GetQueue);
97*baf5664fSJonas Devlieghere 
98b9ffa98cSJason Molenda   SBQueue sb_queue;
99b9ffa98cSJason Molenda   QueueSP queue_sp;
100bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
101bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
102b9ffa98cSJason Molenda 
103b9ffa98cSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
104b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
105b9ffa98cSJason Molenda     Process::StopLocker stop_locker;
106b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
107b9ffa98cSJason Molenda       queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
108b9c1b51eSKate Stone       if (queue_sp) {
109b9ffa98cSJason Molenda         sb_queue.SetQueue(queue_sp);
110b9ffa98cSJason Molenda       }
111b9c1b51eSKate Stone     } else {
112b9ffa98cSJason Molenda       if (log)
113358cf1eaSGreg Clayton         log->Printf("SBThread(%p)::GetQueue() => error: process is running",
114b9ffa98cSJason Molenda                     static_cast<void *>(exe_ctx.GetThreadPtr()));
115b9ffa98cSJason Molenda     }
116b9ffa98cSJason Molenda   }
117b9ffa98cSJason Molenda 
118b9ffa98cSJason Molenda   if (log)
119358cf1eaSGreg Clayton     log->Printf("SBThread(%p)::GetQueue () => SBQueue(%p)",
120b9c1b51eSKate Stone                 static_cast<void *>(exe_ctx.GetThreadPtr()),
121b9c1b51eSKate Stone                 static_cast<void *>(queue_sp.get()));
122b9ffa98cSJason Molenda 
123*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_queue);
124b9ffa98cSJason Molenda }
125b9ffa98cSJason Molenda 
126b9c1b51eSKate Stone bool SBThread::IsValid() const {
127*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThread, IsValid);
128*baf5664fSJonas Devlieghere 
129bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
130bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1317fa7dc36SJim Ingham 
1327fa7dc36SJim Ingham   Target *target = exe_ctx.GetTargetPtr();
1337fa7dc36SJim Ingham   Process *process = exe_ctx.GetProcessPtr();
134b9c1b51eSKate Stone   if (target && process) {
1357fa7dc36SJim Ingham     Process::StopLocker stop_locker;
1367fa7dc36SJim Ingham     if (stop_locker.TryLock(&process->GetRunLock()))
1377fdf9ef1SGreg Clayton       return m_opaque_sp->GetThreadSP().get() != NULL;
13830fdc8d8SChris Lattner   }
1397fa7dc36SJim Ingham   // Without a valid target & process, this thread can't be valid.
1407fa7dc36SJim Ingham   return false;
1417fa7dc36SJim Ingham }
14230fdc8d8SChris Lattner 
143*baf5664fSJonas Devlieghere void SBThread::Clear() {
144*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(void, SBThread, Clear);
145*baf5664fSJonas Devlieghere 
146*baf5664fSJonas Devlieghere   m_opaque_sp->Clear();
147*baf5664fSJonas Devlieghere }
14848e42549SGreg Clayton 
149b9c1b51eSKate Stone StopReason SBThread::GetStopReason() {
150*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::StopReason, SBThread, GetStopReason);
151*baf5664fSJonas Devlieghere 
1525160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
153ceb6b139SCaroline Tice 
154ceb6b139SCaroline Tice   StopReason reason = eStopReasonInvalid;
155bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
156bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1574fc6cb9cSJim Ingham 
158b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1597fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
160b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
16197d5cf05SGreg Clayton       return exe_ctx.GetThreadPtr()->GetStopReason();
162b9c1b51eSKate Stone     } else {
163c9858e4dSGreg Clayton       if (log)
164b9c1b51eSKate Stone         log->Printf(
165b9c1b51eSKate Stone             "SBThread(%p)::GetStopReason() => error: process is running",
166324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
167c9858e4dSGreg Clayton     }
1687fdf9ef1SGreg Clayton   }
169ceb6b139SCaroline Tice 
170ceb6b139SCaroline Tice   if (log)
171324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetStopReason () => %s",
172324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
173750cd175SCaroline Tice                 Thread::StopReasonAsCString(reason));
174ceb6b139SCaroline Tice 
175ceb6b139SCaroline Tice   return reason;
17630fdc8d8SChris Lattner }
17730fdc8d8SChris Lattner 
178b9c1b51eSKate Stone size_t SBThread::GetStopReasonDataCount() {
179*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(size_t, SBThread, GetStopReasonDataCount);
180*baf5664fSJonas Devlieghere 
181bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
182bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1834fc6cb9cSJim Ingham 
184b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1857fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
186b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1871ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
188b9c1b51eSKate Stone       if (stop_info_sp) {
1894e78f606SGreg Clayton         StopReason reason = stop_info_sp->GetStopReason();
190b9c1b51eSKate Stone         switch (reason) {
1914e78f606SGreg Clayton         case eStopReasonInvalid:
1924e78f606SGreg Clayton         case eStopReasonNone:
1934e78f606SGreg Clayton         case eStopReasonTrace:
19490ba8115SGreg Clayton         case eStopReasonExec:
1954e78f606SGreg Clayton         case eStopReasonPlanComplete:
196f85defaeSAndrew Kaylor         case eStopReasonThreadExiting:
197afdf842bSKuba Brecka         case eStopReasonInstrumentation:
1984e78f606SGreg Clayton           // There is no data for these stop reasons.
1994e78f606SGreg Clayton           return 0;
2004e78f606SGreg Clayton 
201b9c1b51eSKate Stone         case eStopReasonBreakpoint: {
2024e78f606SGreg Clayton           break_id_t site_id = stop_info_sp->GetValue();
203b9c1b51eSKate Stone           lldb::BreakpointSiteSP bp_site_sp(
204b9c1b51eSKate Stone               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
205b9c1b51eSKate Stone                   site_id));
2064e78f606SGreg Clayton           if (bp_site_sp)
2074e78f606SGreg Clayton             return bp_site_sp->GetNumberOfOwners() * 2;
2084e78f606SGreg Clayton           else
2094e78f606SGreg Clayton             return 0; // Breakpoint must have cleared itself...
210b9c1b51eSKate Stone         } break;
2114e78f606SGreg Clayton 
2124e78f606SGreg Clayton         case eStopReasonWatchpoint:
213290fa41bSJohnny Chen           return 1;
2144e78f606SGreg Clayton 
2154e78f606SGreg Clayton         case eStopReasonSignal:
2164e78f606SGreg Clayton           return 1;
2174e78f606SGreg Clayton 
2184e78f606SGreg Clayton         case eStopReasonException:
2194e78f606SGreg Clayton           return 1;
2204e78f606SGreg Clayton         }
2214e78f606SGreg Clayton       }
222b9c1b51eSKate Stone     } else {
2235160ce5cSGreg Clayton       Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
224c9858e4dSGreg Clayton       if (log)
225b9c1b51eSKate Stone         log->Printf("SBThread(%p)::GetStopReasonDataCount() => error: process "
226b9c1b51eSKate Stone                     "is running",
227324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
228c9858e4dSGreg Clayton     }
2297fdf9ef1SGreg Clayton   }
2304e78f606SGreg Clayton   return 0;
2314e78f606SGreg Clayton }
2324e78f606SGreg Clayton 
233b9c1b51eSKate Stone uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
234*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(uint64_t, SBThread, GetStopReasonDataAtIndex, (uint32_t),
235*baf5664fSJonas Devlieghere                      idx);
236*baf5664fSJonas Devlieghere 
237bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
238bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
2394fc6cb9cSJim Ingham 
240b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
2417fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
242b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
2431ac04c30SGreg Clayton       Thread *thread = exe_ctx.GetThreadPtr();
2441ac04c30SGreg Clayton       StopInfoSP stop_info_sp = thread->GetStopInfo();
245b9c1b51eSKate Stone       if (stop_info_sp) {
2464e78f606SGreg Clayton         StopReason reason = stop_info_sp->GetStopReason();
247b9c1b51eSKate Stone         switch (reason) {
2484e78f606SGreg Clayton         case eStopReasonInvalid:
2494e78f606SGreg Clayton         case eStopReasonNone:
2504e78f606SGreg Clayton         case eStopReasonTrace:
25190ba8115SGreg Clayton         case eStopReasonExec:
2524e78f606SGreg Clayton         case eStopReasonPlanComplete:
253f85defaeSAndrew Kaylor         case eStopReasonThreadExiting:
254afdf842bSKuba Brecka         case eStopReasonInstrumentation:
2554e78f606SGreg Clayton           // There is no data for these stop reasons.
2564e78f606SGreg Clayton           return 0;
2574e78f606SGreg Clayton 
258b9c1b51eSKate Stone         case eStopReasonBreakpoint: {
2594e78f606SGreg Clayton           break_id_t site_id = stop_info_sp->GetValue();
260b9c1b51eSKate Stone           lldb::BreakpointSiteSP bp_site_sp(
261b9c1b51eSKate Stone               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
262b9c1b51eSKate Stone                   site_id));
263b9c1b51eSKate Stone           if (bp_site_sp) {
2644e78f606SGreg Clayton             uint32_t bp_index = idx / 2;
265b9c1b51eSKate Stone             BreakpointLocationSP bp_loc_sp(
266b9c1b51eSKate Stone                 bp_site_sp->GetOwnerAtIndex(bp_index));
267b9c1b51eSKate Stone             if (bp_loc_sp) {
268b9c1b51eSKate Stone               if (idx & 1) {
2694e78f606SGreg Clayton                 // Odd idx, return the breakpoint location ID
2704e78f606SGreg Clayton                 return bp_loc_sp->GetID();
271b9c1b51eSKate Stone               } else {
2724e78f606SGreg Clayton                 // Even idx, return the breakpoint ID
2734e78f606SGreg Clayton                 return bp_loc_sp->GetBreakpoint().GetID();
2744e78f606SGreg Clayton               }
2754e78f606SGreg Clayton             }
2764e78f606SGreg Clayton           }
2774e78f606SGreg Clayton           return LLDB_INVALID_BREAK_ID;
278b9c1b51eSKate Stone         } break;
2794e78f606SGreg Clayton 
2804e78f606SGreg Clayton         case eStopReasonWatchpoint:
281290fa41bSJohnny Chen           return stop_info_sp->GetValue();
2824e78f606SGreg Clayton 
2834e78f606SGreg Clayton         case eStopReasonSignal:
2844e78f606SGreg Clayton           return stop_info_sp->GetValue();
2854e78f606SGreg Clayton 
2864e78f606SGreg Clayton         case eStopReasonException:
2874e78f606SGreg Clayton           return stop_info_sp->GetValue();
2884e78f606SGreg Clayton         }
2894e78f606SGreg Clayton       }
290b9c1b51eSKate Stone     } else {
2915160ce5cSGreg Clayton       Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
292c9858e4dSGreg Clayton       if (log)
293b9c1b51eSKate Stone         log->Printf("SBThread(%p)::GetStopReasonDataAtIndex() => error: "
294b9c1b51eSKate Stone                     "process is running",
295324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
296c9858e4dSGreg Clayton     }
2977fdf9ef1SGreg Clayton   }
2984e78f606SGreg Clayton   return 0;
2994e78f606SGreg Clayton }
3004e78f606SGreg Clayton 
301b9c1b51eSKate Stone bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) {
302*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, GetStopReasonExtendedInfoAsJSON,
303*baf5664fSJonas Devlieghere                      (lldb::SBStream &), stream);
304*baf5664fSJonas Devlieghere 
305afdf842bSKuba Brecka   Stream &strm = stream.ref();
306afdf842bSKuba Brecka 
307b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
308b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
309b2e7d28eSJim Ingham 
310afdf842bSKuba Brecka   if (!exe_ctx.HasThreadScope())
311afdf842bSKuba Brecka     return false;
312afdf842bSKuba Brecka 
313afdf842bSKuba Brecka   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
314afdf842bSKuba Brecka   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
315afdf842bSKuba Brecka   if (!info)
316afdf842bSKuba Brecka     return false;
317afdf842bSKuba Brecka 
318afdf842bSKuba Brecka   info->Dump(strm);
319afdf842bSKuba Brecka 
320afdf842bSKuba Brecka   return true;
321afdf842bSKuba Brecka }
322afdf842bSKuba Brecka 
3236a831436SKuba Brecka SBThreadCollection
324b9c1b51eSKate Stone SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
325*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBThreadCollection, SBThread,
326*baf5664fSJonas Devlieghere                      GetStopReasonExtendedBacktraces,
327*baf5664fSJonas Devlieghere                      (lldb::InstrumentationRuntimeType), type);
328*baf5664fSJonas Devlieghere 
3296a831436SKuba Brecka   ThreadCollectionSP threads;
330796ac80bSJonas Devlieghere   threads = std::make_shared<ThreadCollection>();
3316a831436SKuba Brecka 
332b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
333b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
334b2e7d28eSJim Ingham 
3356a831436SKuba Brecka   if (!exe_ctx.HasThreadScope())
336*baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(threads);
3376a831436SKuba Brecka 
3386a831436SKuba Brecka   ProcessSP process_sp = exe_ctx.GetProcessSP();
3396a831436SKuba Brecka 
3406a831436SKuba Brecka   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
3416a831436SKuba Brecka   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
3426a831436SKuba Brecka   if (!info)
343*baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(threads);
3446a831436SKuba Brecka 
345*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(process_sp->GetInstrumentationRuntime(type)
346*baf5664fSJonas Devlieghere                                 ->GetBacktracesFromExtendedStopInfo(info));
3476a831436SKuba Brecka }
3486a831436SKuba Brecka 
349b9c1b51eSKate Stone size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
350*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(size_t, SBThread, GetStopDescription, (char *, size_t),
351*baf5664fSJonas Devlieghere                      dst, dst_len);
352*baf5664fSJonas Devlieghere 
3535160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
354ceb6b139SCaroline Tice 
355bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
356bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3574fc6cb9cSJim Ingham 
358b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
3597fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
360b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
3617fdf9ef1SGreg Clayton 
3621ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
363b9c1b51eSKate Stone       if (stop_info_sp) {
364b15bfc75SJim Ingham         const char *stop_desc = stop_info_sp->GetDescription();
365b9c1b51eSKate Stone         if (stop_desc) {
366ceb6b139SCaroline Tice           if (log)
367b9c1b51eSKate Stone             log->Printf(
368b9c1b51eSKate Stone                 "SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
369b9c1b51eSKate Stone                 static_cast<void *>(exe_ctx.GetThreadPtr()), stop_desc);
37030fdc8d8SChris Lattner           if (dst)
37130fdc8d8SChris Lattner             return ::snprintf(dst, dst_len, "%s", stop_desc);
372b9c1b51eSKate Stone           else {
373b9c1b51eSKate Stone             // NULL dst passed in, return the length needed to contain the
374b9c1b51eSKate Stone             // description
37530fdc8d8SChris Lattner             return ::strlen(stop_desc) + 1; // Include the NULL byte for size
37630fdc8d8SChris Lattner           }
377b9c1b51eSKate Stone         } else {
37830fdc8d8SChris Lattner           size_t stop_desc_len = 0;
379b9c1b51eSKate Stone           switch (stop_info_sp->GetStopReason()) {
38030fdc8d8SChris Lattner           case eStopReasonTrace:
381b9c1b51eSKate Stone           case eStopReasonPlanComplete: {
38230fdc8d8SChris Lattner             static char trace_desc[] = "step";
38330fdc8d8SChris Lattner             stop_desc = trace_desc;
384b9c1b51eSKate Stone             stop_desc_len =
385b9c1b51eSKate Stone                 sizeof(trace_desc); // Include the NULL byte for size
386b9c1b51eSKate Stone           } break;
38730fdc8d8SChris Lattner 
388b9c1b51eSKate Stone           case eStopReasonBreakpoint: {
38930fdc8d8SChris Lattner             static char bp_desc[] = "breakpoint hit";
39030fdc8d8SChris Lattner             stop_desc = bp_desc;
39130fdc8d8SChris Lattner             stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
392b9c1b51eSKate Stone           } break;
39330fdc8d8SChris Lattner 
394b9c1b51eSKate Stone           case eStopReasonWatchpoint: {
39530fdc8d8SChris Lattner             static char wp_desc[] = "watchpoint hit";
39630fdc8d8SChris Lattner             stop_desc = wp_desc;
39730fdc8d8SChris Lattner             stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
398b9c1b51eSKate Stone           } break;
39930fdc8d8SChris Lattner 
400b9c1b51eSKate Stone           case eStopReasonSignal: {
401b9c1b51eSKate Stone             stop_desc =
402b9c1b51eSKate Stone                 exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString(
403b9c1b51eSKate Stone                     stop_info_sp->GetValue());
404b9c1b51eSKate Stone             if (stop_desc == NULL || stop_desc[0] == '\0') {
40530fdc8d8SChris Lattner               static char signal_desc[] = "signal";
40630fdc8d8SChris Lattner               stop_desc = signal_desc;
407b9c1b51eSKate Stone               stop_desc_len =
408b9c1b51eSKate Stone                   sizeof(signal_desc); // Include the NULL byte for size
40930fdc8d8SChris Lattner             }
410b9c1b51eSKate Stone           } break;
41130fdc8d8SChris Lattner 
412b9c1b51eSKate Stone           case eStopReasonException: {
41330fdc8d8SChris Lattner             char exc_desc[] = "exception";
41430fdc8d8SChris Lattner             stop_desc = exc_desc;
41530fdc8d8SChris Lattner             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
416b9c1b51eSKate Stone           } break;
417c982c768SGreg Clayton 
418b9c1b51eSKate Stone           case eStopReasonExec: {
41990ba8115SGreg Clayton             char exc_desc[] = "exec";
42090ba8115SGreg Clayton             stop_desc = exc_desc;
42190ba8115SGreg Clayton             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
422b9c1b51eSKate Stone           } break;
42390ba8115SGreg Clayton 
424b9c1b51eSKate Stone           case eStopReasonThreadExiting: {
425f85defaeSAndrew Kaylor             char limbo_desc[] = "thread exiting";
426f85defaeSAndrew Kaylor             stop_desc = limbo_desc;
427f85defaeSAndrew Kaylor             stop_desc_len = sizeof(limbo_desc);
428b9c1b51eSKate Stone           } break;
429c982c768SGreg Clayton           default:
430c982c768SGreg Clayton             break;
43130fdc8d8SChris Lattner           }
43230fdc8d8SChris Lattner 
433b9c1b51eSKate Stone           if (stop_desc && stop_desc[0]) {
434ceb6b139SCaroline Tice             if (log)
435b9c1b51eSKate Stone               log->Printf(
436b9c1b51eSKate Stone                   "SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
437b9c1b51eSKate Stone                   static_cast<void *>(exe_ctx.GetThreadPtr()), stop_desc);
438ceb6b139SCaroline Tice 
43930fdc8d8SChris Lattner             if (dst)
440b9c1b51eSKate Stone               return ::snprintf(dst, dst_len, "%s", stop_desc) +
441b9c1b51eSKate Stone                      1; // Include the NULL byte
44230fdc8d8SChris Lattner 
44330fdc8d8SChris Lattner             if (stop_desc_len == 0)
44430fdc8d8SChris Lattner               stop_desc_len = ::strlen(stop_desc) + 1; // Include the NULL byte
44530fdc8d8SChris Lattner 
44630fdc8d8SChris Lattner             return stop_desc_len;
44730fdc8d8SChris Lattner           }
44830fdc8d8SChris Lattner         }
44930fdc8d8SChris Lattner       }
450b9c1b51eSKate Stone     } else {
4515160ce5cSGreg Clayton       Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
452c9858e4dSGreg Clayton       if (log)
453b9c1b51eSKate Stone         log->Printf(
454b9c1b51eSKate Stone             "SBThread(%p)::GetStopDescription() => error: process is running",
455324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
456c9858e4dSGreg Clayton     }
4577fdf9ef1SGreg Clayton   }
45830fdc8d8SChris Lattner   if (dst)
45930fdc8d8SChris Lattner     *dst = 0;
46030fdc8d8SChris Lattner   return 0;
46130fdc8d8SChris Lattner }
46230fdc8d8SChris Lattner 
463b9c1b51eSKate Stone SBValue SBThread::GetStopReturnValue() {
464*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBValue, SBThread, GetStopReturnValue);
465*baf5664fSJonas Devlieghere 
4665160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
46773ca05a2SJim Ingham   ValueObjectSP return_valobj_sp;
468bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
469bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4704fc6cb9cSJim Ingham 
471b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4727fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
473b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4741ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
475b9c1b51eSKate Stone       if (stop_info_sp) {
47673ca05a2SJim Ingham         return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp);
47773ca05a2SJim Ingham       }
478b9c1b51eSKate Stone     } else {
479c9858e4dSGreg Clayton       if (log)
480b9c1b51eSKate Stone         log->Printf(
481b9c1b51eSKate Stone             "SBThread(%p)::GetStopReturnValue() => error: process is running",
482324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
483c9858e4dSGreg Clayton     }
4847fdf9ef1SGreg Clayton   }
48573ca05a2SJim Ingham 
48673ca05a2SJim Ingham   if (log)
487324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetStopReturnValue () => %s",
488324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
489b9c1b51eSKate Stone                 return_valobj_sp.get() ? return_valobj_sp->GetValueAsCString()
49073ca05a2SJim Ingham                                        : "<no return value>");
49173ca05a2SJim Ingham 
492*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(SBValue(return_valobj_sp));
49373ca05a2SJim Ingham }
49473ca05a2SJim Ingham 
495b9c1b51eSKate Stone void SBThread::SetThread(const ThreadSP &lldb_object_sp) {
4967fdf9ef1SGreg Clayton   m_opaque_sp->SetThreadSP(lldb_object_sp);
49730fdc8d8SChris Lattner }
49830fdc8d8SChris Lattner 
499b9c1b51eSKate Stone lldb::tid_t SBThread::GetThreadID() const {
500*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::tid_t, SBThread, GetThreadID);
501*baf5664fSJonas Devlieghere 
5027fdf9ef1SGreg Clayton   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
50317a6ad05SGreg Clayton   if (thread_sp)
5041ac04c30SGreg Clayton     return thread_sp->GetID();
5051ac04c30SGreg Clayton   return LLDB_INVALID_THREAD_ID;
50630fdc8d8SChris Lattner }
50730fdc8d8SChris Lattner 
508b9c1b51eSKate Stone uint32_t SBThread::GetIndexID() const {
509*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBThread, GetIndexID);
510*baf5664fSJonas Devlieghere 
5117fdf9ef1SGreg Clayton   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
51217a6ad05SGreg Clayton   if (thread_sp)
51317a6ad05SGreg Clayton     return thread_sp->GetIndexID();
51430fdc8d8SChris Lattner   return LLDB_INVALID_INDEX32;
51530fdc8d8SChris Lattner }
5161ac04c30SGreg Clayton 
517b9c1b51eSKate Stone const char *SBThread::GetName() const {
518*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBThread, GetName);
519*baf5664fSJonas Devlieghere 
5205160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
5214838131bSGreg Clayton   const char *name = NULL;
522bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
523bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
5244fc6cb9cSJim Ingham 
525b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
5267fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
527b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
5281ac04c30SGreg Clayton       name = exe_ctx.GetThreadPtr()->GetName();
529b9c1b51eSKate Stone     } else {
530c9858e4dSGreg Clayton       if (log)
531324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::GetName() => error: process is running",
532324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
533c9858e4dSGreg Clayton     }
5347fdf9ef1SGreg Clayton   }
535ceb6b139SCaroline Tice 
536ceb6b139SCaroline Tice   if (log)
537324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetName () => %s",
538324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
539324a1036SSaleem Abdulrasool                 name ? name : "NULL");
540ceb6b139SCaroline Tice 
5414838131bSGreg Clayton   return name;
54230fdc8d8SChris Lattner }
54330fdc8d8SChris Lattner 
544b9c1b51eSKate Stone const char *SBThread::GetQueueName() const {
545*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBThread, GetQueueName);
546*baf5664fSJonas Devlieghere 
5474838131bSGreg Clayton   const char *name = NULL;
548bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
549bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
5504fc6cb9cSJim Ingham 
5515160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
552b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
5537fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
554b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
5551ac04c30SGreg Clayton       name = exe_ctx.GetThreadPtr()->GetQueueName();
556b9c1b51eSKate Stone     } else {
557c9858e4dSGreg Clayton       if (log)
558324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::GetQueueName() => error: process is running",
559324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
560c9858e4dSGreg Clayton     }
5617fdf9ef1SGreg Clayton   }
562ceb6b139SCaroline Tice 
563ceb6b139SCaroline Tice   if (log)
564324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetQueueName () => %s",
565324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
566324a1036SSaleem Abdulrasool                 name ? name : "NULL");
567ceb6b139SCaroline Tice 
5684838131bSGreg Clayton   return name;
56930fdc8d8SChris Lattner }
57030fdc8d8SChris Lattner 
571b9c1b51eSKate Stone lldb::queue_id_t SBThread::GetQueueID() const {
572*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::queue_id_t, SBThread, GetQueueID);
573*baf5664fSJonas Devlieghere 
5744fdb5863SJason Molenda   queue_id_t id = LLDB_INVALID_QUEUE_ID;
575bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
576bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
5774fdb5863SJason Molenda 
5784fdb5863SJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
579b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
5804fdb5863SJason Molenda     Process::StopLocker stop_locker;
581b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
5824fdb5863SJason Molenda       id = exe_ctx.GetThreadPtr()->GetQueueID();
583b9c1b51eSKate Stone     } else {
5844fdb5863SJason Molenda       if (log)
585324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::GetQueueID() => error: process is running",
586324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
5874fdb5863SJason Molenda     }
5884fdb5863SJason Molenda   }
5894fdb5863SJason Molenda 
5904fdb5863SJason Molenda   if (log)
591324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetQueueID () => 0x%" PRIx64,
592324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), id);
5934fdb5863SJason Molenda 
5944fdb5863SJason Molenda   return id;
5954fdb5863SJason Molenda }
5964fdb5863SJason Molenda 
597b9c1b51eSKate Stone bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
598*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, GetInfoItemByPathAsString,
599*baf5664fSJonas Devlieghere                      (const char *, lldb::SBStream &), path, strm);
600*baf5664fSJonas Devlieghere 
601705b1809SJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
602705b1809SJason Molenda   bool success = false;
603bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
604bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
605705b1809SJason Molenda 
606b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
607705b1809SJason Molenda     Process::StopLocker stop_locker;
608b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
609705b1809SJason Molenda       Thread *thread = exe_ctx.GetThreadPtr();
610705b1809SJason Molenda       StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
611b9c1b51eSKate Stone       if (info_root_sp) {
612b9c1b51eSKate Stone         StructuredData::ObjectSP node =
613b9c1b51eSKate Stone             info_root_sp->GetObjectForDotSeparatedPath(path);
614b9c1b51eSKate Stone         if (node) {
6155bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeString) {
6162833321fSZachary Turner             strm.Printf("%s", node->GetAsString()->GetValue().str().c_str());
617705b1809SJason Molenda             success = true;
618705b1809SJason Molenda           }
6195bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeInteger) {
620705b1809SJason Molenda             strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue());
621705b1809SJason Molenda             success = true;
622705b1809SJason Molenda           }
6235bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeFloat) {
624705b1809SJason Molenda             strm.Printf("0x%f", node->GetAsFloat()->GetValue());
625705b1809SJason Molenda             success = true;
626705b1809SJason Molenda           }
6275bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeBoolean) {
628a6682a41SJonas Devlieghere             if (node->GetAsBoolean()->GetValue())
629705b1809SJason Molenda               strm.Printf("true");
630705b1809SJason Molenda             else
631705b1809SJason Molenda               strm.Printf("false");
632705b1809SJason Molenda             success = true;
633705b1809SJason Molenda           }
6345bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeNull) {
635705b1809SJason Molenda             strm.Printf("null");
636705b1809SJason Molenda             success = true;
637705b1809SJason Molenda           }
638705b1809SJason Molenda         }
639705b1809SJason Molenda       }
640b9c1b51eSKate Stone     } else {
641705b1809SJason Molenda       if (log)
642b9c1b51eSKate Stone         log->Printf("SBThread(%p)::GetInfoItemByPathAsString() => error: "
643b9c1b51eSKate Stone                     "process is running",
644705b1809SJason Molenda                     static_cast<void *>(exe_ctx.GetThreadPtr()));
645705b1809SJason Molenda     }
646705b1809SJason Molenda   }
647705b1809SJason Molenda 
648705b1809SJason Molenda   if (log)
649753e13c0SJason Molenda     log->Printf("SBThread(%p)::GetInfoItemByPathAsString (\"%s\") => \"%s\"",
650753e13c0SJason Molenda                 static_cast<void *>(exe_ctx.GetThreadPtr()), path, strm.GetData());
651705b1809SJason Molenda 
652705b1809SJason Molenda   return success;
653705b1809SJason Molenda }
654705b1809SJason Molenda 
655b9c1b51eSKate Stone SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
656b9c1b51eSKate Stone                                 ThreadPlan *new_plan) {
65764e7ead1SJim Ingham   SBError sb_error;
65864e7ead1SJim Ingham 
65964e7ead1SJim Ingham   Process *process = exe_ctx.GetProcessPtr();
660b9c1b51eSKate Stone   if (!process) {
66164e7ead1SJim Ingham     sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
66264e7ead1SJim Ingham     return sb_error;
66364e7ead1SJim Ingham   }
66464e7ead1SJim Ingham 
66564e7ead1SJim Ingham   Thread *thread = exe_ctx.GetThreadPtr();
666b9c1b51eSKate Stone   if (!thread) {
66764e7ead1SJim Ingham     sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
66864e7ead1SJim Ingham     return sb_error;
66964e7ead1SJim Ingham   }
67064e7ead1SJim Ingham 
671b9c1b51eSKate Stone   // User level plans should be Master Plans so they can be interrupted, other
67205097246SAdrian Prantl   // plans executed, and then a "continue" will resume the plan.
673b9c1b51eSKate Stone   if (new_plan != NULL) {
67464e7ead1SJim Ingham     new_plan->SetIsMasterPlan(true);
67564e7ead1SJim Ingham     new_plan->SetOkayToDiscard(false);
67664e7ead1SJim Ingham   }
67764e7ead1SJim Ingham 
67864e7ead1SJim Ingham   // Why do we need to set the current thread by ID here???
67964e7ead1SJim Ingham   process->GetThreadList().SetSelectedThreadByID(thread->GetID());
68064e7ead1SJim Ingham 
681dc6224e0SGreg Clayton   if (process->GetTarget().GetDebugger().GetAsyncExecution())
682dc6224e0SGreg Clayton     sb_error.ref() = process->Resume();
683dc6224e0SGreg Clayton   else
684dc6224e0SGreg Clayton     sb_error.ref() = process->ResumeSynchronous(NULL);
68564e7ead1SJim Ingham 
68664e7ead1SJim Ingham   return sb_error;
68764e7ead1SJim Ingham }
68830fdc8d8SChris Lattner 
689b9c1b51eSKate Stone void SBThread::StepOver(lldb::RunMode stop_other_threads) {
690*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOver, (lldb::RunMode),
691*baf5664fSJonas Devlieghere                      stop_other_threads);
692*baf5664fSJonas Devlieghere 
693859f54b3SAlexander Polyakov   SBError error; // Ignored
694859f54b3SAlexander Polyakov   StepOver(stop_other_threads, error);
695859f54b3SAlexander Polyakov }
696859f54b3SAlexander Polyakov 
697859f54b3SAlexander Polyakov void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
698*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOver, (lldb::RunMode, lldb::SBError &),
699*baf5664fSJonas Devlieghere                      stop_other_threads, error);
700*baf5664fSJonas Devlieghere 
7015160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
702ceb6b139SCaroline Tice 
703bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
704bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
70517a6ad05SGreg Clayton 
706ceb6b139SCaroline Tice   if (log)
707324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::StepOver (stop_other_threads='%s')",
708324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
709ceb6b139SCaroline Tice                 Thread::RunModeAsCString(stop_other_threads));
710ceb6b139SCaroline Tice 
711859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
712859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
713859f54b3SAlexander Polyakov     return;
714859f54b3SAlexander Polyakov   }
715859f54b3SAlexander Polyakov 
7161ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
7177ba6e991SJim Ingham   bool abort_other_plans = false;
718b57e4a1bSJason Molenda   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
71930fdc8d8SChris Lattner 
720e103ae92SJonas Devlieghere   Status new_plan_status;
7214d56e9c1SJim Ingham   ThreadPlanSP new_plan_sp;
722b9c1b51eSKate Stone   if (frame_sp) {
723b9c1b51eSKate Stone     if (frame_sp->HasDebugInformation()) {
7244b4b2478SJim Ingham       const LazyBool avoid_no_debug = eLazyBoolCalculate;
72530fdc8d8SChris Lattner       SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
726b9c1b51eSKate Stone       new_plan_sp = thread->QueueThreadPlanForStepOverRange(
727b9c1b51eSKate Stone           abort_other_plans, sc.line_entry, sc, stop_other_threads,
728e103ae92SJonas Devlieghere           new_plan_status, avoid_no_debug);
729b9c1b51eSKate Stone     } else {
730b9c1b51eSKate Stone       new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
731e103ae92SJonas Devlieghere           true, abort_other_plans, stop_other_threads, new_plan_status);
73230fdc8d8SChris Lattner     }
73330fdc8d8SChris Lattner   }
734859f54b3SAlexander Polyakov   error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
73530fdc8d8SChris Lattner }
73630fdc8d8SChris Lattner 
737b9c1b51eSKate Stone void SBThread::StepInto(lldb::RunMode stop_other_threads) {
738*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInto, (lldb::RunMode),
739*baf5664fSJonas Devlieghere                      stop_other_threads);
740*baf5664fSJonas Devlieghere 
741c627682eSJim Ingham   StepInto(NULL, stop_other_threads);
742c627682eSJim Ingham }
743c627682eSJim Ingham 
744b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name,
745b9c1b51eSKate Stone                         lldb::RunMode stop_other_threads) {
746*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInto, (const char *, lldb::RunMode),
747*baf5664fSJonas Devlieghere                      target_name, stop_other_threads);
748*baf5664fSJonas Devlieghere 
749859f54b3SAlexander Polyakov   SBError error; // Ignored
750cbf6f9b2SJim Ingham   StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
751cbf6f9b2SJim Ingham }
752cbf6f9b2SJim Ingham 
753b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name, uint32_t end_line,
754b9c1b51eSKate Stone                         SBError &error, lldb::RunMode stop_other_threads) {
755*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInto,
756*baf5664fSJonas Devlieghere                      (const char *, uint32_t, lldb::SBError &, lldb::RunMode),
757*baf5664fSJonas Devlieghere                      target_name, end_line, error, stop_other_threads);
758*baf5664fSJonas Devlieghere 
7595160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
760ceb6b139SCaroline Tice 
761bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
762bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
76317a6ad05SGreg Clayton 
76417a6ad05SGreg Clayton   if (log)
765b9c1b51eSKate Stone     log->Printf(
766b9c1b51eSKate Stone         "SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
767324a1036SSaleem Abdulrasool         static_cast<void *>(exe_ctx.GetThreadPtr()),
768c627682eSJim Ingham         target_name ? target_name : "<NULL>",
76917a6ad05SGreg Clayton         Thread::RunModeAsCString(stop_other_threads));
770c627682eSJim Ingham 
771859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
772859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
773859f54b3SAlexander Polyakov     return;
774859f54b3SAlexander Polyakov   }
775859f54b3SAlexander Polyakov 
7767ba6e991SJim Ingham   bool abort_other_plans = false;
77730fdc8d8SChris Lattner 
7781ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
779b57e4a1bSJason Molenda   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
7804d56e9c1SJim Ingham   ThreadPlanSP new_plan_sp;
781e103ae92SJonas Devlieghere   Status new_plan_status;
78230fdc8d8SChris Lattner 
783b9c1b51eSKate Stone   if (frame_sp && frame_sp->HasDebugInformation()) {
784cbf6f9b2SJim Ingham     SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
785cbf6f9b2SJim Ingham     AddressRange range;
786cbf6f9b2SJim Ingham     if (end_line == LLDB_INVALID_LINE_NUMBER)
787cbf6f9b2SJim Ingham       range = sc.line_entry.range;
788b9c1b51eSKate Stone     else {
789cbf6f9b2SJim Ingham       if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
790cbf6f9b2SJim Ingham         return;
791cbf6f9b2SJim Ingham     }
792cbf6f9b2SJim Ingham 
793b9c1b51eSKate Stone     const LazyBool step_out_avoids_code_without_debug_info =
794b9c1b51eSKate Stone         eLazyBoolCalculate;
795b9c1b51eSKate Stone     const LazyBool step_in_avoids_code_without_debug_info =
796b9c1b51eSKate Stone         eLazyBoolCalculate;
797b9c1b51eSKate Stone     new_plan_sp = thread->QueueThreadPlanForStepInRange(
798b9c1b51eSKate Stone         abort_other_plans, range, sc, target_name, stop_other_threads,
799e103ae92SJonas Devlieghere         new_plan_status, step_in_avoids_code_without_debug_info,
8004b4b2478SJim Ingham         step_out_avoids_code_without_debug_info);
801b9c1b51eSKate Stone   } else {
802b9c1b51eSKate Stone     new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
803e103ae92SJonas Devlieghere         false, abort_other_plans, stop_other_threads, new_plan_status);
80430fdc8d8SChris Lattner   }
805e103ae92SJonas Devlieghere 
806e103ae92SJonas Devlieghere   if (new_plan_status.Success())
807cbf6f9b2SJim Ingham     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
808e103ae92SJonas Devlieghere   else
809e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
81030fdc8d8SChris Lattner }
81130fdc8d8SChris Lattner 
812b9c1b51eSKate Stone void SBThread::StepOut() {
813*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(void, SBThread, StepOut);
814*baf5664fSJonas Devlieghere 
815859f54b3SAlexander Polyakov   SBError error; // Ignored
816859f54b3SAlexander Polyakov   StepOut(error);
817859f54b3SAlexander Polyakov }
818859f54b3SAlexander Polyakov 
819859f54b3SAlexander Polyakov void SBThread::StepOut(SBError &error) {
820*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOut, (lldb::SBError &), error);
821*baf5664fSJonas Devlieghere 
8225160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
823ceb6b139SCaroline Tice 
824bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
825bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
8264fc6cb9cSJim Ingham 
82717a6ad05SGreg Clayton   if (log)
828324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::StepOut ()",
829324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()));
83017a6ad05SGreg Clayton 
831859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
832859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
833859f54b3SAlexander Polyakov     return;
834859f54b3SAlexander Polyakov   }
835859f54b3SAlexander Polyakov 
8367ba6e991SJim Ingham   bool abort_other_plans = false;
83794b09246SJim Ingham   bool stop_other_threads = false;
83830fdc8d8SChris Lattner 
8391ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
8401ac04c30SGreg Clayton 
8414b4b2478SJim Ingham   const LazyBool avoid_no_debug = eLazyBoolCalculate;
842e103ae92SJonas Devlieghere   Status new_plan_status;
843b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
844b9c1b51eSKate Stone       abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
845e103ae92SJonas Devlieghere       eVoteNoOpinion, 0, new_plan_status, avoid_no_debug));
846481cef25SGreg Clayton 
847e103ae92SJonas Devlieghere   if (new_plan_status.Success())
848859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
849e103ae92SJonas Devlieghere   else
850e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
851481cef25SGreg Clayton }
852481cef25SGreg Clayton 
853859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
854*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOutOfFrame, (lldb::SBFrame &),
855*baf5664fSJonas Devlieghere                      sb_frame);
856*baf5664fSJonas Devlieghere 
857859f54b3SAlexander Polyakov   SBError error; // Ignored
858859f54b3SAlexander Polyakov   StepOutOfFrame(sb_frame, error);
859859f54b3SAlexander Polyakov }
860859f54b3SAlexander Polyakov 
861859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
862*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOutOfFrame,
863*baf5664fSJonas Devlieghere                      (lldb::SBFrame &, lldb::SBError &), sb_frame, error);
864*baf5664fSJonas Devlieghere 
8655160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
866481cef25SGreg Clayton 
867bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
868bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
8694fc6cb9cSJim Ingham 
870b9c1b51eSKate Stone   if (!sb_frame.IsValid()) {
871989a7558SJim Ingham     if (log)
872b9c1b51eSKate Stone       log->Printf(
873b9c1b51eSKate Stone           "SBThread(%p)::StepOutOfFrame passed an invalid frame, returning.",
874989a7558SJim Ingham           static_cast<void *>(exe_ctx.GetThreadPtr()));
875859f54b3SAlexander Polyakov     error.SetErrorString("passed invalid SBFrame object");
876989a7558SJim Ingham     return;
877989a7558SJim Ingham   }
878989a7558SJim Ingham 
879b57e4a1bSJason Molenda   StackFrameSP frame_sp(sb_frame.GetFrameSP());
880b9c1b51eSKate Stone   if (log) {
881481cef25SGreg Clayton     SBStream frame_desc_strm;
882481cef25SGreg Clayton     sb_frame.GetDescription(frame_desc_strm);
883324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)",
884324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
885b9c1b51eSKate Stone                 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
886481cef25SGreg Clayton   }
887481cef25SGreg Clayton 
888859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
889859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
890859f54b3SAlexander Polyakov     return;
891859f54b3SAlexander Polyakov   }
892859f54b3SAlexander Polyakov 
8937ba6e991SJim Ingham   bool abort_other_plans = false;
89494b09246SJim Ingham   bool stop_other_threads = false;
8951ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
896b9c1b51eSKate Stone   if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
897b9c1b51eSKate Stone     log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another "
898b9c1b51eSKate Stone                 "thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.",
899989a7558SJim Ingham                 static_cast<void *>(exe_ctx.GetThreadPtr()),
900b9c1b51eSKate Stone                 sb_frame.GetThread().GetThreadID(), thread->GetID());
901859f54b3SAlexander Polyakov     error.SetErrorString("passed a frame from another thread");
902859f54b3SAlexander Polyakov     return;
903989a7558SJim Ingham   }
904481cef25SGreg Clayton 
905e103ae92SJonas Devlieghere   Status new_plan_status;
906b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
907b9c1b51eSKate Stone       abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
908e103ae92SJonas Devlieghere       eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status));
90930fdc8d8SChris Lattner 
910e103ae92SJonas Devlieghere   if (new_plan_status.Success())
911859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
912e103ae92SJonas Devlieghere   else
913e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
91430fdc8d8SChris Lattner }
91530fdc8d8SChris Lattner 
916b9c1b51eSKate Stone void SBThread::StepInstruction(bool step_over) {
917*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInstruction, (bool), step_over);
918*baf5664fSJonas Devlieghere 
919859f54b3SAlexander Polyakov   SBError error; // Ignored
920859f54b3SAlexander Polyakov   StepInstruction(step_over, error);
921859f54b3SAlexander Polyakov }
922859f54b3SAlexander Polyakov 
923859f54b3SAlexander Polyakov void SBThread::StepInstruction(bool step_over, SBError &error) {
924*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInstruction, (bool, lldb::SBError &),
925*baf5664fSJonas Devlieghere                      step_over, error);
926*baf5664fSJonas Devlieghere 
9275160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
928ceb6b139SCaroline Tice 
929bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
930bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
931ceb6b139SCaroline Tice 
93217a6ad05SGreg Clayton   if (log)
933324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::StepInstruction (step_over=%i)",
934324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), step_over);
93517a6ad05SGreg Clayton 
936859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
937859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
938859f54b3SAlexander Polyakov     return;
939859f54b3SAlexander Polyakov   }
940859f54b3SAlexander Polyakov 
9411ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
942e103ae92SJonas Devlieghere   Status new_plan_status;
943e103ae92SJonas Devlieghere   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction(
944e103ae92SJonas Devlieghere       step_over, true, true, new_plan_status));
94564e7ead1SJim Ingham 
946e103ae92SJonas Devlieghere   if (new_plan_status.Success())
947859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
948e103ae92SJonas Devlieghere   else
949e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
95030fdc8d8SChris Lattner }
95130fdc8d8SChris Lattner 
952b9c1b51eSKate Stone void SBThread::RunToAddress(lldb::addr_t addr) {
953*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, RunToAddress, (lldb::addr_t), addr);
954*baf5664fSJonas Devlieghere 
955859f54b3SAlexander Polyakov   SBError error; // Ignored
956859f54b3SAlexander Polyakov   RunToAddress(addr, error);
957859f54b3SAlexander Polyakov }
958859f54b3SAlexander Polyakov 
959859f54b3SAlexander Polyakov void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
960*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, RunToAddress,
961*baf5664fSJonas Devlieghere                      (lldb::addr_t, lldb::SBError &), addr, error);
962*baf5664fSJonas Devlieghere 
9635160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
964ceb6b139SCaroline Tice 
965bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
966bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
967ceb6b139SCaroline Tice 
96817a6ad05SGreg Clayton   if (log)
969324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")",
970324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), addr);
97117a6ad05SGreg Clayton 
972859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
973859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
974859f54b3SAlexander Polyakov     return;
975859f54b3SAlexander Polyakov   }
976859f54b3SAlexander Polyakov 
9777ba6e991SJim Ingham   bool abort_other_plans = false;
97830fdc8d8SChris Lattner   bool stop_other_threads = true;
97930fdc8d8SChris Lattner 
980e72dfb32SGreg Clayton   Address target_addr(addr);
98130fdc8d8SChris Lattner 
9821ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
9831ac04c30SGreg Clayton 
984e103ae92SJonas Devlieghere   Status new_plan_status;
985b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
986e103ae92SJonas Devlieghere       abort_other_plans, target_addr, stop_other_threads, new_plan_status));
98764e7ead1SJim Ingham 
988e103ae92SJonas Devlieghere   if (new_plan_status.Success())
989859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
990e103ae92SJonas Devlieghere   else
991e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
99230fdc8d8SChris Lattner }
99330fdc8d8SChris Lattner 
994b9c1b51eSKate Stone SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
995b9c1b51eSKate Stone                                 lldb::SBFileSpec &sb_file_spec, uint32_t line) {
996*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepOverUntil,
997*baf5664fSJonas Devlieghere                      (lldb::SBFrame &, lldb::SBFileSpec &, uint32_t), sb_frame,
998*baf5664fSJonas Devlieghere                      sb_file_spec, line);
999*baf5664fSJonas Devlieghere 
1000481cef25SGreg Clayton   SBError sb_error;
10015160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1002481cef25SGreg Clayton   char path[PATH_MAX];
1003481cef25SGreg Clayton 
1004bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1005bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
10064fc6cb9cSJim Ingham 
1007b57e4a1bSJason Molenda   StackFrameSP frame_sp(sb_frame.GetFrameSP());
100817a6ad05SGreg Clayton 
1009b9c1b51eSKate Stone   if (log) {
1010481cef25SGreg Clayton     SBStream frame_desc_strm;
1011481cef25SGreg Clayton     sb_frame.GetDescription(frame_desc_strm);
1012481cef25SGreg Clayton     sb_file_spec->GetPath(path, sizeof(path));
1013b9c1b51eSKate Stone     log->Printf("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, "
1014b9c1b51eSKate Stone                 "file+line = %s:%u)",
1015324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
1016b9c1b51eSKate Stone                 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData(),
1017b9c1b51eSKate Stone                 path, line);
1018481cef25SGreg Clayton   }
1019481cef25SGreg Clayton 
1020b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
10211ac04c30SGreg Clayton     Target *target = exe_ctx.GetTargetPtr();
10221ac04c30SGreg Clayton     Thread *thread = exe_ctx.GetThreadPtr();
1023481cef25SGreg Clayton 
1024b9c1b51eSKate Stone     if (line == 0) {
1025481cef25SGreg Clayton       sb_error.SetErrorString("invalid line argument");
1026*baf5664fSJonas Devlieghere       return LLDB_RECORD_RESULT(sb_error);
1027481cef25SGreg Clayton     }
1028481cef25SGreg Clayton 
1029b9c1b51eSKate Stone     if (!frame_sp) {
10301ac04c30SGreg Clayton       frame_sp = thread->GetSelectedFrame();
1031481cef25SGreg Clayton       if (!frame_sp)
10321ac04c30SGreg Clayton         frame_sp = thread->GetStackFrameAtIndex(0);
1033481cef25SGreg Clayton     }
1034481cef25SGreg Clayton 
1035481cef25SGreg Clayton     SymbolContext frame_sc;
1036b9c1b51eSKate Stone     if (!frame_sp) {
1037481cef25SGreg Clayton       sb_error.SetErrorString("no valid frames in thread to step");
1038*baf5664fSJonas Devlieghere       return LLDB_RECORD_RESULT(sb_error);
1039481cef25SGreg Clayton     }
1040481cef25SGreg Clayton 
1041481cef25SGreg Clayton     // If we have a frame, get its line
1042b9c1b51eSKate Stone     frame_sc = frame_sp->GetSymbolContext(
1043b9c1b51eSKate Stone         eSymbolContextCompUnit | eSymbolContextFunction |
1044b9c1b51eSKate Stone         eSymbolContextLineEntry | eSymbolContextSymbol);
1045481cef25SGreg Clayton 
1046b9c1b51eSKate Stone     if (frame_sc.comp_unit == NULL) {
1047b9c1b51eSKate Stone       sb_error.SetErrorStringWithFormat(
1048b9c1b51eSKate Stone           "frame %u doesn't have debug information", frame_sp->GetFrameIndex());
1049*baf5664fSJonas Devlieghere       return LLDB_RECORD_RESULT(sb_error);
1050481cef25SGreg Clayton     }
1051481cef25SGreg Clayton 
1052481cef25SGreg Clayton     FileSpec step_file_spec;
1053b9c1b51eSKate Stone     if (sb_file_spec.IsValid()) {
1054481cef25SGreg Clayton       // The file spec passed in was valid, so use it
1055481cef25SGreg Clayton       step_file_spec = sb_file_spec.ref();
1056b9c1b51eSKate Stone     } else {
1057481cef25SGreg Clayton       if (frame_sc.line_entry.IsValid())
1058481cef25SGreg Clayton         step_file_spec = frame_sc.line_entry.file;
1059b9c1b51eSKate Stone       else {
1060481cef25SGreg Clayton         sb_error.SetErrorString("invalid file argument or no file for frame");
1061*baf5664fSJonas Devlieghere         return LLDB_RECORD_RESULT(sb_error);
1062481cef25SGreg Clayton       }
1063481cef25SGreg Clayton     }
1064481cef25SGreg Clayton 
10659b70ddb3SJim Ingham     // Grab the current function, then we will make sure the "until" address is
10669b70ddb3SJim Ingham     // within the function.  We discard addresses that are out of the current
1067b9c1b51eSKate Stone     // function, and then if there are no addresses remaining, give an
106805097246SAdrian Prantl     // appropriate error message.
10699b70ddb3SJim Ingham 
10709b70ddb3SJim Ingham     bool all_in_function = true;
10719b70ddb3SJim Ingham     AddressRange fun_range = frame_sc.function->GetAddressRange();
10729b70ddb3SJim Ingham 
1073481cef25SGreg Clayton     std::vector<addr_t> step_over_until_addrs;
10747ba6e991SJim Ingham     const bool abort_other_plans = false;
1075c02e3344SJim Ingham     const bool stop_other_threads = false;
1076481cef25SGreg Clayton     const bool check_inlines = true;
1077481cef25SGreg Clayton     const bool exact = false;
1078481cef25SGreg Clayton 
1079481cef25SGreg Clayton     SymbolContextList sc_list;
1080b9c1b51eSKate Stone     const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext(
1081b9c1b51eSKate Stone         step_file_spec, line, check_inlines, exact, eSymbolContextLineEntry,
10829b70ddb3SJim Ingham         sc_list);
1083b9c1b51eSKate Stone     if (num_matches > 0) {
1084481cef25SGreg Clayton       SymbolContext sc;
1085b9c1b51eSKate Stone       for (uint32_t i = 0; i < num_matches; ++i) {
1086b9c1b51eSKate Stone         if (sc_list.GetContextAtIndex(i, sc)) {
1087b9c1b51eSKate Stone           addr_t step_addr =
1088b9c1b51eSKate Stone               sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
1089b9c1b51eSKate Stone           if (step_addr != LLDB_INVALID_ADDRESS) {
10909b70ddb3SJim Ingham             if (fun_range.ContainsLoadAddress(step_addr, target))
1091481cef25SGreg Clayton               step_over_until_addrs.push_back(step_addr);
10929b70ddb3SJim Ingham             else
10939b70ddb3SJim Ingham               all_in_function = false;
1094481cef25SGreg Clayton           }
1095481cef25SGreg Clayton         }
1096481cef25SGreg Clayton       }
1097481cef25SGreg Clayton     }
1098481cef25SGreg Clayton 
1099b9c1b51eSKate Stone     if (step_over_until_addrs.empty()) {
1100b9c1b51eSKate Stone       if (all_in_function) {
1101481cef25SGreg Clayton         step_file_spec.GetPath(path, sizeof(path));
1102b9c1b51eSKate Stone         sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path,
1103b9c1b51eSKate Stone                                           line);
1104b9c1b51eSKate Stone       } else
110586edbf41SGreg Clayton         sb_error.SetErrorString("step until target not in current function");
1106b9c1b51eSKate Stone     } else {
1107e103ae92SJonas Devlieghere       Status new_plan_status;
1108b9c1b51eSKate Stone       ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil(
1109b9c1b51eSKate Stone           abort_other_plans, &step_over_until_addrs[0],
1110b9c1b51eSKate Stone           step_over_until_addrs.size(), stop_other_threads,
1111e103ae92SJonas Devlieghere           frame_sp->GetFrameIndex(), new_plan_status));
1112481cef25SGreg Clayton 
1113e103ae92SJonas Devlieghere       if (new_plan_status.Success())
11144d56e9c1SJim Ingham         sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
1115e103ae92SJonas Devlieghere       else
1116e103ae92SJonas Devlieghere         sb_error.SetErrorString(new_plan_status.AsCString());
1117481cef25SGreg Clayton     }
1118b9c1b51eSKate Stone   } else {
1119481cef25SGreg Clayton     sb_error.SetErrorString("this SBThread object is invalid");
1120481cef25SGreg Clayton   }
1121*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
1122481cef25SGreg Clayton }
1123481cef25SGreg Clayton 
1124b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) {
1125*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
1126*baf5664fSJonas Devlieghere                      (const char *), script_class_name);
1127*baf5664fSJonas Devlieghere 
1128*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
1129*baf5664fSJonas Devlieghere       StepUsingScriptedThreadPlan(script_class_name, true));
1130c915a7d2SJim Ingham }
1131c915a7d2SJim Ingham 
1132b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
1133b9c1b51eSKate Stone                                               bool resume_immediately) {
1134*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
1135*baf5664fSJonas Devlieghere                      (const char *, bool), script_class_name,
1136*baf5664fSJonas Devlieghere                      resume_immediately);
1137*baf5664fSJonas Devlieghere 
11382bdbfd50SJim Ingham   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1139e103ae92SJonas Devlieghere   SBError error;
11402bdbfd50SJim Ingham 
1141bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1142bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11432bdbfd50SJim Ingham 
1144b9c1b51eSKate Stone   if (log) {
11452bdbfd50SJim Ingham     log->Printf("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s",
1146b9c1b51eSKate Stone                 static_cast<void *>(exe_ctx.GetThreadPtr()), script_class_name);
11472bdbfd50SJim Ingham   }
11482bdbfd50SJim Ingham 
1149b9c1b51eSKate Stone   if (!exe_ctx.HasThreadScope()) {
1150e103ae92SJonas Devlieghere     error.SetErrorString("this SBThread object is invalid");
1151*baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(error);
11522bdbfd50SJim Ingham   }
11532bdbfd50SJim Ingham 
11542bdbfd50SJim Ingham   Thread *thread = exe_ctx.GetThreadPtr();
1155e103ae92SJonas Devlieghere   Status new_plan_status;
1156e103ae92SJonas Devlieghere   ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted(
1157e103ae92SJonas Devlieghere       false, script_class_name, false, new_plan_status);
11582bdbfd50SJim Ingham 
1159e103ae92SJonas Devlieghere   if (new_plan_status.Fail()) {
1160e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
1161*baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(error);
1162c915a7d2SJim Ingham   }
1163c915a7d2SJim Ingham 
1164e103ae92SJonas Devlieghere   if (!resume_immediately)
1165*baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(error);
1166c915a7d2SJim Ingham 
1167e103ae92SJonas Devlieghere   if (new_plan_status.Success())
1168e103ae92SJonas Devlieghere     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
1169e103ae92SJonas Devlieghere   else
1170e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
11712bdbfd50SJim Ingham 
1172*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(error);
11732bdbfd50SJim Ingham }
11742bdbfd50SJim Ingham 
1175b9c1b51eSKate Stone SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
1176*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, JumpToLine,
1177*baf5664fSJonas Devlieghere                      (lldb::SBFileSpec &, uint32_t), file_spec, line);
1178*baf5664fSJonas Devlieghere 
1179f86248d9SRichard Mitton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1180f86248d9SRichard Mitton   SBError sb_error;
1181f86248d9SRichard Mitton 
1182bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1183bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1184f86248d9SRichard Mitton 
1185f86248d9SRichard Mitton   if (log)
1186324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::JumpToLine (file+line = %s:%u)",
1187324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
1188324a1036SSaleem Abdulrasool                 file_spec->GetPath().c_str(), line);
1189f86248d9SRichard Mitton 
1190b9c1b51eSKate Stone   if (!exe_ctx.HasThreadScope()) {
1191f86248d9SRichard Mitton     sb_error.SetErrorString("this SBThread object is invalid");
1192*baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(sb_error);
1193f86248d9SRichard Mitton   }
1194f86248d9SRichard Mitton 
1195f86248d9SRichard Mitton   Thread *thread = exe_ctx.GetThreadPtr();
1196f86248d9SRichard Mitton 
119797206d57SZachary Turner   Status err = thread->JumpToLine(file_spec.get(), line, true);
1198f86248d9SRichard Mitton   sb_error.SetError(err);
1199*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
1200f86248d9SRichard Mitton }
1201f86248d9SRichard Mitton 
1202b9c1b51eSKate Stone SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
1203*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, ReturnFromFrame,
1204*baf5664fSJonas Devlieghere                      (lldb::SBFrame &, lldb::SBValue &), frame, return_value);
1205*baf5664fSJonas Devlieghere 
12064413758cSJim Ingham   SBError sb_error;
12074413758cSJim Ingham 
12085160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
12094413758cSJim Ingham 
1210bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1211bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12124413758cSJim Ingham 
12134413758cSJim Ingham   if (log)
1214324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::ReturnFromFrame (frame=%d)",
1215324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
1216324a1036SSaleem Abdulrasool                 frame.GetFrameID());
12174413758cSJim Ingham 
1218b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
12194413758cSJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
1220b9c1b51eSKate Stone     sb_error.SetError(
1221b9c1b51eSKate Stone         thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
12224413758cSJim Ingham   }
12234413758cSJim Ingham 
1224*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
12254413758cSJim Ingham }
12264413758cSJim Ingham 
1227b9c1b51eSKate Stone SBError SBThread::UnwindInnermostExpression() {
1228*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBError, SBThread,
1229*baf5664fSJonas Devlieghere                              UnwindInnermostExpression);
1230*baf5664fSJonas Devlieghere 
12314ac8e93aSJim Ingham   SBError sb_error;
12324ac8e93aSJim Ingham 
12334ac8e93aSJim Ingham   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
12344ac8e93aSJim Ingham 
12354ac8e93aSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
12364ac8e93aSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12374ac8e93aSJim Ingham 
12384ac8e93aSJim Ingham   if (log)
12394ac8e93aSJim Ingham     log->Printf("SBThread(%p)::UnwindExpressionEvaluation",
12404ac8e93aSJim Ingham                 static_cast<void *>(exe_ctx.GetThreadPtr()));
12414ac8e93aSJim Ingham 
1242b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
12434ac8e93aSJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
12444ac8e93aSJim Ingham     sb_error.SetError(thread->UnwindInnermostExpression());
12454ac8e93aSJim Ingham     if (sb_error.Success())
12464ac8e93aSJim Ingham       thread->SetSelectedFrameByIndex(0, false);
12474ac8e93aSJim Ingham   }
12484ac8e93aSJim Ingham 
1249*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
12504ac8e93aSJim Ingham }
1251481cef25SGreg Clayton 
1252b9c1b51eSKate Stone bool SBThread::Suspend() {
1253*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, Suspend);
1254*baf5664fSJonas Devlieghere 
1255859f54b3SAlexander Polyakov   SBError error; // Ignored
1256859f54b3SAlexander Polyakov   return Suspend(error);
1257859f54b3SAlexander Polyakov }
1258859f54b3SAlexander Polyakov 
1259859f54b3SAlexander Polyakov bool SBThread::Suspend(SBError &error) {
1260*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, Suspend, (lldb::SBError &), error);
1261*baf5664fSJonas Devlieghere 
12625160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1263b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1264b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1265b2e7d28eSJim Ingham 
1266c9858e4dSGreg Clayton   bool result = false;
1267b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1268c9858e4dSGreg Clayton     Process::StopLocker stop_locker;
1269b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
12701ac04c30SGreg Clayton       exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
1271c9858e4dSGreg Clayton       result = true;
1272b9c1b51eSKate Stone     } else {
1273859f54b3SAlexander Polyakov       error.SetErrorString("process is running");
1274c9858e4dSGreg Clayton       if (log)
1275324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::Suspend() => error: process is running",
1276324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
1277c9858e4dSGreg Clayton     }
1278859f54b3SAlexander Polyakov   } else
1279859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
1280c9858e4dSGreg Clayton   if (log)
1281324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::Suspend() => %i",
1282324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), result);
1283c9858e4dSGreg Clayton   return result;
1284722a0cdcSGreg Clayton }
1285722a0cdcSGreg Clayton 
1286b9c1b51eSKate Stone bool SBThread::Resume() {
1287*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, Resume);
1288*baf5664fSJonas Devlieghere 
1289859f54b3SAlexander Polyakov   SBError error; // Ignored
1290859f54b3SAlexander Polyakov   return Resume(error);
1291859f54b3SAlexander Polyakov }
1292859f54b3SAlexander Polyakov 
1293859f54b3SAlexander Polyakov bool SBThread::Resume(SBError &error) {
1294*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, Resume, (lldb::SBError &), error);
1295*baf5664fSJonas Devlieghere 
12965160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1297b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1298b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1299b2e7d28eSJim Ingham 
1300c9858e4dSGreg Clayton   bool result = false;
1301b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1302c9858e4dSGreg Clayton     Process::StopLocker stop_locker;
1303b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
13046c9ed91cSJim Ingham       const bool override_suspend = true;
13056c9ed91cSJim Ingham       exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
1306c9858e4dSGreg Clayton       result = true;
1307b9c1b51eSKate Stone     } else {
1308859f54b3SAlexander Polyakov       error.SetErrorString("process is running");
1309c9858e4dSGreg Clayton       if (log)
1310324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::Resume() => error: process is running",
1311324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
1312c9858e4dSGreg Clayton     }
1313859f54b3SAlexander Polyakov   } else
1314859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
1315c9858e4dSGreg Clayton   if (log)
1316324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::Resume() => %i",
1317324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), result);
1318c9858e4dSGreg Clayton   return result;
1319722a0cdcSGreg Clayton }
1320722a0cdcSGreg Clayton 
1321b9c1b51eSKate Stone bool SBThread::IsSuspended() {
1322*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, IsSuspended);
1323*baf5664fSJonas Devlieghere 
1324b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1325b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1326b2e7d28eSJim Ingham 
13271ac04c30SGreg Clayton   if (exe_ctx.HasThreadScope())
13281ac04c30SGreg Clayton     return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
1329722a0cdcSGreg Clayton   return false;
1330722a0cdcSGreg Clayton }
1331722a0cdcSGreg Clayton 
1332b9c1b51eSKate Stone bool SBThread::IsStopped() {
1333*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, IsStopped);
1334*baf5664fSJonas Devlieghere 
1335b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1336b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1337b2e7d28eSJim Ingham 
1338a75418dbSAndrew Kaylor   if (exe_ctx.HasThreadScope())
1339a75418dbSAndrew Kaylor     return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1340a75418dbSAndrew Kaylor   return false;
1341a75418dbSAndrew Kaylor }
1342a75418dbSAndrew Kaylor 
1343b9c1b51eSKate Stone SBProcess SBThread::GetProcess() {
1344*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBProcess, SBThread, GetProcess);
1345*baf5664fSJonas Devlieghere 
1346b9556accSGreg Clayton   SBProcess sb_process;
1347b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1348b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1349b2e7d28eSJim Ingham 
1350b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1351b9c1b51eSKate Stone     // Have to go up to the target so we can get a shared pointer to our
1352b9c1b51eSKate Stone     // process...
13531ac04c30SGreg Clayton     sb_process.SetSP(exe_ctx.GetProcessSP());
135430fdc8d8SChris Lattner   }
1355ceb6b139SCaroline Tice 
13565160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1357b9c1b51eSKate Stone   if (log) {
1358481cef25SGreg Clayton     SBStream frame_desc_strm;
1359b9556accSGreg Clayton     sb_process.GetDescription(frame_desc_strm);
1360324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetProcess () => SBProcess(%p): %s",
1361324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
1362324a1036SSaleem Abdulrasool                 static_cast<void *>(sb_process.GetSP().get()),
1363324a1036SSaleem Abdulrasool                 frame_desc_strm.GetData());
1364ceb6b139SCaroline Tice   }
1365ceb6b139SCaroline Tice 
1366*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_process);
136730fdc8d8SChris Lattner }
136830fdc8d8SChris Lattner 
1369b9c1b51eSKate Stone uint32_t SBThread::GetNumFrames() {
1370*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBThread, GetNumFrames);
1371*baf5664fSJonas Devlieghere 
13725160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1373ceb6b139SCaroline Tice 
1374ceb6b139SCaroline Tice   uint32_t num_frames = 0;
1375bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1376bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
13774fc6cb9cSJim Ingham 
1378b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
13797fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1380b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
13811ac04c30SGreg Clayton       num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1382b9c1b51eSKate Stone     } else {
1383c9858e4dSGreg Clayton       if (log)
1384324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::GetNumFrames() => error: process is running",
1385324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
1386c9858e4dSGreg Clayton     }
13877fdf9ef1SGreg Clayton   }
1388ceb6b139SCaroline Tice 
1389ceb6b139SCaroline Tice   if (log)
1390324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetNumFrames () => %u",
1391324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), num_frames);
1392ceb6b139SCaroline Tice 
1393ceb6b139SCaroline Tice   return num_frames;
139430fdc8d8SChris Lattner }
139530fdc8d8SChris Lattner 
1396b9c1b51eSKate Stone SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
1397*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBFrame, SBThread, GetFrameAtIndex, (uint32_t), idx);
1398*baf5664fSJonas Devlieghere 
13995160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1400ceb6b139SCaroline Tice 
140130fdc8d8SChris Lattner   SBFrame sb_frame;
1402b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1403bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1404bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
14054fc6cb9cSJim Ingham 
1406b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
14077fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1408b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
14091ac04c30SGreg Clayton       frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
1410b9556accSGreg Clayton       sb_frame.SetFrameSP(frame_sp);
1411b9c1b51eSKate Stone     } else {
1412c9858e4dSGreg Clayton       if (log)
1413b9c1b51eSKate Stone         log->Printf(
1414b9c1b51eSKate Stone             "SBThread(%p)::GetFrameAtIndex() => error: process is running",
1415324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
1416c9858e4dSGreg Clayton     }
14177fdf9ef1SGreg Clayton   }
1418ceb6b139SCaroline Tice 
1419b9c1b51eSKate Stone   if (log) {
1420481cef25SGreg Clayton     SBStream frame_desc_strm;
1421481cef25SGreg Clayton     sb_frame.GetDescription(frame_desc_strm);
14224838131bSGreg Clayton     log->Printf("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
1423324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), idx,
1424b9c1b51eSKate Stone                 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1425ceb6b139SCaroline Tice   }
1426ceb6b139SCaroline Tice 
1427*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_frame);
142830fdc8d8SChris Lattner }
142930fdc8d8SChris Lattner 
1430b9c1b51eSKate Stone lldb::SBFrame SBThread::GetSelectedFrame() {
1431*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBFrame, SBThread, GetSelectedFrame);
1432*baf5664fSJonas Devlieghere 
14335160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1434f028a1fbSGreg Clayton 
1435f028a1fbSGreg Clayton   SBFrame sb_frame;
1436b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1437bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1438bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
14394fc6cb9cSJim Ingham 
1440b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
14417fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1442b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
14431ac04c30SGreg Clayton       frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame();
1444b9556accSGreg Clayton       sb_frame.SetFrameSP(frame_sp);
1445b9c1b51eSKate Stone     } else {
1446c9858e4dSGreg Clayton       if (log)
1447b9c1b51eSKate Stone         log->Printf(
1448b9c1b51eSKate Stone             "SBThread(%p)::GetSelectedFrame() => error: process is running",
1449324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
1450c9858e4dSGreg Clayton     }
14517fdf9ef1SGreg Clayton   }
1452f028a1fbSGreg Clayton 
1453b9c1b51eSKate Stone   if (log) {
1454481cef25SGreg Clayton     SBStream frame_desc_strm;
1455481cef25SGreg Clayton     sb_frame.GetDescription(frame_desc_strm);
1456f028a1fbSGreg Clayton     log->Printf("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
1457324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
1458b9c1b51eSKate Stone                 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1459f028a1fbSGreg Clayton   }
1460f028a1fbSGreg Clayton 
1461*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_frame);
1462f028a1fbSGreg Clayton }
1463f028a1fbSGreg Clayton 
1464b9c1b51eSKate Stone lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
1465*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBFrame, SBThread, SetSelectedFrame, (uint32_t),
1466*baf5664fSJonas Devlieghere                      idx);
1467*baf5664fSJonas Devlieghere 
14685160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1469f028a1fbSGreg Clayton 
1470f028a1fbSGreg Clayton   SBFrame sb_frame;
1471b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1472bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1473bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
14744fc6cb9cSJim Ingham 
1475b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
14767fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1477b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
14781ac04c30SGreg Clayton       Thread *thread = exe_ctx.GetThreadPtr();
14791ac04c30SGreg Clayton       frame_sp = thread->GetStackFrameAtIndex(idx);
1480b9c1b51eSKate Stone       if (frame_sp) {
14811ac04c30SGreg Clayton         thread->SetSelectedFrame(frame_sp.get());
1482b9556accSGreg Clayton         sb_frame.SetFrameSP(frame_sp);
1483f028a1fbSGreg Clayton       }
1484b9c1b51eSKate Stone     } else {
1485c9858e4dSGreg Clayton       if (log)
1486b9c1b51eSKate Stone         log->Printf(
1487b9c1b51eSKate Stone             "SBThread(%p)::SetSelectedFrame() => error: process is running",
1488324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
1489c9858e4dSGreg Clayton     }
14907fdf9ef1SGreg Clayton   }
1491f028a1fbSGreg Clayton 
1492b9c1b51eSKate Stone   if (log) {
1493481cef25SGreg Clayton     SBStream frame_desc_strm;
1494481cef25SGreg Clayton     sb_frame.GetDescription(frame_desc_strm);
1495f028a1fbSGreg Clayton     log->Printf("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
1496324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), idx,
1497b9c1b51eSKate Stone                 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1498f028a1fbSGreg Clayton   }
1499*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_frame);
1500f028a1fbSGreg Clayton }
1501f028a1fbSGreg Clayton 
1502b9c1b51eSKate Stone bool SBThread::EventIsThreadEvent(const SBEvent &event) {
1503*baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(bool, SBThread, EventIsThreadEvent,
1504*baf5664fSJonas Devlieghere                             (const lldb::SBEvent &), event);
1505*baf5664fSJonas Devlieghere 
15064f465cffSJim Ingham   return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
15074f465cffSJim Ingham }
15084f465cffSJim Ingham 
1509b9c1b51eSKate Stone SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) {
1510*baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(lldb::SBFrame, SBThread, GetStackFrameFromEvent,
1511*baf5664fSJonas Devlieghere                             (const lldb::SBEvent &), event);
1512*baf5664fSJonas Devlieghere 
1513*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
1514*baf5664fSJonas Devlieghere       Thread::ThreadEventData::GetStackFrameFromEvent(event.get()));
15154f465cffSJim Ingham }
15164f465cffSJim Ingham 
1517b9c1b51eSKate Stone SBThread SBThread::GetThreadFromEvent(const SBEvent &event) {
1518*baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(lldb::SBThread, SBThread, GetThreadFromEvent,
1519*baf5664fSJonas Devlieghere                             (const lldb::SBEvent &), event);
1520*baf5664fSJonas Devlieghere 
1521*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
1522*baf5664fSJonas Devlieghere       Thread::ThreadEventData::GetThreadFromEvent(event.get()));
15234f465cffSJim Ingham }
1524f028a1fbSGreg Clayton 
1525b9c1b51eSKate Stone bool SBThread::operator==(const SBThread &rhs) const {
1526*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, operator==,(const lldb::SBThread &),
1527*baf5664fSJonas Devlieghere                            rhs);
1528*baf5664fSJonas Devlieghere 
1529b9c1b51eSKate Stone   return m_opaque_sp->GetThreadSP().get() ==
1530b9c1b51eSKate Stone          rhs.m_opaque_sp->GetThreadSP().get();
153130fdc8d8SChris Lattner }
153230fdc8d8SChris Lattner 
1533b9c1b51eSKate Stone bool SBThread::operator!=(const SBThread &rhs) const {
1534*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, operator!=,(const lldb::SBThread &),
1535*baf5664fSJonas Devlieghere                            rhs);
1536*baf5664fSJonas Devlieghere 
1537b9c1b51eSKate Stone   return m_opaque_sp->GetThreadSP().get() !=
1538b9c1b51eSKate Stone          rhs.m_opaque_sp->GetThreadSP().get();
153930fdc8d8SChris Lattner }
1540dde9cff3SCaroline Tice 
1541b9c1b51eSKate Stone bool SBThread::GetStatus(SBStream &status) const {
1542*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetStatus, (lldb::SBStream &),
1543*baf5664fSJonas Devlieghere                            status);
1544*baf5664fSJonas Devlieghere 
15454f465cffSJim Ingham   Stream &strm = status.ref();
15464f465cffSJim Ingham 
1547b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1548b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1549b2e7d28eSJim Ingham 
1550b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
15516a9767c7SJim Ingham     exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true);
1552b9c1b51eSKate Stone   } else
15534f465cffSJim Ingham     strm.PutCString("No status");
15544f465cffSJim Ingham 
15554f465cffSJim Ingham   return true;
15564f465cffSJim Ingham }
15574f465cffSJim Ingham 
1558b9c1b51eSKate Stone bool SBThread::GetDescription(SBStream &description) const {
1559*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetDescription, (lldb::SBStream &),
1560*baf5664fSJonas Devlieghere                            description);
1561*baf5664fSJonas Devlieghere 
15626a9767c7SJim Ingham   return GetDescription(description, false);
15636a9767c7SJim Ingham }
15646a9767c7SJim Ingham 
15656a9767c7SJim Ingham bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
1566*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetDescription,
1567*baf5664fSJonas Devlieghere                            (lldb::SBStream &, bool), description, stop_format);
1568*baf5664fSJonas Devlieghere 
1569da7bc7d0SGreg Clayton   Stream &strm = description.ref();
1570da7bc7d0SGreg Clayton 
1571b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1572b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1573b2e7d28eSJim Ingham 
1574b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1575b9c1b51eSKate Stone     exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm,
15766a9767c7SJim Ingham                                                     LLDB_INVALID_THREAD_ID,
15776a9767c7SJim Ingham                                                     stop_format);
1578b9c1b51eSKate Stone     // strm.Printf("SBThread: tid = 0x%4.4" PRIx64,
1579b9c1b51eSKate Stone     // exe_ctx.GetThreadPtr()->GetID());
1580b9c1b51eSKate Stone   } else
1581da7bc7d0SGreg Clayton     strm.PutCString("No value");
1582ceb6b139SCaroline Tice 
1583ceb6b139SCaroline Tice   return true;
1584ceb6b139SCaroline Tice }
15855dd4916fSJason Molenda 
1586b9c1b51eSKate Stone SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
1587*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBThread, SBThread, GetExtendedBacktraceThread,
1588*baf5664fSJonas Devlieghere                      (const char *), type);
1589*baf5664fSJonas Devlieghere 
15905dd4916fSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1591bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1592bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
15935dd4916fSJason Molenda   SBThread sb_origin_thread;
15945dd4916fSJason Molenda 
1595b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
15965dd4916fSJason Molenda     Process::StopLocker stop_locker;
1597b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
15987a2f7904SJason Molenda       ThreadSP real_thread(exe_ctx.GetThreadSP());
1599b9c1b51eSKate Stone       if (real_thread) {
16005dd4916fSJason Molenda         ConstString type_const(type);
16017a2f7904SJason Molenda         Process *process = exe_ctx.GetProcessPtr();
1602b9c1b51eSKate Stone         if (process) {
16037a2f7904SJason Molenda           SystemRuntime *runtime = process->GetSystemRuntime();
1604b9c1b51eSKate Stone           if (runtime) {
1605b9c1b51eSKate Stone             ThreadSP new_thread_sp(
1606b9c1b51eSKate Stone                 runtime->GetExtendedBacktraceThread(real_thread, type_const));
1607b9c1b51eSKate Stone             if (new_thread_sp) {
1608b9c1b51eSKate Stone               // Save this in the Process' ExtendedThreadList so a strong
160905097246SAdrian Prantl               // pointer retains the object.
16107a2f7904SJason Molenda               process->GetExtendedThreadList().AddThread(new_thread_sp);
16117a2f7904SJason Molenda               sb_origin_thread.SetThread(new_thread_sp);
1612b9c1b51eSKate Stone               if (log) {
1613a6e9130dSJason Molenda                 const char *queue_name = new_thread_sp->GetQueueName();
1614a6e9130dSJason Molenda                 if (queue_name == NULL)
1615a6e9130dSJason Molenda                   queue_name = "";
1616b9c1b51eSKate Stone                 log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => new "
1617b9c1b51eSKate Stone                             "extended Thread "
1618b9c1b51eSKate Stone                             "created (%p) with queue_id 0x%" PRIx64
1619b9c1b51eSKate Stone                             " queue name '%s'",
1620324a1036SSaleem Abdulrasool                             static_cast<void *>(exe_ctx.GetThreadPtr()),
1621324a1036SSaleem Abdulrasool                             static_cast<void *>(new_thread_sp.get()),
1622b9c1b51eSKate Stone                             new_thread_sp->GetQueueID(), queue_name);
1623a6e9130dSJason Molenda               }
1624a6e9130dSJason Molenda             }
16257a2f7904SJason Molenda           }
16265dd4916fSJason Molenda         }
16275dd4916fSJason Molenda       }
1628b9c1b51eSKate Stone     } else {
16295dd4916fSJason Molenda       if (log)
1630b9c1b51eSKate Stone         log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => error: "
1631b9c1b51eSKate Stone                     "process is running",
1632324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
16335dd4916fSJason Molenda     }
16345dd4916fSJason Molenda   }
16355dd4916fSJason Molenda 
1636a6682a41SJonas Devlieghere   if (log && !sb_origin_thread.IsValid())
1637b9c1b51eSKate Stone     log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a "
1638b9c1b51eSKate Stone                 "Valid thread",
1639324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()));
1640*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_origin_thread);
16415dd4916fSJason Molenda }
16428ee9cb58SJason Molenda 
1643b9c1b51eSKate Stone uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
1644*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBThread,
1645*baf5664fSJonas Devlieghere                              GetExtendedBacktraceOriginatingIndexID);
1646*baf5664fSJonas Devlieghere 
16478ee9cb58SJason Molenda   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
16488ee9cb58SJason Molenda   if (thread_sp)
16498ee9cb58SJason Molenda     return thread_sp->GetExtendedBacktraceOriginatingIndexID();
16508ee9cb58SJason Molenda   return LLDB_INVALID_INDEX32;
16518ee9cb58SJason Molenda }
1652b4892cd2SJason Molenda 
1653e60bc53bSKuba Mracek SBValue SBThread::GetCurrentException() {
1654*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBValue, SBThread, GetCurrentException);
1655e60bc53bSKuba Mracek 
1656*baf5664fSJonas Devlieghere   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1657*baf5664fSJonas Devlieghere   if (!thread_sp)
1658*baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(SBValue());
1659*baf5664fSJonas Devlieghere 
1660*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(SBValue(thread_sp->GetCurrentException()));
1661e60bc53bSKuba Mracek }
1662e60bc53bSKuba Mracek 
1663e60bc53bSKuba Mracek SBThread SBThread::GetCurrentExceptionBacktrace() {
1664*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBThread, SBThread,
1665*baf5664fSJonas Devlieghere                              GetCurrentExceptionBacktrace);
1666e60bc53bSKuba Mracek 
1667*baf5664fSJonas Devlieghere   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1668*baf5664fSJonas Devlieghere   if (!thread_sp)
1669*baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(SBThread());
1670*baf5664fSJonas Devlieghere 
1671*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
1672*baf5664fSJonas Devlieghere       SBThread(thread_sp->GetCurrentExceptionBacktrace()));
1673c9e1190aSKuba Mracek }
1674e60bc53bSKuba Mracek 
1675b9c1b51eSKate Stone bool SBThread::SafeToCallFunctions() {
1676*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, SafeToCallFunctions);
1677*baf5664fSJonas Devlieghere 
1678b4892cd2SJason Molenda   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1679b4892cd2SJason Molenda   if (thread_sp)
1680b4892cd2SJason Molenda     return thread_sp->SafeToCallFunctions();
1681b4892cd2SJason Molenda   return true;
1682b4892cd2SJason Molenda }
16832bdbfd50SJim Ingham 
1684b9c1b51eSKate Stone lldb_private::Thread *SBThread::operator->() {
1685*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb_private::Thread *, SBThread, operator->);
1686*baf5664fSJonas Devlieghere 
16872bdbfd50SJim Ingham   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
16882bdbfd50SJim Ingham   if (thread_sp)
16892bdbfd50SJim Ingham     return thread_sp.get();
16902bdbfd50SJim Ingham   else
16912bdbfd50SJim Ingham     return NULL;
16922bdbfd50SJim Ingham }
16932bdbfd50SJim Ingham 
1694b9c1b51eSKate Stone lldb_private::Thread *SBThread::get() {
1695*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb_private::Thread *, SBThread, get);
1696*baf5664fSJonas Devlieghere 
16972bdbfd50SJim Ingham   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
16982bdbfd50SJim Ingham   if (thread_sp)
16992bdbfd50SJim Ingham     return thread_sp.get();
17002bdbfd50SJim Ingham   else
17012bdbfd50SJim Ingham     return NULL;
17022bdbfd50SJim Ingham }
1703