130fdc8d8SChris Lattner //===-- SBThread.cpp --------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner 
94c5de699SEli Friedman #include "lldb/API/SBThread.h"
10baf5664fSJonas Devlieghere #include "SBReproducerPrivate.h"
11bd4bf82aSJonas Devlieghere #include "Utils.h"
12bd4bf82aSJonas Devlieghere #include "lldb/API/SBAddress.h"
13bd4bf82aSJonas Devlieghere #include "lldb/API/SBDebugger.h"
14bd4bf82aSJonas Devlieghere #include "lldb/API/SBEvent.h"
1530fdc8d8SChris Lattner #include "lldb/API/SBFileSpec.h"
16bd4bf82aSJonas Devlieghere #include "lldb/API/SBFrame.h"
17bd4bf82aSJonas Devlieghere #include "lldb/API/SBProcess.h"
18dde9cff3SCaroline Tice #include "lldb/API/SBStream.h"
19b9c1b51eSKate Stone #include "lldb/API/SBSymbolContext.h"
20bd4bf82aSJonas Devlieghere #include "lldb/API/SBThreadCollection.h"
21bd4bf82aSJonas Devlieghere #include "lldb/API/SBThreadPlan.h"
22bd4bf82aSJonas Devlieghere #include "lldb/API/SBValue.h"
234e78f606SGreg Clayton #include "lldb/Breakpoint/BreakpointLocation.h"
246611103cSGreg Clayton #include "lldb/Core/Debugger.h"
2530fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h"
26a78bd7ffSZachary Turner #include "lldb/Core/ValueObject.h"
276611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
2893749ab3SZachary Turner #include "lldb/Symbol/CompileUnit.h"
29b9c1b51eSKate Stone #include "lldb/Symbol/SymbolContext.h"
3030fdc8d8SChris Lattner #include "lldb/Target/Process.h"
31b9ffa98cSJason Molenda #include "lldb/Target/Queue.h"
32f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h"
33b9c1b51eSKate Stone #include "lldb/Target/SystemRuntime.h"
3430fdc8d8SChris Lattner #include "lldb/Target/Target.h"
35b9c1b51eSKate Stone #include "lldb/Target/Thread.h"
3630fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h"
37b9c1b51eSKate Stone #include "lldb/Target/ThreadPlanStepInRange.h"
3830fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h"
3930fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h"
4030fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h"
41b9c1b51eSKate Stone #include "lldb/Target/UnixSignals.h"
42d821c997SPavel Labath #include "lldb/Utility/State.h"
43bf9a7730SZachary Turner #include "lldb/Utility/Stream.h"
44f2a8bccfSPavel Labath #include "lldb/Utility/StructuredData.h"
455bfee5f1SAbhishek Aggarwal #include "lldb/lldb-enumerations.h"
4630fdc8d8SChris Lattner 
47796ac80bSJonas Devlieghere #include <memory>
48796ac80bSJonas Devlieghere 
4930fdc8d8SChris Lattner using namespace lldb;
5030fdc8d8SChris Lattner using namespace lldb_private;
5130fdc8d8SChris Lattner 
52b9c1b51eSKate Stone const char *SBThread::GetBroadcasterClassName() {
53baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBThread,
54baf5664fSJonas Devlieghere                                     GetBroadcasterClassName);
55baf5664fSJonas Devlieghere 
564f465cffSJim Ingham   return Thread::GetStaticBroadcasterClass().AsCString();
574f465cffSJim Ingham }
584f465cffSJim Ingham 
59cfd1acedSGreg Clayton //----------------------------------------------------------------------
60cfd1acedSGreg Clayton // Constructors
61cfd1acedSGreg Clayton //----------------------------------------------------------------------
62baf5664fSJonas Devlieghere SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {
63baf5664fSJonas Devlieghere   LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBThread);
64baf5664fSJonas Devlieghere }
6530fdc8d8SChris Lattner 
66b9c1b51eSKate Stone SBThread::SBThread(const ThreadSP &lldb_object_sp)
67baf5664fSJonas Devlieghere     : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {
68baf5664fSJonas Devlieghere   LLDB_RECORD_CONSTRUCTOR(SBThread, (const lldb::ThreadSP &), lldb_object_sp);
69baf5664fSJonas Devlieghere }
7030fdc8d8SChris Lattner 
71bd4bf82aSJonas Devlieghere SBThread::SBThread(const SBThread &rhs) : m_opaque_sp() {
72baf5664fSJonas Devlieghere   LLDB_RECORD_CONSTRUCTOR(SBThread, (const lldb::SBThread &), rhs);
73baf5664fSJonas 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) {
82baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(const lldb::SBThread &,
83baf5664fSJonas Devlieghere                      SBThread, operator=,(const lldb::SBThread &), rhs);
84baf5664fSJonas 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 {
96baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBQueue, SBThread, GetQueue);
97baf5664fSJonas 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 
103b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
104b9ffa98cSJason Molenda     Process::StopLocker stop_locker;
105b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
106b9ffa98cSJason Molenda       queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
107b9c1b51eSKate Stone       if (queue_sp) {
108b9ffa98cSJason Molenda         sb_queue.SetQueue(queue_sp);
109b9ffa98cSJason Molenda       }
110b9ffa98cSJason Molenda     }
111b9ffa98cSJason Molenda   }
112b9ffa98cSJason Molenda 
113baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_queue);
114b9ffa98cSJason Molenda }
115b9ffa98cSJason Molenda 
116b9c1b51eSKate Stone bool SBThread::IsValid() const {
117baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThread, IsValid);
1187f5237bcSPavel Labath   return this->operator bool();
1197f5237bcSPavel Labath }
1207f5237bcSPavel Labath SBThread::operator bool() const {
1217f5237bcSPavel Labath   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThread, operator bool);
122baf5664fSJonas Devlieghere 
123bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
124bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1257fa7dc36SJim Ingham 
1267fa7dc36SJim Ingham   Target *target = exe_ctx.GetTargetPtr();
1277fa7dc36SJim Ingham   Process *process = exe_ctx.GetProcessPtr();
128b9c1b51eSKate Stone   if (target && process) {
1297fa7dc36SJim Ingham     Process::StopLocker stop_locker;
1307fa7dc36SJim Ingham     if (stop_locker.TryLock(&process->GetRunLock()))
1317fdf9ef1SGreg Clayton       return m_opaque_sp->GetThreadSP().get() != NULL;
13230fdc8d8SChris Lattner   }
1337fa7dc36SJim Ingham   // Without a valid target & process, this thread can't be valid.
1347fa7dc36SJim Ingham   return false;
1357fa7dc36SJim Ingham }
13630fdc8d8SChris Lattner 
137baf5664fSJonas Devlieghere void SBThread::Clear() {
138baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(void, SBThread, Clear);
139baf5664fSJonas Devlieghere 
140baf5664fSJonas Devlieghere   m_opaque_sp->Clear();
141baf5664fSJonas Devlieghere }
14248e42549SGreg Clayton 
143b9c1b51eSKate Stone StopReason SBThread::GetStopReason() {
144baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::StopReason, SBThread, GetStopReason);
145baf5664fSJonas Devlieghere 
146ceb6b139SCaroline Tice   StopReason reason = eStopReasonInvalid;
147bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
148bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1494fc6cb9cSJim Ingham 
150b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1517fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
152b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
15397d5cf05SGreg Clayton       return exe_ctx.GetThreadPtr()->GetStopReason();
154c9858e4dSGreg Clayton     }
1557fdf9ef1SGreg Clayton   }
156ceb6b139SCaroline Tice 
157ceb6b139SCaroline Tice   return reason;
15830fdc8d8SChris Lattner }
15930fdc8d8SChris Lattner 
160b9c1b51eSKate Stone size_t SBThread::GetStopReasonDataCount() {
161baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(size_t, SBThread, GetStopReasonDataCount);
162baf5664fSJonas Devlieghere 
163bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
164bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1654fc6cb9cSJim Ingham 
166b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1677fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
168b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1691ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
170b9c1b51eSKate Stone       if (stop_info_sp) {
1714e78f606SGreg Clayton         StopReason reason = stop_info_sp->GetStopReason();
172b9c1b51eSKate Stone         switch (reason) {
1734e78f606SGreg Clayton         case eStopReasonInvalid:
1744e78f606SGreg Clayton         case eStopReasonNone:
1754e78f606SGreg Clayton         case eStopReasonTrace:
17690ba8115SGreg Clayton         case eStopReasonExec:
1774e78f606SGreg Clayton         case eStopReasonPlanComplete:
178f85defaeSAndrew Kaylor         case eStopReasonThreadExiting:
179afdf842bSKuba Brecka         case eStopReasonInstrumentation:
1804e78f606SGreg Clayton           // There is no data for these stop reasons.
1814e78f606SGreg Clayton           return 0;
1824e78f606SGreg Clayton 
183b9c1b51eSKate Stone         case eStopReasonBreakpoint: {
1844e78f606SGreg Clayton           break_id_t site_id = stop_info_sp->GetValue();
185b9c1b51eSKate Stone           lldb::BreakpointSiteSP bp_site_sp(
186b9c1b51eSKate Stone               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
187b9c1b51eSKate Stone                   site_id));
1884e78f606SGreg Clayton           if (bp_site_sp)
1894e78f606SGreg Clayton             return bp_site_sp->GetNumberOfOwners() * 2;
1904e78f606SGreg Clayton           else
1914e78f606SGreg Clayton             return 0; // Breakpoint must have cleared itself...
192b9c1b51eSKate Stone         } break;
1934e78f606SGreg Clayton 
1944e78f606SGreg Clayton         case eStopReasonWatchpoint:
195290fa41bSJohnny Chen           return 1;
1964e78f606SGreg Clayton 
1974e78f606SGreg Clayton         case eStopReasonSignal:
1984e78f606SGreg Clayton           return 1;
1994e78f606SGreg Clayton 
2004e78f606SGreg Clayton         case eStopReasonException:
2014e78f606SGreg Clayton           return 1;
2024e78f606SGreg Clayton         }
2034e78f606SGreg Clayton       }
204c9858e4dSGreg Clayton     }
2057fdf9ef1SGreg Clayton   }
2064e78f606SGreg Clayton   return 0;
2074e78f606SGreg Clayton }
2084e78f606SGreg Clayton 
209b9c1b51eSKate Stone uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
210baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(uint64_t, SBThread, GetStopReasonDataAtIndex, (uint32_t),
211baf5664fSJonas Devlieghere                      idx);
212baf5664fSJonas Devlieghere 
213bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
214bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
2154fc6cb9cSJim Ingham 
216b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
2177fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
218b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
2191ac04c30SGreg Clayton       Thread *thread = exe_ctx.GetThreadPtr();
2201ac04c30SGreg Clayton       StopInfoSP stop_info_sp = thread->GetStopInfo();
221b9c1b51eSKate Stone       if (stop_info_sp) {
2224e78f606SGreg Clayton         StopReason reason = stop_info_sp->GetStopReason();
223b9c1b51eSKate Stone         switch (reason) {
2244e78f606SGreg Clayton         case eStopReasonInvalid:
2254e78f606SGreg Clayton         case eStopReasonNone:
2264e78f606SGreg Clayton         case eStopReasonTrace:
22790ba8115SGreg Clayton         case eStopReasonExec:
2284e78f606SGreg Clayton         case eStopReasonPlanComplete:
229f85defaeSAndrew Kaylor         case eStopReasonThreadExiting:
230afdf842bSKuba Brecka         case eStopReasonInstrumentation:
2314e78f606SGreg Clayton           // There is no data for these stop reasons.
2324e78f606SGreg Clayton           return 0;
2334e78f606SGreg Clayton 
234b9c1b51eSKate Stone         case eStopReasonBreakpoint: {
2354e78f606SGreg Clayton           break_id_t site_id = stop_info_sp->GetValue();
236b9c1b51eSKate Stone           lldb::BreakpointSiteSP bp_site_sp(
237b9c1b51eSKate Stone               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
238b9c1b51eSKate Stone                   site_id));
239b9c1b51eSKate Stone           if (bp_site_sp) {
2404e78f606SGreg Clayton             uint32_t bp_index = idx / 2;
241b9c1b51eSKate Stone             BreakpointLocationSP bp_loc_sp(
242b9c1b51eSKate Stone                 bp_site_sp->GetOwnerAtIndex(bp_index));
243b9c1b51eSKate Stone             if (bp_loc_sp) {
244b9c1b51eSKate Stone               if (idx & 1) {
2454e78f606SGreg Clayton                 // Odd idx, return the breakpoint location ID
2464e78f606SGreg Clayton                 return bp_loc_sp->GetID();
247b9c1b51eSKate Stone               } else {
2484e78f606SGreg Clayton                 // Even idx, return the breakpoint ID
2494e78f606SGreg Clayton                 return bp_loc_sp->GetBreakpoint().GetID();
2504e78f606SGreg Clayton               }
2514e78f606SGreg Clayton             }
2524e78f606SGreg Clayton           }
2534e78f606SGreg Clayton           return LLDB_INVALID_BREAK_ID;
254b9c1b51eSKate Stone         } break;
2554e78f606SGreg Clayton 
2564e78f606SGreg Clayton         case eStopReasonWatchpoint:
257290fa41bSJohnny Chen           return stop_info_sp->GetValue();
2584e78f606SGreg Clayton 
2594e78f606SGreg Clayton         case eStopReasonSignal:
2604e78f606SGreg Clayton           return stop_info_sp->GetValue();
2614e78f606SGreg Clayton 
2624e78f606SGreg Clayton         case eStopReasonException:
2634e78f606SGreg Clayton           return stop_info_sp->GetValue();
2644e78f606SGreg Clayton         }
2654e78f606SGreg Clayton       }
266c9858e4dSGreg Clayton     }
2677fdf9ef1SGreg Clayton   }
2684e78f606SGreg Clayton   return 0;
2694e78f606SGreg Clayton }
2704e78f606SGreg Clayton 
271b9c1b51eSKate Stone bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) {
272baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, GetStopReasonExtendedInfoAsJSON,
273baf5664fSJonas Devlieghere                      (lldb::SBStream &), stream);
274baf5664fSJonas Devlieghere 
275afdf842bSKuba Brecka   Stream &strm = stream.ref();
276afdf842bSKuba Brecka 
277b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
278b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
279b2e7d28eSJim Ingham 
280afdf842bSKuba Brecka   if (!exe_ctx.HasThreadScope())
281afdf842bSKuba Brecka     return false;
282afdf842bSKuba Brecka 
283afdf842bSKuba Brecka   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
284afdf842bSKuba Brecka   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
285afdf842bSKuba Brecka   if (!info)
286afdf842bSKuba Brecka     return false;
287afdf842bSKuba Brecka 
288afdf842bSKuba Brecka   info->Dump(strm);
289afdf842bSKuba Brecka 
290afdf842bSKuba Brecka   return true;
291afdf842bSKuba Brecka }
292afdf842bSKuba Brecka 
2936a831436SKuba Brecka SBThreadCollection
294b9c1b51eSKate Stone SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
295baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBThreadCollection, SBThread,
296baf5664fSJonas Devlieghere                      GetStopReasonExtendedBacktraces,
297baf5664fSJonas Devlieghere                      (lldb::InstrumentationRuntimeType), type);
298baf5664fSJonas Devlieghere 
2996a831436SKuba Brecka   ThreadCollectionSP threads;
300796ac80bSJonas Devlieghere   threads = std::make_shared<ThreadCollection>();
3016a831436SKuba Brecka 
302b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
303b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
304b2e7d28eSJim Ingham 
3056a831436SKuba Brecka   if (!exe_ctx.HasThreadScope())
306baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(threads);
3076a831436SKuba Brecka 
3086a831436SKuba Brecka   ProcessSP process_sp = exe_ctx.GetProcessSP();
3096a831436SKuba Brecka 
3106a831436SKuba Brecka   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
3116a831436SKuba Brecka   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
3126a831436SKuba Brecka   if (!info)
313baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(threads);
3146a831436SKuba Brecka 
315baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(process_sp->GetInstrumentationRuntime(type)
316baf5664fSJonas Devlieghere                                 ->GetBacktracesFromExtendedStopInfo(info));
3176a831436SKuba Brecka }
3186a831436SKuba Brecka 
319b9c1b51eSKate Stone size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
320baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(size_t, SBThread, GetStopDescription, (char *, size_t),
321baf5664fSJonas Devlieghere                      dst, dst_len);
322baf5664fSJonas Devlieghere 
323bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
324bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3254fc6cb9cSJim Ingham 
326b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
3277fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
328b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
3297fdf9ef1SGreg Clayton 
3301ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
331b9c1b51eSKate Stone       if (stop_info_sp) {
332b15bfc75SJim Ingham         const char *stop_desc = stop_info_sp->GetDescription();
333b9c1b51eSKate Stone         if (stop_desc) {
33430fdc8d8SChris Lattner           if (dst)
33530fdc8d8SChris Lattner             return ::snprintf(dst, dst_len, "%s", stop_desc);
336b9c1b51eSKate Stone           else {
337b9c1b51eSKate Stone             // NULL dst passed in, return the length needed to contain the
338b9c1b51eSKate Stone             // description
33930fdc8d8SChris Lattner             return ::strlen(stop_desc) + 1; // Include the NULL byte for size
34030fdc8d8SChris Lattner           }
341b9c1b51eSKate Stone         } else {
34230fdc8d8SChris Lattner           size_t stop_desc_len = 0;
343b9c1b51eSKate Stone           switch (stop_info_sp->GetStopReason()) {
34430fdc8d8SChris Lattner           case eStopReasonTrace:
345b9c1b51eSKate Stone           case eStopReasonPlanComplete: {
34630fdc8d8SChris Lattner             static char trace_desc[] = "step";
34730fdc8d8SChris Lattner             stop_desc = trace_desc;
348b9c1b51eSKate Stone             stop_desc_len =
349b9c1b51eSKate Stone                 sizeof(trace_desc); // Include the NULL byte for size
350b9c1b51eSKate Stone           } break;
35130fdc8d8SChris Lattner 
352b9c1b51eSKate Stone           case eStopReasonBreakpoint: {
35330fdc8d8SChris Lattner             static char bp_desc[] = "breakpoint hit";
35430fdc8d8SChris Lattner             stop_desc = bp_desc;
35530fdc8d8SChris Lattner             stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
356b9c1b51eSKate Stone           } break;
35730fdc8d8SChris Lattner 
358b9c1b51eSKate Stone           case eStopReasonWatchpoint: {
35930fdc8d8SChris Lattner             static char wp_desc[] = "watchpoint hit";
36030fdc8d8SChris Lattner             stop_desc = wp_desc;
36130fdc8d8SChris Lattner             stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
362b9c1b51eSKate Stone           } break;
36330fdc8d8SChris Lattner 
364b9c1b51eSKate Stone           case eStopReasonSignal: {
365b9c1b51eSKate Stone             stop_desc =
366b9c1b51eSKate Stone                 exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString(
367b9c1b51eSKate Stone                     stop_info_sp->GetValue());
368b9c1b51eSKate Stone             if (stop_desc == NULL || stop_desc[0] == '\0') {
36930fdc8d8SChris Lattner               static char signal_desc[] = "signal";
37030fdc8d8SChris Lattner               stop_desc = signal_desc;
371b9c1b51eSKate Stone               stop_desc_len =
372b9c1b51eSKate Stone                   sizeof(signal_desc); // Include the NULL byte for size
37330fdc8d8SChris Lattner             }
374b9c1b51eSKate Stone           } break;
37530fdc8d8SChris Lattner 
376b9c1b51eSKate Stone           case eStopReasonException: {
37730fdc8d8SChris Lattner             char exc_desc[] = "exception";
37830fdc8d8SChris Lattner             stop_desc = exc_desc;
37930fdc8d8SChris Lattner             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
380b9c1b51eSKate Stone           } break;
381c982c768SGreg Clayton 
382b9c1b51eSKate Stone           case eStopReasonExec: {
38390ba8115SGreg Clayton             char exc_desc[] = "exec";
38490ba8115SGreg Clayton             stop_desc = exc_desc;
38590ba8115SGreg Clayton             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
386b9c1b51eSKate Stone           } break;
38790ba8115SGreg Clayton 
388b9c1b51eSKate Stone           case eStopReasonThreadExiting: {
389f85defaeSAndrew Kaylor             char limbo_desc[] = "thread exiting";
390f85defaeSAndrew Kaylor             stop_desc = limbo_desc;
391f85defaeSAndrew Kaylor             stop_desc_len = sizeof(limbo_desc);
392b9c1b51eSKate Stone           } break;
393c982c768SGreg Clayton           default:
394c982c768SGreg Clayton             break;
39530fdc8d8SChris Lattner           }
39630fdc8d8SChris Lattner 
397b9c1b51eSKate Stone           if (stop_desc && stop_desc[0]) {
39830fdc8d8SChris Lattner             if (dst)
399b9c1b51eSKate Stone               return ::snprintf(dst, dst_len, "%s", stop_desc) +
400b9c1b51eSKate Stone                      1; // Include the NULL byte
40130fdc8d8SChris Lattner 
40230fdc8d8SChris Lattner             if (stop_desc_len == 0)
40330fdc8d8SChris Lattner               stop_desc_len = ::strlen(stop_desc) + 1; // Include the NULL byte
40430fdc8d8SChris Lattner 
40530fdc8d8SChris Lattner             return stop_desc_len;
40630fdc8d8SChris Lattner           }
40730fdc8d8SChris Lattner         }
40830fdc8d8SChris Lattner       }
409c9858e4dSGreg Clayton     }
4107fdf9ef1SGreg Clayton   }
41130fdc8d8SChris Lattner   if (dst)
41230fdc8d8SChris Lattner     *dst = 0;
41330fdc8d8SChris Lattner   return 0;
41430fdc8d8SChris Lattner }
41530fdc8d8SChris Lattner 
416b9c1b51eSKate Stone SBValue SBThread::GetStopReturnValue() {
417baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBValue, SBThread, GetStopReturnValue);
418baf5664fSJonas Devlieghere 
41973ca05a2SJim Ingham   ValueObjectSP return_valobj_sp;
420bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
421bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4224fc6cb9cSJim Ingham 
423b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4247fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
425b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4261ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
427b9c1b51eSKate Stone       if (stop_info_sp) {
42873ca05a2SJim Ingham         return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp);
42973ca05a2SJim Ingham       }
430c9858e4dSGreg Clayton     }
4317fdf9ef1SGreg Clayton   }
43273ca05a2SJim Ingham 
433baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(SBValue(return_valobj_sp));
43473ca05a2SJim Ingham }
43573ca05a2SJim Ingham 
436b9c1b51eSKate Stone void SBThread::SetThread(const ThreadSP &lldb_object_sp) {
4377fdf9ef1SGreg Clayton   m_opaque_sp->SetThreadSP(lldb_object_sp);
43830fdc8d8SChris Lattner }
43930fdc8d8SChris Lattner 
440b9c1b51eSKate Stone lldb::tid_t SBThread::GetThreadID() const {
441baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::tid_t, SBThread, GetThreadID);
442baf5664fSJonas Devlieghere 
4437fdf9ef1SGreg Clayton   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
44417a6ad05SGreg Clayton   if (thread_sp)
4451ac04c30SGreg Clayton     return thread_sp->GetID();
4461ac04c30SGreg Clayton   return LLDB_INVALID_THREAD_ID;
44730fdc8d8SChris Lattner }
44830fdc8d8SChris Lattner 
449b9c1b51eSKate Stone uint32_t SBThread::GetIndexID() const {
450baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBThread, GetIndexID);
451baf5664fSJonas Devlieghere 
4527fdf9ef1SGreg Clayton   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
45317a6ad05SGreg Clayton   if (thread_sp)
45417a6ad05SGreg Clayton     return thread_sp->GetIndexID();
45530fdc8d8SChris Lattner   return LLDB_INVALID_INDEX32;
45630fdc8d8SChris Lattner }
4571ac04c30SGreg Clayton 
458b9c1b51eSKate Stone const char *SBThread::GetName() const {
459baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBThread, GetName);
460baf5664fSJonas Devlieghere 
4614838131bSGreg Clayton   const char *name = NULL;
462bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
463bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4644fc6cb9cSJim Ingham 
465b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4667fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
467b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4681ac04c30SGreg Clayton       name = exe_ctx.GetThreadPtr()->GetName();
469c9858e4dSGreg Clayton     }
4707fdf9ef1SGreg Clayton   }
471ceb6b139SCaroline Tice 
4724838131bSGreg Clayton   return name;
47330fdc8d8SChris Lattner }
47430fdc8d8SChris Lattner 
475b9c1b51eSKate Stone const char *SBThread::GetQueueName() const {
476baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBThread, GetQueueName);
477baf5664fSJonas Devlieghere 
4784838131bSGreg Clayton   const char *name = NULL;
479bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
480bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4814fc6cb9cSJim Ingham 
482b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4837fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
484b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4851ac04c30SGreg Clayton       name = exe_ctx.GetThreadPtr()->GetQueueName();
486c9858e4dSGreg Clayton     }
4877fdf9ef1SGreg Clayton   }
488ceb6b139SCaroline Tice 
4894838131bSGreg Clayton   return name;
49030fdc8d8SChris Lattner }
49130fdc8d8SChris Lattner 
492b9c1b51eSKate Stone lldb::queue_id_t SBThread::GetQueueID() const {
493baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::queue_id_t, SBThread, GetQueueID);
494baf5664fSJonas Devlieghere 
4954fdb5863SJason Molenda   queue_id_t id = LLDB_INVALID_QUEUE_ID;
496bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
497bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4984fdb5863SJason Molenda 
499b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
5004fdb5863SJason Molenda     Process::StopLocker stop_locker;
501b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
5024fdb5863SJason Molenda       id = exe_ctx.GetThreadPtr()->GetQueueID();
5034fdb5863SJason Molenda     }
5044fdb5863SJason Molenda   }
5054fdb5863SJason Molenda 
5064fdb5863SJason Molenda   return id;
5074fdb5863SJason Molenda }
5084fdb5863SJason Molenda 
509b9c1b51eSKate Stone bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
510baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, GetInfoItemByPathAsString,
511baf5664fSJonas Devlieghere                      (const char *, lldb::SBStream &), path, strm);
512baf5664fSJonas Devlieghere 
513705b1809SJason Molenda   bool success = false;
514bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
515bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
516705b1809SJason Molenda 
517b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
518705b1809SJason Molenda     Process::StopLocker stop_locker;
519b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
520705b1809SJason Molenda       Thread *thread = exe_ctx.GetThreadPtr();
521705b1809SJason Molenda       StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
522b9c1b51eSKate Stone       if (info_root_sp) {
523b9c1b51eSKate Stone         StructuredData::ObjectSP node =
524b9c1b51eSKate Stone             info_root_sp->GetObjectForDotSeparatedPath(path);
525b9c1b51eSKate Stone         if (node) {
5265bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeString) {
5272833321fSZachary Turner             strm.Printf("%s", node->GetAsString()->GetValue().str().c_str());
528705b1809SJason Molenda             success = true;
529705b1809SJason Molenda           }
5305bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeInteger) {
531705b1809SJason Molenda             strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue());
532705b1809SJason Molenda             success = true;
533705b1809SJason Molenda           }
5345bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeFloat) {
535705b1809SJason Molenda             strm.Printf("0x%f", node->GetAsFloat()->GetValue());
536705b1809SJason Molenda             success = true;
537705b1809SJason Molenda           }
5385bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeBoolean) {
539a6682a41SJonas Devlieghere             if (node->GetAsBoolean()->GetValue())
540705b1809SJason Molenda               strm.Printf("true");
541705b1809SJason Molenda             else
542705b1809SJason Molenda               strm.Printf("false");
543705b1809SJason Molenda             success = true;
544705b1809SJason Molenda           }
5455bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeNull) {
546705b1809SJason Molenda             strm.Printf("null");
547705b1809SJason Molenda             success = true;
548705b1809SJason Molenda           }
549705b1809SJason Molenda         }
550705b1809SJason Molenda       }
551705b1809SJason Molenda     }
552705b1809SJason Molenda   }
553705b1809SJason Molenda 
554705b1809SJason Molenda   return success;
555705b1809SJason Molenda }
556705b1809SJason Molenda 
557b9c1b51eSKate Stone SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
558b9c1b51eSKate Stone                                 ThreadPlan *new_plan) {
55964e7ead1SJim Ingham   SBError sb_error;
56064e7ead1SJim Ingham 
56164e7ead1SJim Ingham   Process *process = exe_ctx.GetProcessPtr();
562b9c1b51eSKate Stone   if (!process) {
56364e7ead1SJim Ingham     sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
56464e7ead1SJim Ingham     return sb_error;
56564e7ead1SJim Ingham   }
56664e7ead1SJim Ingham 
56764e7ead1SJim Ingham   Thread *thread = exe_ctx.GetThreadPtr();
568b9c1b51eSKate Stone   if (!thread) {
56964e7ead1SJim Ingham     sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
57064e7ead1SJim Ingham     return sb_error;
57164e7ead1SJim Ingham   }
57264e7ead1SJim Ingham 
573b9c1b51eSKate Stone   // User level plans should be Master Plans so they can be interrupted, other
57405097246SAdrian Prantl   // plans executed, and then a "continue" will resume the plan.
575b9c1b51eSKate Stone   if (new_plan != NULL) {
57664e7ead1SJim Ingham     new_plan->SetIsMasterPlan(true);
57764e7ead1SJim Ingham     new_plan->SetOkayToDiscard(false);
57864e7ead1SJim Ingham   }
57964e7ead1SJim Ingham 
58064e7ead1SJim Ingham   // Why do we need to set the current thread by ID here???
58164e7ead1SJim Ingham   process->GetThreadList().SetSelectedThreadByID(thread->GetID());
58264e7ead1SJim Ingham 
583dc6224e0SGreg Clayton   if (process->GetTarget().GetDebugger().GetAsyncExecution())
584dc6224e0SGreg Clayton     sb_error.ref() = process->Resume();
585dc6224e0SGreg Clayton   else
586dc6224e0SGreg Clayton     sb_error.ref() = process->ResumeSynchronous(NULL);
58764e7ead1SJim Ingham 
58864e7ead1SJim Ingham   return sb_error;
58964e7ead1SJim Ingham }
59030fdc8d8SChris Lattner 
591b9c1b51eSKate Stone void SBThread::StepOver(lldb::RunMode stop_other_threads) {
592baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOver, (lldb::RunMode),
593baf5664fSJonas Devlieghere                      stop_other_threads);
594baf5664fSJonas Devlieghere 
595859f54b3SAlexander Polyakov   SBError error; // Ignored
596859f54b3SAlexander Polyakov   StepOver(stop_other_threads, error);
597859f54b3SAlexander Polyakov }
598859f54b3SAlexander Polyakov 
599859f54b3SAlexander Polyakov void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
600baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOver, (lldb::RunMode, lldb::SBError &),
601baf5664fSJonas Devlieghere                      stop_other_threads, error);
602baf5664fSJonas Devlieghere 
603bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
604bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
60517a6ad05SGreg Clayton 
606859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
607859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
608859f54b3SAlexander Polyakov     return;
609859f54b3SAlexander Polyakov   }
610859f54b3SAlexander Polyakov 
6111ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
6127ba6e991SJim Ingham   bool abort_other_plans = false;
613b57e4a1bSJason Molenda   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
61430fdc8d8SChris Lattner 
615e103ae92SJonas Devlieghere   Status new_plan_status;
6164d56e9c1SJim Ingham   ThreadPlanSP new_plan_sp;
617b9c1b51eSKate Stone   if (frame_sp) {
618b9c1b51eSKate Stone     if (frame_sp->HasDebugInformation()) {
6194b4b2478SJim Ingham       const LazyBool avoid_no_debug = eLazyBoolCalculate;
62030fdc8d8SChris Lattner       SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
621b9c1b51eSKate Stone       new_plan_sp = thread->QueueThreadPlanForStepOverRange(
622b9c1b51eSKate Stone           abort_other_plans, sc.line_entry, sc, stop_other_threads,
623e103ae92SJonas Devlieghere           new_plan_status, avoid_no_debug);
624b9c1b51eSKate Stone     } else {
625b9c1b51eSKate Stone       new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
626e103ae92SJonas Devlieghere           true, abort_other_plans, stop_other_threads, new_plan_status);
62730fdc8d8SChris Lattner     }
62830fdc8d8SChris Lattner   }
629859f54b3SAlexander Polyakov   error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
63030fdc8d8SChris Lattner }
63130fdc8d8SChris Lattner 
632b9c1b51eSKate Stone void SBThread::StepInto(lldb::RunMode stop_other_threads) {
633baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInto, (lldb::RunMode),
634baf5664fSJonas Devlieghere                      stop_other_threads);
635baf5664fSJonas Devlieghere 
636c627682eSJim Ingham   StepInto(NULL, stop_other_threads);
637c627682eSJim Ingham }
638c627682eSJim Ingham 
639b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name,
640b9c1b51eSKate Stone                         lldb::RunMode stop_other_threads) {
641baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInto, (const char *, lldb::RunMode),
642baf5664fSJonas Devlieghere                      target_name, stop_other_threads);
643baf5664fSJonas Devlieghere 
644859f54b3SAlexander Polyakov   SBError error; // Ignored
645cbf6f9b2SJim Ingham   StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
646cbf6f9b2SJim Ingham }
647cbf6f9b2SJim Ingham 
648b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name, uint32_t end_line,
649b9c1b51eSKate Stone                         SBError &error, lldb::RunMode stop_other_threads) {
650baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInto,
651baf5664fSJonas Devlieghere                      (const char *, uint32_t, lldb::SBError &, lldb::RunMode),
652baf5664fSJonas Devlieghere                      target_name, end_line, error, stop_other_threads);
653baf5664fSJonas Devlieghere 
654ceb6b139SCaroline Tice 
655bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
656bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
65717a6ad05SGreg Clayton 
658859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
659859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
660859f54b3SAlexander Polyakov     return;
661859f54b3SAlexander Polyakov   }
662859f54b3SAlexander Polyakov 
6637ba6e991SJim Ingham   bool abort_other_plans = false;
66430fdc8d8SChris Lattner 
6651ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
666b57e4a1bSJason Molenda   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
6674d56e9c1SJim Ingham   ThreadPlanSP new_plan_sp;
668e103ae92SJonas Devlieghere   Status new_plan_status;
66930fdc8d8SChris Lattner 
670b9c1b51eSKate Stone   if (frame_sp && frame_sp->HasDebugInformation()) {
671cbf6f9b2SJim Ingham     SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
672cbf6f9b2SJim Ingham     AddressRange range;
673cbf6f9b2SJim Ingham     if (end_line == LLDB_INVALID_LINE_NUMBER)
674cbf6f9b2SJim Ingham       range = sc.line_entry.range;
675b9c1b51eSKate Stone     else {
676cbf6f9b2SJim Ingham       if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
677cbf6f9b2SJim Ingham         return;
678cbf6f9b2SJim Ingham     }
679cbf6f9b2SJim Ingham 
680b9c1b51eSKate Stone     const LazyBool step_out_avoids_code_without_debug_info =
681b9c1b51eSKate Stone         eLazyBoolCalculate;
682b9c1b51eSKate Stone     const LazyBool step_in_avoids_code_without_debug_info =
683b9c1b51eSKate Stone         eLazyBoolCalculate;
684b9c1b51eSKate Stone     new_plan_sp = thread->QueueThreadPlanForStepInRange(
685b9c1b51eSKate Stone         abort_other_plans, range, sc, target_name, stop_other_threads,
686e103ae92SJonas Devlieghere         new_plan_status, step_in_avoids_code_without_debug_info,
6874b4b2478SJim Ingham         step_out_avoids_code_without_debug_info);
688b9c1b51eSKate Stone   } else {
689b9c1b51eSKate Stone     new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
690e103ae92SJonas Devlieghere         false, abort_other_plans, stop_other_threads, new_plan_status);
69130fdc8d8SChris Lattner   }
692e103ae92SJonas Devlieghere 
693e103ae92SJonas Devlieghere   if (new_plan_status.Success())
694cbf6f9b2SJim Ingham     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
695e103ae92SJonas Devlieghere   else
696e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
69730fdc8d8SChris Lattner }
69830fdc8d8SChris Lattner 
699b9c1b51eSKate Stone void SBThread::StepOut() {
700baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(void, SBThread, StepOut);
701baf5664fSJonas Devlieghere 
702859f54b3SAlexander Polyakov   SBError error; // Ignored
703859f54b3SAlexander Polyakov   StepOut(error);
704859f54b3SAlexander Polyakov }
705859f54b3SAlexander Polyakov 
706859f54b3SAlexander Polyakov void SBThread::StepOut(SBError &error) {
707baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOut, (lldb::SBError &), error);
708baf5664fSJonas Devlieghere 
709bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
710bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
7114fc6cb9cSJim Ingham 
712859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
713859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
714859f54b3SAlexander Polyakov     return;
715859f54b3SAlexander Polyakov   }
716859f54b3SAlexander Polyakov 
7177ba6e991SJim Ingham   bool abort_other_plans = false;
71894b09246SJim Ingham   bool stop_other_threads = false;
71930fdc8d8SChris Lattner 
7201ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
7211ac04c30SGreg Clayton 
7224b4b2478SJim Ingham   const LazyBool avoid_no_debug = eLazyBoolCalculate;
723e103ae92SJonas Devlieghere   Status new_plan_status;
724b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
725b9c1b51eSKate Stone       abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
726e103ae92SJonas Devlieghere       eVoteNoOpinion, 0, new_plan_status, avoid_no_debug));
727481cef25SGreg Clayton 
728e103ae92SJonas Devlieghere   if (new_plan_status.Success())
729859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
730e103ae92SJonas Devlieghere   else
731e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
732481cef25SGreg Clayton }
733481cef25SGreg Clayton 
734859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
735baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOutOfFrame, (lldb::SBFrame &),
736baf5664fSJonas Devlieghere                      sb_frame);
737baf5664fSJonas Devlieghere 
738859f54b3SAlexander Polyakov   SBError error; // Ignored
739859f54b3SAlexander Polyakov   StepOutOfFrame(sb_frame, error);
740859f54b3SAlexander Polyakov }
741859f54b3SAlexander Polyakov 
742859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
743baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOutOfFrame,
744baf5664fSJonas Devlieghere                      (lldb::SBFrame &, lldb::SBError &), sb_frame, error);
745baf5664fSJonas Devlieghere 
746481cef25SGreg Clayton 
747bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
748bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
7494fc6cb9cSJim Ingham 
750b9c1b51eSKate Stone   if (!sb_frame.IsValid()) {
751859f54b3SAlexander Polyakov     error.SetErrorString("passed invalid SBFrame object");
752989a7558SJim Ingham     return;
753989a7558SJim Ingham   }
754989a7558SJim Ingham 
755b57e4a1bSJason Molenda   StackFrameSP frame_sp(sb_frame.GetFrameSP());
756481cef25SGreg Clayton 
757859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
758859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
759859f54b3SAlexander Polyakov     return;
760859f54b3SAlexander Polyakov   }
761859f54b3SAlexander Polyakov 
7627ba6e991SJim Ingham   bool abort_other_plans = false;
76394b09246SJim Ingham   bool stop_other_threads = false;
7641ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
765b9c1b51eSKate Stone   if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
766859f54b3SAlexander Polyakov     error.SetErrorString("passed a frame from another thread");
767859f54b3SAlexander Polyakov     return;
768989a7558SJim Ingham   }
769481cef25SGreg Clayton 
770e103ae92SJonas Devlieghere   Status new_plan_status;
771b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
772b9c1b51eSKate Stone       abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
773e103ae92SJonas Devlieghere       eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status));
77430fdc8d8SChris Lattner 
775e103ae92SJonas Devlieghere   if (new_plan_status.Success())
776859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
777e103ae92SJonas Devlieghere   else
778e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
77930fdc8d8SChris Lattner }
78030fdc8d8SChris Lattner 
781b9c1b51eSKate Stone void SBThread::StepInstruction(bool step_over) {
782baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInstruction, (bool), step_over);
783baf5664fSJonas Devlieghere 
784859f54b3SAlexander Polyakov   SBError error; // Ignored
785859f54b3SAlexander Polyakov   StepInstruction(step_over, error);
786859f54b3SAlexander Polyakov }
787859f54b3SAlexander Polyakov 
788859f54b3SAlexander Polyakov void SBThread::StepInstruction(bool step_over, SBError &error) {
789baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInstruction, (bool, lldb::SBError &),
790baf5664fSJonas Devlieghere                      step_over, error);
791baf5664fSJonas Devlieghere 
792bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
793bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
794ceb6b139SCaroline Tice 
795859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
796859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
797859f54b3SAlexander Polyakov     return;
798859f54b3SAlexander Polyakov   }
799859f54b3SAlexander Polyakov 
8001ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
801e103ae92SJonas Devlieghere   Status new_plan_status;
802e103ae92SJonas Devlieghere   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction(
803e103ae92SJonas Devlieghere       step_over, true, true, new_plan_status));
80464e7ead1SJim Ingham 
805e103ae92SJonas Devlieghere   if (new_plan_status.Success())
806859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
807e103ae92SJonas Devlieghere   else
808e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
80930fdc8d8SChris Lattner }
81030fdc8d8SChris Lattner 
811b9c1b51eSKate Stone void SBThread::RunToAddress(lldb::addr_t addr) {
812baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, RunToAddress, (lldb::addr_t), addr);
813baf5664fSJonas Devlieghere 
814859f54b3SAlexander Polyakov   SBError error; // Ignored
815859f54b3SAlexander Polyakov   RunToAddress(addr, error);
816859f54b3SAlexander Polyakov }
817859f54b3SAlexander Polyakov 
818859f54b3SAlexander Polyakov void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
819baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, RunToAddress,
820baf5664fSJonas Devlieghere                      (lldb::addr_t, lldb::SBError &), addr, error);
821baf5664fSJonas Devlieghere 
822bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
823bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
824ceb6b139SCaroline Tice 
825859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
826859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
827859f54b3SAlexander Polyakov     return;
828859f54b3SAlexander Polyakov   }
829859f54b3SAlexander Polyakov 
8307ba6e991SJim Ingham   bool abort_other_plans = false;
83130fdc8d8SChris Lattner   bool stop_other_threads = true;
83230fdc8d8SChris Lattner 
833e72dfb32SGreg Clayton   Address target_addr(addr);
83430fdc8d8SChris Lattner 
8351ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
8361ac04c30SGreg Clayton 
837e103ae92SJonas Devlieghere   Status new_plan_status;
838b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
839e103ae92SJonas Devlieghere       abort_other_plans, target_addr, stop_other_threads, new_plan_status));
84064e7ead1SJim Ingham 
841e103ae92SJonas Devlieghere   if (new_plan_status.Success())
842859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
843e103ae92SJonas Devlieghere   else
844e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
84530fdc8d8SChris Lattner }
84630fdc8d8SChris Lattner 
847b9c1b51eSKate Stone SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
848b9c1b51eSKate Stone                                 lldb::SBFileSpec &sb_file_spec, uint32_t line) {
849baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepOverUntil,
850baf5664fSJonas Devlieghere                      (lldb::SBFrame &, lldb::SBFileSpec &, uint32_t), sb_frame,
851baf5664fSJonas Devlieghere                      sb_file_spec, line);
852baf5664fSJonas Devlieghere 
853481cef25SGreg Clayton   SBError sb_error;
854481cef25SGreg Clayton   char path[PATH_MAX];
855481cef25SGreg Clayton 
856bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
857bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
8584fc6cb9cSJim Ingham 
859b57e4a1bSJason Molenda   StackFrameSP frame_sp(sb_frame.GetFrameSP());
86017a6ad05SGreg Clayton 
861b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
8621ac04c30SGreg Clayton     Target *target = exe_ctx.GetTargetPtr();
8631ac04c30SGreg Clayton     Thread *thread = exe_ctx.GetThreadPtr();
864481cef25SGreg Clayton 
865b9c1b51eSKate Stone     if (line == 0) {
866481cef25SGreg Clayton       sb_error.SetErrorString("invalid line argument");
867baf5664fSJonas Devlieghere       return LLDB_RECORD_RESULT(sb_error);
868481cef25SGreg Clayton     }
869481cef25SGreg Clayton 
870b9c1b51eSKate Stone     if (!frame_sp) {
8711ac04c30SGreg Clayton       frame_sp = thread->GetSelectedFrame();
872481cef25SGreg Clayton       if (!frame_sp)
8731ac04c30SGreg Clayton         frame_sp = thread->GetStackFrameAtIndex(0);
874481cef25SGreg Clayton     }
875481cef25SGreg Clayton 
876481cef25SGreg Clayton     SymbolContext frame_sc;
877b9c1b51eSKate Stone     if (!frame_sp) {
878481cef25SGreg Clayton       sb_error.SetErrorString("no valid frames in thread to step");
879baf5664fSJonas Devlieghere       return LLDB_RECORD_RESULT(sb_error);
880481cef25SGreg Clayton     }
881481cef25SGreg Clayton 
882481cef25SGreg Clayton     // If we have a frame, get its line
883b9c1b51eSKate Stone     frame_sc = frame_sp->GetSymbolContext(
884b9c1b51eSKate Stone         eSymbolContextCompUnit | eSymbolContextFunction |
885b9c1b51eSKate Stone         eSymbolContextLineEntry | eSymbolContextSymbol);
886481cef25SGreg Clayton 
887b9c1b51eSKate Stone     if (frame_sc.comp_unit == NULL) {
888b9c1b51eSKate Stone       sb_error.SetErrorStringWithFormat(
889b9c1b51eSKate Stone           "frame %u doesn't have debug information", frame_sp->GetFrameIndex());
890baf5664fSJonas Devlieghere       return LLDB_RECORD_RESULT(sb_error);
891481cef25SGreg Clayton     }
892481cef25SGreg Clayton 
893481cef25SGreg Clayton     FileSpec step_file_spec;
894b9c1b51eSKate Stone     if (sb_file_spec.IsValid()) {
895481cef25SGreg Clayton       // The file spec passed in was valid, so use it
896481cef25SGreg Clayton       step_file_spec = sb_file_spec.ref();
897b9c1b51eSKate Stone     } else {
898481cef25SGreg Clayton       if (frame_sc.line_entry.IsValid())
899481cef25SGreg Clayton         step_file_spec = frame_sc.line_entry.file;
900b9c1b51eSKate Stone       else {
901481cef25SGreg Clayton         sb_error.SetErrorString("invalid file argument or no file for frame");
902baf5664fSJonas Devlieghere         return LLDB_RECORD_RESULT(sb_error);
903481cef25SGreg Clayton       }
904481cef25SGreg Clayton     }
905481cef25SGreg Clayton 
9069b70ddb3SJim Ingham     // Grab the current function, then we will make sure the "until" address is
9079b70ddb3SJim Ingham     // within the function.  We discard addresses that are out of the current
908b9c1b51eSKate Stone     // function, and then if there are no addresses remaining, give an
90905097246SAdrian Prantl     // appropriate error message.
9109b70ddb3SJim Ingham 
9119b70ddb3SJim Ingham     bool all_in_function = true;
9129b70ddb3SJim Ingham     AddressRange fun_range = frame_sc.function->GetAddressRange();
9139b70ddb3SJim Ingham 
914481cef25SGreg Clayton     std::vector<addr_t> step_over_until_addrs;
9157ba6e991SJim Ingham     const bool abort_other_plans = false;
916c02e3344SJim Ingham     const bool stop_other_threads = false;
917481cef25SGreg Clayton     const bool check_inlines = true;
918481cef25SGreg Clayton     const bool exact = false;
919481cef25SGreg Clayton 
920481cef25SGreg Clayton     SymbolContextList sc_list;
921b9c1b51eSKate Stone     const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext(
922b9c1b51eSKate Stone         step_file_spec, line, check_inlines, exact, eSymbolContextLineEntry,
9239b70ddb3SJim Ingham         sc_list);
924b9c1b51eSKate Stone     if (num_matches > 0) {
925481cef25SGreg Clayton       SymbolContext sc;
926b9c1b51eSKate Stone       for (uint32_t i = 0; i < num_matches; ++i) {
927b9c1b51eSKate Stone         if (sc_list.GetContextAtIndex(i, sc)) {
928b9c1b51eSKate Stone           addr_t step_addr =
929b9c1b51eSKate Stone               sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
930b9c1b51eSKate Stone           if (step_addr != LLDB_INVALID_ADDRESS) {
9319b70ddb3SJim Ingham             if (fun_range.ContainsLoadAddress(step_addr, target))
932481cef25SGreg Clayton               step_over_until_addrs.push_back(step_addr);
9339b70ddb3SJim Ingham             else
9349b70ddb3SJim Ingham               all_in_function = false;
935481cef25SGreg Clayton           }
936481cef25SGreg Clayton         }
937481cef25SGreg Clayton       }
938481cef25SGreg Clayton     }
939481cef25SGreg Clayton 
940b9c1b51eSKate Stone     if (step_over_until_addrs.empty()) {
941b9c1b51eSKate Stone       if (all_in_function) {
942481cef25SGreg Clayton         step_file_spec.GetPath(path, sizeof(path));
943b9c1b51eSKate Stone         sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path,
944b9c1b51eSKate Stone                                           line);
945b9c1b51eSKate Stone       } else
94686edbf41SGreg Clayton         sb_error.SetErrorString("step until target not in current function");
947b9c1b51eSKate Stone     } else {
948e103ae92SJonas Devlieghere       Status new_plan_status;
949b9c1b51eSKate Stone       ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil(
950b9c1b51eSKate Stone           abort_other_plans, &step_over_until_addrs[0],
951b9c1b51eSKate Stone           step_over_until_addrs.size(), stop_other_threads,
952e103ae92SJonas Devlieghere           frame_sp->GetFrameIndex(), new_plan_status));
953481cef25SGreg Clayton 
954e103ae92SJonas Devlieghere       if (new_plan_status.Success())
9554d56e9c1SJim Ingham         sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
956e103ae92SJonas Devlieghere       else
957e103ae92SJonas Devlieghere         sb_error.SetErrorString(new_plan_status.AsCString());
958481cef25SGreg Clayton     }
959b9c1b51eSKate Stone   } else {
960481cef25SGreg Clayton     sb_error.SetErrorString("this SBThread object is invalid");
961481cef25SGreg Clayton   }
962baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
963481cef25SGreg Clayton }
964481cef25SGreg Clayton 
965b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) {
966baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
967baf5664fSJonas Devlieghere                      (const char *), script_class_name);
968baf5664fSJonas Devlieghere 
969baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
970baf5664fSJonas Devlieghere       StepUsingScriptedThreadPlan(script_class_name, true));
971c915a7d2SJim Ingham }
972c915a7d2SJim Ingham 
973b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
974b9c1b51eSKate Stone                                               bool resume_immediately) {
975baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
976baf5664fSJonas Devlieghere                      (const char *, bool), script_class_name,
977baf5664fSJonas Devlieghere                      resume_immediately);
978baf5664fSJonas Devlieghere 
979e103ae92SJonas Devlieghere   SBError error;
9802bdbfd50SJim Ingham 
981bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
982bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
9832bdbfd50SJim Ingham 
984b9c1b51eSKate Stone   if (!exe_ctx.HasThreadScope()) {
985e103ae92SJonas Devlieghere     error.SetErrorString("this SBThread object is invalid");
986baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(error);
9872bdbfd50SJim Ingham   }
9882bdbfd50SJim Ingham 
9892bdbfd50SJim Ingham   Thread *thread = exe_ctx.GetThreadPtr();
990e103ae92SJonas Devlieghere   Status new_plan_status;
991e103ae92SJonas Devlieghere   ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted(
992e103ae92SJonas Devlieghere       false, script_class_name, false, new_plan_status);
9932bdbfd50SJim Ingham 
994e103ae92SJonas Devlieghere   if (new_plan_status.Fail()) {
995e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
996baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(error);
997c915a7d2SJim Ingham   }
998c915a7d2SJim Ingham 
999e103ae92SJonas Devlieghere   if (!resume_immediately)
1000baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(error);
1001c915a7d2SJim Ingham 
1002e103ae92SJonas Devlieghere   if (new_plan_status.Success())
1003e103ae92SJonas Devlieghere     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
1004e103ae92SJonas Devlieghere   else
1005e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
10062bdbfd50SJim Ingham 
1007baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(error);
10082bdbfd50SJim Ingham }
10092bdbfd50SJim Ingham 
1010b9c1b51eSKate Stone SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
1011baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, JumpToLine,
1012baf5664fSJonas Devlieghere                      (lldb::SBFileSpec &, uint32_t), file_spec, line);
1013baf5664fSJonas Devlieghere 
1014f86248d9SRichard Mitton   SBError sb_error;
1015f86248d9SRichard Mitton 
1016bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1017bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1018f86248d9SRichard Mitton 
1019b9c1b51eSKate Stone   if (!exe_ctx.HasThreadScope()) {
1020f86248d9SRichard Mitton     sb_error.SetErrorString("this SBThread object is invalid");
1021baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(sb_error);
1022f86248d9SRichard Mitton   }
1023f86248d9SRichard Mitton 
1024f86248d9SRichard Mitton   Thread *thread = exe_ctx.GetThreadPtr();
1025f86248d9SRichard Mitton 
102697206d57SZachary Turner   Status err = thread->JumpToLine(file_spec.get(), line, true);
1027f86248d9SRichard Mitton   sb_error.SetError(err);
1028baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
1029f86248d9SRichard Mitton }
1030f86248d9SRichard Mitton 
1031b9c1b51eSKate Stone SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
1032baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, ReturnFromFrame,
1033baf5664fSJonas Devlieghere                      (lldb::SBFrame &, lldb::SBValue &), frame, return_value);
1034baf5664fSJonas Devlieghere 
10354413758cSJim Ingham   SBError sb_error;
10364413758cSJim Ingham 
1037bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1038bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
10394413758cSJim Ingham 
1040b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
10414413758cSJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
1042b9c1b51eSKate Stone     sb_error.SetError(
1043b9c1b51eSKate Stone         thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
10444413758cSJim Ingham   }
10454413758cSJim Ingham 
1046baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
10474413758cSJim Ingham }
10484413758cSJim Ingham 
1049b9c1b51eSKate Stone SBError SBThread::UnwindInnermostExpression() {
1050baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBError, SBThread,
1051baf5664fSJonas Devlieghere                              UnwindInnermostExpression);
1052baf5664fSJonas Devlieghere 
10534ac8e93aSJim Ingham   SBError sb_error;
10544ac8e93aSJim Ingham 
10554ac8e93aSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
10564ac8e93aSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
10574ac8e93aSJim Ingham 
1058b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
10594ac8e93aSJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
10604ac8e93aSJim Ingham     sb_error.SetError(thread->UnwindInnermostExpression());
10614ac8e93aSJim Ingham     if (sb_error.Success())
10624ac8e93aSJim Ingham       thread->SetSelectedFrameByIndex(0, false);
10634ac8e93aSJim Ingham   }
10644ac8e93aSJim Ingham 
1065baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
10664ac8e93aSJim Ingham }
1067481cef25SGreg Clayton 
1068b9c1b51eSKate Stone bool SBThread::Suspend() {
1069baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, Suspend);
1070baf5664fSJonas Devlieghere 
1071859f54b3SAlexander Polyakov   SBError error; // Ignored
1072859f54b3SAlexander Polyakov   return Suspend(error);
1073859f54b3SAlexander Polyakov }
1074859f54b3SAlexander Polyakov 
1075859f54b3SAlexander Polyakov bool SBThread::Suspend(SBError &error) {
1076baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, Suspend, (lldb::SBError &), error);
1077baf5664fSJonas Devlieghere 
1078b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1079b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1080b2e7d28eSJim Ingham 
1081c9858e4dSGreg Clayton   bool result = false;
1082b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1083c9858e4dSGreg Clayton     Process::StopLocker stop_locker;
1084b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
10851ac04c30SGreg Clayton       exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
1086c9858e4dSGreg Clayton       result = true;
1087b9c1b51eSKate Stone     } else {
1088859f54b3SAlexander Polyakov       error.SetErrorString("process is running");
1089c9858e4dSGreg Clayton     }
1090859f54b3SAlexander Polyakov   } else
1091859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
1092c9858e4dSGreg Clayton   return result;
1093722a0cdcSGreg Clayton }
1094722a0cdcSGreg Clayton 
1095b9c1b51eSKate Stone bool SBThread::Resume() {
1096baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, Resume);
1097baf5664fSJonas Devlieghere 
1098859f54b3SAlexander Polyakov   SBError error; // Ignored
1099859f54b3SAlexander Polyakov   return Resume(error);
1100859f54b3SAlexander Polyakov }
1101859f54b3SAlexander Polyakov 
1102859f54b3SAlexander Polyakov bool SBThread::Resume(SBError &error) {
1103baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, Resume, (lldb::SBError &), error);
1104baf5664fSJonas Devlieghere 
1105b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1106b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1107b2e7d28eSJim Ingham 
1108c9858e4dSGreg Clayton   bool result = false;
1109b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1110c9858e4dSGreg Clayton     Process::StopLocker stop_locker;
1111b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11126c9ed91cSJim Ingham       const bool override_suspend = true;
11136c9ed91cSJim Ingham       exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
1114c9858e4dSGreg Clayton       result = true;
1115b9c1b51eSKate Stone     } else {
1116859f54b3SAlexander Polyakov       error.SetErrorString("process is running");
1117c9858e4dSGreg Clayton     }
1118859f54b3SAlexander Polyakov   } else
1119859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
1120c9858e4dSGreg Clayton   return result;
1121722a0cdcSGreg Clayton }
1122722a0cdcSGreg Clayton 
1123b9c1b51eSKate Stone bool SBThread::IsSuspended() {
1124baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, IsSuspended);
1125baf5664fSJonas Devlieghere 
1126b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1127b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1128b2e7d28eSJim Ingham 
11291ac04c30SGreg Clayton   if (exe_ctx.HasThreadScope())
11301ac04c30SGreg Clayton     return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
1131722a0cdcSGreg Clayton   return false;
1132722a0cdcSGreg Clayton }
1133722a0cdcSGreg Clayton 
1134b9c1b51eSKate Stone bool SBThread::IsStopped() {
1135baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, IsStopped);
1136baf5664fSJonas Devlieghere 
1137b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1138b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1139b2e7d28eSJim Ingham 
1140a75418dbSAndrew Kaylor   if (exe_ctx.HasThreadScope())
1141a75418dbSAndrew Kaylor     return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1142a75418dbSAndrew Kaylor   return false;
1143a75418dbSAndrew Kaylor }
1144a75418dbSAndrew Kaylor 
1145b9c1b51eSKate Stone SBProcess SBThread::GetProcess() {
1146baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBProcess, SBThread, GetProcess);
1147baf5664fSJonas Devlieghere 
1148b9556accSGreg Clayton   SBProcess sb_process;
1149b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1150b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1151b2e7d28eSJim Ingham 
1152b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1153b9c1b51eSKate Stone     // Have to go up to the target so we can get a shared pointer to our
1154b9c1b51eSKate Stone     // process...
11551ac04c30SGreg Clayton     sb_process.SetSP(exe_ctx.GetProcessSP());
115630fdc8d8SChris Lattner   }
1157ceb6b139SCaroline Tice 
1158baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_process);
115930fdc8d8SChris Lattner }
116030fdc8d8SChris Lattner 
1161b9c1b51eSKate Stone uint32_t SBThread::GetNumFrames() {
1162baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBThread, GetNumFrames);
1163baf5664fSJonas Devlieghere 
1164ceb6b139SCaroline Tice   uint32_t num_frames = 0;
1165bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1166bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11674fc6cb9cSJim Ingham 
1168b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11697fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1170b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11711ac04c30SGreg Clayton       num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1172c9858e4dSGreg Clayton     }
11737fdf9ef1SGreg Clayton   }
1174ceb6b139SCaroline Tice 
1175ceb6b139SCaroline Tice   return num_frames;
117630fdc8d8SChris Lattner }
117730fdc8d8SChris Lattner 
1178b9c1b51eSKate Stone SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
1179baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBFrame, SBThread, GetFrameAtIndex, (uint32_t), idx);
1180baf5664fSJonas Devlieghere 
118130fdc8d8SChris Lattner   SBFrame sb_frame;
1182b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1183bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1184bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11854fc6cb9cSJim Ingham 
1186b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11877fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1188b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11891ac04c30SGreg Clayton       frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
1190b9556accSGreg Clayton       sb_frame.SetFrameSP(frame_sp);
1191c9858e4dSGreg Clayton     }
11927fdf9ef1SGreg Clayton   }
1193ceb6b139SCaroline Tice 
1194baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_frame);
119530fdc8d8SChris Lattner }
119630fdc8d8SChris Lattner 
1197b9c1b51eSKate Stone lldb::SBFrame SBThread::GetSelectedFrame() {
1198baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBFrame, SBThread, GetSelectedFrame);
1199baf5664fSJonas Devlieghere 
1200f028a1fbSGreg Clayton   SBFrame sb_frame;
1201b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1202bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1203bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12044fc6cb9cSJim Ingham 
1205b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
12067fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1207b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
12081ac04c30SGreg Clayton       frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame();
1209b9556accSGreg Clayton       sb_frame.SetFrameSP(frame_sp);
1210c9858e4dSGreg Clayton     }
12117fdf9ef1SGreg Clayton   }
1212f028a1fbSGreg Clayton 
1213baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_frame);
1214f028a1fbSGreg Clayton }
1215f028a1fbSGreg Clayton 
1216b9c1b51eSKate Stone lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
1217baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBFrame, SBThread, SetSelectedFrame, (uint32_t),
1218baf5664fSJonas Devlieghere                      idx);
1219baf5664fSJonas Devlieghere 
1220f028a1fbSGreg Clayton   SBFrame sb_frame;
1221b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1222bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1223bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12244fc6cb9cSJim Ingham 
1225b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
12267fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1227b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
12281ac04c30SGreg Clayton       Thread *thread = exe_ctx.GetThreadPtr();
12291ac04c30SGreg Clayton       frame_sp = thread->GetStackFrameAtIndex(idx);
1230b9c1b51eSKate Stone       if (frame_sp) {
12311ac04c30SGreg Clayton         thread->SetSelectedFrame(frame_sp.get());
1232b9556accSGreg Clayton         sb_frame.SetFrameSP(frame_sp);
1233f028a1fbSGreg Clayton       }
1234c9858e4dSGreg Clayton     }
12357fdf9ef1SGreg Clayton   }
1236f028a1fbSGreg Clayton 
1237baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_frame);
1238f028a1fbSGreg Clayton }
1239f028a1fbSGreg Clayton 
1240b9c1b51eSKate Stone bool SBThread::EventIsThreadEvent(const SBEvent &event) {
1241baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(bool, SBThread, EventIsThreadEvent,
1242baf5664fSJonas Devlieghere                             (const lldb::SBEvent &), event);
1243baf5664fSJonas Devlieghere 
12444f465cffSJim Ingham   return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
12454f465cffSJim Ingham }
12464f465cffSJim Ingham 
1247b9c1b51eSKate Stone SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) {
1248baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(lldb::SBFrame, SBThread, GetStackFrameFromEvent,
1249baf5664fSJonas Devlieghere                             (const lldb::SBEvent &), event);
1250baf5664fSJonas Devlieghere 
1251baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
1252baf5664fSJonas Devlieghere       Thread::ThreadEventData::GetStackFrameFromEvent(event.get()));
12534f465cffSJim Ingham }
12544f465cffSJim Ingham 
1255b9c1b51eSKate Stone SBThread SBThread::GetThreadFromEvent(const SBEvent &event) {
1256baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(lldb::SBThread, SBThread, GetThreadFromEvent,
1257baf5664fSJonas Devlieghere                             (const lldb::SBEvent &), event);
1258baf5664fSJonas Devlieghere 
1259baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
1260baf5664fSJonas Devlieghere       Thread::ThreadEventData::GetThreadFromEvent(event.get()));
12614f465cffSJim Ingham }
1262f028a1fbSGreg Clayton 
1263b9c1b51eSKate Stone bool SBThread::operator==(const SBThread &rhs) const {
1264baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, operator==,(const lldb::SBThread &),
1265baf5664fSJonas Devlieghere                            rhs);
1266baf5664fSJonas Devlieghere 
1267b9c1b51eSKate Stone   return m_opaque_sp->GetThreadSP().get() ==
1268b9c1b51eSKate Stone          rhs.m_opaque_sp->GetThreadSP().get();
126930fdc8d8SChris Lattner }
127030fdc8d8SChris Lattner 
1271b9c1b51eSKate Stone bool SBThread::operator!=(const SBThread &rhs) const {
1272baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, operator!=,(const lldb::SBThread &),
1273baf5664fSJonas Devlieghere                            rhs);
1274baf5664fSJonas Devlieghere 
1275b9c1b51eSKate Stone   return m_opaque_sp->GetThreadSP().get() !=
1276b9c1b51eSKate Stone          rhs.m_opaque_sp->GetThreadSP().get();
127730fdc8d8SChris Lattner }
1278dde9cff3SCaroline Tice 
1279b9c1b51eSKate Stone bool SBThread::GetStatus(SBStream &status) const {
1280baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetStatus, (lldb::SBStream &),
1281baf5664fSJonas Devlieghere                            status);
1282baf5664fSJonas Devlieghere 
12834f465cffSJim Ingham   Stream &strm = status.ref();
12844f465cffSJim Ingham 
1285b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1286b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1287b2e7d28eSJim Ingham 
1288b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
12896a9767c7SJim Ingham     exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true);
1290b9c1b51eSKate Stone   } else
12914f465cffSJim Ingham     strm.PutCString("No status");
12924f465cffSJim Ingham 
12934f465cffSJim Ingham   return true;
12944f465cffSJim Ingham }
12954f465cffSJim Ingham 
1296b9c1b51eSKate Stone bool SBThread::GetDescription(SBStream &description) const {
1297baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetDescription, (lldb::SBStream &),
1298baf5664fSJonas Devlieghere                            description);
1299baf5664fSJonas Devlieghere 
13006a9767c7SJim Ingham   return GetDescription(description, false);
13016a9767c7SJim Ingham }
13026a9767c7SJim Ingham 
13036a9767c7SJim Ingham bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
1304baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetDescription,
1305baf5664fSJonas Devlieghere                            (lldb::SBStream &, bool), description, stop_format);
1306baf5664fSJonas Devlieghere 
1307da7bc7d0SGreg Clayton   Stream &strm = description.ref();
1308da7bc7d0SGreg Clayton 
1309b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1310b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1311b2e7d28eSJim Ingham 
1312b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1313b9c1b51eSKate Stone     exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm,
13146a9767c7SJim Ingham                                                     LLDB_INVALID_THREAD_ID,
13156a9767c7SJim Ingham                                                     stop_format);
1316b9c1b51eSKate Stone     // strm.Printf("SBThread: tid = 0x%4.4" PRIx64,
1317b9c1b51eSKate Stone     // exe_ctx.GetThreadPtr()->GetID());
1318b9c1b51eSKate Stone   } else
1319da7bc7d0SGreg Clayton     strm.PutCString("No value");
1320ceb6b139SCaroline Tice 
1321ceb6b139SCaroline Tice   return true;
1322ceb6b139SCaroline Tice }
13235dd4916fSJason Molenda 
1324b9c1b51eSKate Stone SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
1325baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBThread, SBThread, GetExtendedBacktraceThread,
1326baf5664fSJonas Devlieghere                      (const char *), type);
1327baf5664fSJonas Devlieghere 
1328bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1329bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
13305dd4916fSJason Molenda   SBThread sb_origin_thread;
13315dd4916fSJason Molenda 
1332b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
13335dd4916fSJason Molenda     Process::StopLocker stop_locker;
1334b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
13357a2f7904SJason Molenda       ThreadSP real_thread(exe_ctx.GetThreadSP());
1336b9c1b51eSKate Stone       if (real_thread) {
13375dd4916fSJason Molenda         ConstString type_const(type);
13387a2f7904SJason Molenda         Process *process = exe_ctx.GetProcessPtr();
1339b9c1b51eSKate Stone         if (process) {
13407a2f7904SJason Molenda           SystemRuntime *runtime = process->GetSystemRuntime();
1341b9c1b51eSKate Stone           if (runtime) {
1342b9c1b51eSKate Stone             ThreadSP new_thread_sp(
1343b9c1b51eSKate Stone                 runtime->GetExtendedBacktraceThread(real_thread, type_const));
1344b9c1b51eSKate Stone             if (new_thread_sp) {
1345b9c1b51eSKate Stone               // Save this in the Process' ExtendedThreadList so a strong
134605097246SAdrian Prantl               // pointer retains the object.
13477a2f7904SJason Molenda               process->GetExtendedThreadList().AddThread(new_thread_sp);
13487a2f7904SJason Molenda               sb_origin_thread.SetThread(new_thread_sp);
1349a6e9130dSJason Molenda             }
1350a6e9130dSJason Molenda           }
13517a2f7904SJason Molenda         }
13525dd4916fSJason Molenda       }
13535dd4916fSJason Molenda     }
13545dd4916fSJason Molenda   }
13555dd4916fSJason Molenda 
1356baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_origin_thread);
13575dd4916fSJason Molenda }
13588ee9cb58SJason Molenda 
1359b9c1b51eSKate Stone uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
1360baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBThread,
1361baf5664fSJonas Devlieghere                              GetExtendedBacktraceOriginatingIndexID);
1362baf5664fSJonas Devlieghere 
13638ee9cb58SJason Molenda   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
13648ee9cb58SJason Molenda   if (thread_sp)
13658ee9cb58SJason Molenda     return thread_sp->GetExtendedBacktraceOriginatingIndexID();
13668ee9cb58SJason Molenda   return LLDB_INVALID_INDEX32;
13678ee9cb58SJason Molenda }
1368b4892cd2SJason Molenda 
1369e60bc53bSKuba Mracek SBValue SBThread::GetCurrentException() {
1370baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBValue, SBThread, GetCurrentException);
1371e60bc53bSKuba Mracek 
1372baf5664fSJonas Devlieghere   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1373baf5664fSJonas Devlieghere   if (!thread_sp)
1374baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(SBValue());
1375baf5664fSJonas Devlieghere 
1376baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(SBValue(thread_sp->GetCurrentException()));
1377e60bc53bSKuba Mracek }
1378e60bc53bSKuba Mracek 
1379e60bc53bSKuba Mracek SBThread SBThread::GetCurrentExceptionBacktrace() {
1380baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBThread, SBThread,
1381baf5664fSJonas Devlieghere                              GetCurrentExceptionBacktrace);
1382e60bc53bSKuba Mracek 
1383baf5664fSJonas Devlieghere   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1384baf5664fSJonas Devlieghere   if (!thread_sp)
1385baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(SBThread());
1386baf5664fSJonas Devlieghere 
1387baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
1388baf5664fSJonas Devlieghere       SBThread(thread_sp->GetCurrentExceptionBacktrace()));
1389c9e1190aSKuba Mracek }
1390e60bc53bSKuba Mracek 
1391b9c1b51eSKate Stone bool SBThread::SafeToCallFunctions() {
1392baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, SafeToCallFunctions);
1393baf5664fSJonas Devlieghere 
1394b4892cd2SJason Molenda   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1395b4892cd2SJason Molenda   if (thread_sp)
1396b4892cd2SJason Molenda     return thread_sp->SafeToCallFunctions();
1397b4892cd2SJason Molenda   return true;
1398b4892cd2SJason Molenda }
13992bdbfd50SJim Ingham 
1400b9c1b51eSKate Stone lldb_private::Thread *SBThread::operator->() {
1401baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb_private::Thread *, SBThread, operator->);
1402baf5664fSJonas Devlieghere 
14032bdbfd50SJim Ingham   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
14042bdbfd50SJim Ingham   if (thread_sp)
14052bdbfd50SJim Ingham     return thread_sp.get();
14062bdbfd50SJim Ingham   else
14072bdbfd50SJim Ingham     return NULL;
14082bdbfd50SJim Ingham }
14092bdbfd50SJim Ingham 
1410b9c1b51eSKate Stone lldb_private::Thread *SBThread::get() {
1411baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb_private::Thread *, SBThread, get);
1412baf5664fSJonas Devlieghere 
14132bdbfd50SJim Ingham   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
14142bdbfd50SJim Ingham   if (thread_sp)
14152bdbfd50SJim Ingham     return thread_sp.get();
14162bdbfd50SJim Ingham   else
14172bdbfd50SJim Ingham     return NULL;
14182bdbfd50SJim Ingham }
1419*ae211eceSMichal Gorny 
1420*ae211eceSMichal Gorny namespace lldb_private {
1421*ae211eceSMichal Gorny namespace repro {
1422*ae211eceSMichal Gorny 
1423*ae211eceSMichal Gorny template <>
1424*ae211eceSMichal Gorny void RegisterMethods<SBThread>(Registry &R) {
1425*ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(const char *, SBThread, GetBroadcasterClassName,
1426*ae211eceSMichal Gorny                               ());
1427*ae211eceSMichal Gorny   LLDB_REGISTER_CONSTRUCTOR(SBThread, ());
1428*ae211eceSMichal Gorny   LLDB_REGISTER_CONSTRUCTOR(SBThread, (const lldb::ThreadSP &));
1429*ae211eceSMichal Gorny   LLDB_REGISTER_CONSTRUCTOR(SBThread, (const lldb::SBThread &));
1430*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(const lldb::SBThread &,
1431*ae211eceSMichal Gorny                        SBThread, operator=,(const lldb::SBThread &));
1432*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(lldb::SBQueue, SBThread, GetQueue, ());
1433*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, IsValid, ());
1434*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, operator bool, ());
1435*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, Clear, ());
1436*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::StopReason, SBThread, GetStopReason, ());
1437*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(size_t, SBThread, GetStopReasonDataCount, ());
1438*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(uint64_t, SBThread, GetStopReasonDataAtIndex,
1439*ae211eceSMichal Gorny                        (uint32_t));
1440*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, GetStopReasonExtendedInfoAsJSON,
1441*ae211eceSMichal Gorny                        (lldb::SBStream &));
1442*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBThreadCollection, SBThread,
1443*ae211eceSMichal Gorny                        GetStopReasonExtendedBacktraces,
1444*ae211eceSMichal Gorny                        (lldb::InstrumentationRuntimeType));
1445*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(size_t, SBThread, GetStopDescription,
1446*ae211eceSMichal Gorny                        (char *, size_t));
1447*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBValue, SBThread, GetStopReturnValue, ());
1448*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(lldb::tid_t, SBThread, GetThreadID, ());
1449*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(uint32_t, SBThread, GetIndexID, ());
1450*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(const char *, SBThread, GetName, ());
1451*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(const char *, SBThread, GetQueueName, ());
1452*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(lldb::queue_id_t, SBThread, GetQueueID, ());
1453*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, GetInfoItemByPathAsString,
1454*ae211eceSMichal Gorny                        (const char *, lldb::SBStream &));
1455*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOver, (lldb::RunMode));
1456*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOver,
1457*ae211eceSMichal Gorny                        (lldb::RunMode, lldb::SBError &));
1458*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInto, (lldb::RunMode));
1459*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInto,
1460*ae211eceSMichal Gorny                        (const char *, lldb::RunMode));
1461*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(
1462*ae211eceSMichal Gorny       void, SBThread, StepInto,
1463*ae211eceSMichal Gorny       (const char *, uint32_t, lldb::SBError &, lldb::RunMode));
1464*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOut, ());
1465*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOut, (lldb::SBError &));
1466*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOutOfFrame, (lldb::SBFrame &));
1467*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOutOfFrame,
1468*ae211eceSMichal Gorny                        (lldb::SBFrame &, lldb::SBError &));
1469*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInstruction, (bool));
1470*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInstruction,
1471*ae211eceSMichal Gorny                        (bool, lldb::SBError &));
1472*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, RunToAddress, (lldb::addr_t));
1473*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, RunToAddress,
1474*ae211eceSMichal Gorny                        (lldb::addr_t, lldb::SBError &));
1475*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepOverUntil,
1476*ae211eceSMichal Gorny                        (lldb::SBFrame &, lldb::SBFileSpec &, uint32_t));
1477*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
1478*ae211eceSMichal Gorny                        (const char *));
1479*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
1480*ae211eceSMichal Gorny                        (const char *, bool));
1481*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, JumpToLine,
1482*ae211eceSMichal Gorny                        (lldb::SBFileSpec &, uint32_t));
1483*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, ReturnFromFrame,
1484*ae211eceSMichal Gorny                        (lldb::SBFrame &, lldb::SBValue &));
1485*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, UnwindInnermostExpression,
1486*ae211eceSMichal Gorny                        ());
1487*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Suspend, ());
1488*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Suspend, (lldb::SBError &));
1489*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Resume, ());
1490*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Resume, (lldb::SBError &));
1491*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, IsSuspended, ());
1492*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, IsStopped, ());
1493*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBProcess, SBThread, GetProcess, ());
1494*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(uint32_t, SBThread, GetNumFrames, ());
1495*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, GetFrameAtIndex, (uint32_t));
1496*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, GetSelectedFrame, ());
1497*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, SetSelectedFrame, (uint32_t));
1498*ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(bool, SBThread, EventIsThreadEvent,
1499*ae211eceSMichal Gorny                               (const lldb::SBEvent &));
1500*ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(lldb::SBFrame, SBThread, GetStackFrameFromEvent,
1501*ae211eceSMichal Gorny                               (const lldb::SBEvent &));
1502*ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(lldb::SBThread, SBThread, GetThreadFromEvent,
1503*ae211eceSMichal Gorny                               (const lldb::SBEvent &));
1504*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool,
1505*ae211eceSMichal Gorny                              SBThread, operator==,(const lldb::SBThread &));
1506*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool,
1507*ae211eceSMichal Gorny                              SBThread, operator!=,(const lldb::SBThread &));
1508*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetStatus, (lldb::SBStream &));
1509*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetDescription,
1510*ae211eceSMichal Gorny                              (lldb::SBStream &));
1511*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetDescription,
1512*ae211eceSMichal Gorny                              (lldb::SBStream &, bool));
1513*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBThread, SBThread, GetExtendedBacktraceThread,
1514*ae211eceSMichal Gorny                        (const char *));
1515*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(uint32_t, SBThread,
1516*ae211eceSMichal Gorny                        GetExtendedBacktraceOriginatingIndexID, ());
1517*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBValue, SBThread, GetCurrentException, ());
1518*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBThread, SBThread, GetCurrentExceptionBacktrace,
1519*ae211eceSMichal Gorny                        ());
1520*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, SafeToCallFunctions, ());
1521*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb_private::Thread *, SBThread, operator->,());
1522*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb_private::Thread *, SBThread, get, ());
1523*ae211eceSMichal Gorny }
1524*ae211eceSMichal Gorny 
1525*ae211eceSMichal Gorny }
1526*ae211eceSMichal Gorny }
1527