130fdc8d8SChris Lattner //===-- SBThread.cpp --------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
104c5de699SEli Friedman #include "lldb/API/SBThread.h"
1130fdc8d8SChris Lattner 
1230fdc8d8SChris Lattner #include "lldb/API/SBFileSpec.h"
13dde9cff3SCaroline Tice #include "lldb/API/SBStream.h"
14b9c1b51eSKate Stone #include "lldb/API/SBSymbolContext.h"
154e78f606SGreg Clayton #include "lldb/Breakpoint/BreakpointLocation.h"
166611103cSGreg Clayton #include "lldb/Core/Debugger.h"
17a75418dbSAndrew Kaylor #include "lldb/Core/State.h"
1830fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h"
19a78bd7ffSZachary Turner #include "lldb/Core/ValueObject.h"
206611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
2193749ab3SZachary Turner #include "lldb/Symbol/CompileUnit.h"
22b9c1b51eSKate Stone #include "lldb/Symbol/SymbolContext.h"
2330fdc8d8SChris Lattner #include "lldb/Target/Process.h"
24b9ffa98cSJason Molenda #include "lldb/Target/Queue.h"
25f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h"
26b9c1b51eSKate Stone #include "lldb/Target/SystemRuntime.h"
2730fdc8d8SChris Lattner #include "lldb/Target/Target.h"
28b9c1b51eSKate Stone #include "lldb/Target/Thread.h"
2930fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h"
30b9c1b51eSKate Stone #include "lldb/Target/ThreadPlanStepInRange.h"
3130fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h"
3230fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h"
3330fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h"
34b9c1b51eSKate Stone #include "lldb/Target/UnixSignals.h"
35bf9a7730SZachary Turner #include "lldb/Utility/Stream.h"
36f2a8bccfSPavel Labath #include "lldb/Utility/StructuredData.h"
3730fdc8d8SChris Lattner 
384c5de699SEli Friedman #include "lldb/API/SBAddress.h"
394c5de699SEli Friedman #include "lldb/API/SBDebugger.h"
404f465cffSJim Ingham #include "lldb/API/SBEvent.h"
4173ca05a2SJim Ingham #include "lldb/API/SBFrame.h"
424c5de699SEli Friedman #include "lldb/API/SBProcess.h"
436a831436SKuba Brecka #include "lldb/API/SBThreadCollection.h"
442bdbfd50SJim Ingham #include "lldb/API/SBThreadPlan.h"
4573ca05a2SJim Ingham #include "lldb/API/SBValue.h"
465bfee5f1SAbhishek Aggarwal #include "lldb/lldb-enumerations.h"
4730fdc8d8SChris Lattner 
4830fdc8d8SChris Lattner using namespace lldb;
4930fdc8d8SChris Lattner using namespace lldb_private;
5030fdc8d8SChris Lattner 
51b9c1b51eSKate Stone const char *SBThread::GetBroadcasterClassName() {
524f465cffSJim Ingham   return Thread::GetStaticBroadcasterClass().AsCString();
534f465cffSJim Ingham }
544f465cffSJim Ingham 
55cfd1acedSGreg Clayton //----------------------------------------------------------------------
56cfd1acedSGreg Clayton // Constructors
57cfd1acedSGreg Clayton //----------------------------------------------------------------------
58b9c1b51eSKate Stone SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {}
5930fdc8d8SChris Lattner 
60b9c1b51eSKate Stone SBThread::SBThread(const ThreadSP &lldb_object_sp)
61b9c1b51eSKate Stone     : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {}
6230fdc8d8SChris Lattner 
63b9c1b51eSKate Stone SBThread::SBThread(const SBThread &rhs)
64b9c1b51eSKate Stone     : m_opaque_sp(new ExecutionContextRef(*rhs.m_opaque_sp)) {}
6530fdc8d8SChris Lattner 
6630fdc8d8SChris Lattner //----------------------------------------------------------------------
67cfd1acedSGreg Clayton // Assignment operator
68cfd1acedSGreg Clayton //----------------------------------------------------------------------
69cfd1acedSGreg Clayton 
70b9c1b51eSKate Stone const lldb::SBThread &SBThread::operator=(const SBThread &rhs) {
71cfd1acedSGreg Clayton   if (this != &rhs)
727fdf9ef1SGreg Clayton     *m_opaque_sp = *rhs.m_opaque_sp;
73cfd1acedSGreg Clayton   return *this;
74cfd1acedSGreg Clayton }
75cfd1acedSGreg Clayton 
76cfd1acedSGreg Clayton //----------------------------------------------------------------------
7730fdc8d8SChris Lattner // Destructor
7830fdc8d8SChris Lattner //----------------------------------------------------------------------
79b9c1b51eSKate Stone SBThread::~SBThread() {}
8030fdc8d8SChris Lattner 
81b9c1b51eSKate Stone lldb::SBQueue SBThread::GetQueue() const {
82b9ffa98cSJason Molenda   SBQueue sb_queue;
83b9ffa98cSJason Molenda   QueueSP queue_sp;
84bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
85bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
86b9ffa98cSJason Molenda 
87b9ffa98cSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
88b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
89b9ffa98cSJason Molenda     Process::StopLocker stop_locker;
90b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
91b9ffa98cSJason Molenda       queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
92b9c1b51eSKate Stone       if (queue_sp) {
93b9ffa98cSJason Molenda         sb_queue.SetQueue(queue_sp);
94b9ffa98cSJason Molenda       }
95b9c1b51eSKate Stone     } else {
96b9ffa98cSJason Molenda       if (log)
97358cf1eaSGreg Clayton         log->Printf("SBThread(%p)::GetQueue() => error: process is running",
98b9ffa98cSJason Molenda                     static_cast<void *>(exe_ctx.GetThreadPtr()));
99b9ffa98cSJason Molenda     }
100b9ffa98cSJason Molenda   }
101b9ffa98cSJason Molenda 
102b9ffa98cSJason Molenda   if (log)
103358cf1eaSGreg Clayton     log->Printf("SBThread(%p)::GetQueue () => SBQueue(%p)",
104b9c1b51eSKate Stone                 static_cast<void *>(exe_ctx.GetThreadPtr()),
105b9c1b51eSKate Stone                 static_cast<void *>(queue_sp.get()));
106b9ffa98cSJason Molenda 
107b9ffa98cSJason Molenda   return sb_queue;
108b9ffa98cSJason Molenda }
109b9ffa98cSJason Molenda 
110b9c1b51eSKate Stone bool SBThread::IsValid() const {
111bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
112bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1137fa7dc36SJim Ingham 
1147fa7dc36SJim Ingham   Target *target = exe_ctx.GetTargetPtr();
1157fa7dc36SJim Ingham   Process *process = exe_ctx.GetProcessPtr();
116b9c1b51eSKate Stone   if (target && process) {
1177fa7dc36SJim Ingham     Process::StopLocker stop_locker;
1187fa7dc36SJim Ingham     if (stop_locker.TryLock(&process->GetRunLock()))
1197fdf9ef1SGreg Clayton       return m_opaque_sp->GetThreadSP().get() != NULL;
12030fdc8d8SChris Lattner   }
1217fa7dc36SJim Ingham   // Without a valid target & process, this thread can't be valid.
1227fa7dc36SJim Ingham   return false;
1237fa7dc36SJim Ingham }
12430fdc8d8SChris Lattner 
125b9c1b51eSKate Stone void SBThread::Clear() { m_opaque_sp->Clear(); }
12648e42549SGreg Clayton 
127b9c1b51eSKate Stone StopReason SBThread::GetStopReason() {
1285160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
129ceb6b139SCaroline Tice 
130ceb6b139SCaroline Tice   StopReason reason = eStopReasonInvalid;
131bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
132bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1334fc6cb9cSJim Ingham 
134b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1357fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
136b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
13797d5cf05SGreg Clayton       return exe_ctx.GetThreadPtr()->GetStopReason();
138b9c1b51eSKate Stone     } else {
139c9858e4dSGreg Clayton       if (log)
140b9c1b51eSKate Stone         log->Printf(
141b9c1b51eSKate Stone             "SBThread(%p)::GetStopReason() => error: process is running",
142324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
143c9858e4dSGreg Clayton     }
1447fdf9ef1SGreg Clayton   }
145ceb6b139SCaroline Tice 
146ceb6b139SCaroline Tice   if (log)
147324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetStopReason () => %s",
148324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
149750cd175SCaroline Tice                 Thread::StopReasonAsCString(reason));
150ceb6b139SCaroline Tice 
151ceb6b139SCaroline Tice   return reason;
15230fdc8d8SChris Lattner }
15330fdc8d8SChris Lattner 
154b9c1b51eSKate Stone size_t SBThread::GetStopReasonDataCount() {
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())) {
1611ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
162b9c1b51eSKate Stone       if (stop_info_sp) {
1634e78f606SGreg Clayton         StopReason reason = stop_info_sp->GetStopReason();
164b9c1b51eSKate Stone         switch (reason) {
1654e78f606SGreg Clayton         case eStopReasonInvalid:
1664e78f606SGreg Clayton         case eStopReasonNone:
1674e78f606SGreg Clayton         case eStopReasonTrace:
16890ba8115SGreg Clayton         case eStopReasonExec:
1694e78f606SGreg Clayton         case eStopReasonPlanComplete:
170f85defaeSAndrew Kaylor         case eStopReasonThreadExiting:
171afdf842bSKuba Brecka         case eStopReasonInstrumentation:
1724e78f606SGreg Clayton           // There is no data for these stop reasons.
1734e78f606SGreg Clayton           return 0;
1744e78f606SGreg Clayton 
175b9c1b51eSKate Stone         case eStopReasonBreakpoint: {
1764e78f606SGreg Clayton           break_id_t site_id = stop_info_sp->GetValue();
177b9c1b51eSKate Stone           lldb::BreakpointSiteSP bp_site_sp(
178b9c1b51eSKate Stone               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
179b9c1b51eSKate Stone                   site_id));
1804e78f606SGreg Clayton           if (bp_site_sp)
1814e78f606SGreg Clayton             return bp_site_sp->GetNumberOfOwners() * 2;
1824e78f606SGreg Clayton           else
1834e78f606SGreg Clayton             return 0; // Breakpoint must have cleared itself...
184b9c1b51eSKate Stone         } break;
1854e78f606SGreg Clayton 
1864e78f606SGreg Clayton         case eStopReasonWatchpoint:
187290fa41bSJohnny Chen           return 1;
1884e78f606SGreg Clayton 
1894e78f606SGreg Clayton         case eStopReasonSignal:
1904e78f606SGreg Clayton           return 1;
1914e78f606SGreg Clayton 
1924e78f606SGreg Clayton         case eStopReasonException:
1934e78f606SGreg Clayton           return 1;
1944e78f606SGreg Clayton         }
1954e78f606SGreg Clayton       }
196b9c1b51eSKate Stone     } else {
1975160ce5cSGreg Clayton       Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
198c9858e4dSGreg Clayton       if (log)
199b9c1b51eSKate Stone         log->Printf("SBThread(%p)::GetStopReasonDataCount() => error: process "
200b9c1b51eSKate Stone                     "is running",
201324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
202c9858e4dSGreg Clayton     }
2037fdf9ef1SGreg Clayton   }
2044e78f606SGreg Clayton   return 0;
2054e78f606SGreg Clayton }
2064e78f606SGreg Clayton 
207b9c1b51eSKate Stone uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
208bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
209bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
2104fc6cb9cSJim Ingham 
211b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
2127fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
213b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
2141ac04c30SGreg Clayton       Thread *thread = exe_ctx.GetThreadPtr();
2151ac04c30SGreg Clayton       StopInfoSP stop_info_sp = thread->GetStopInfo();
216b9c1b51eSKate Stone       if (stop_info_sp) {
2174e78f606SGreg Clayton         StopReason reason = stop_info_sp->GetStopReason();
218b9c1b51eSKate Stone         switch (reason) {
2194e78f606SGreg Clayton         case eStopReasonInvalid:
2204e78f606SGreg Clayton         case eStopReasonNone:
2214e78f606SGreg Clayton         case eStopReasonTrace:
22290ba8115SGreg Clayton         case eStopReasonExec:
2234e78f606SGreg Clayton         case eStopReasonPlanComplete:
224f85defaeSAndrew Kaylor         case eStopReasonThreadExiting:
225afdf842bSKuba Brecka         case eStopReasonInstrumentation:
2264e78f606SGreg Clayton           // There is no data for these stop reasons.
2274e78f606SGreg Clayton           return 0;
2284e78f606SGreg Clayton 
229b9c1b51eSKate Stone         case eStopReasonBreakpoint: {
2304e78f606SGreg Clayton           break_id_t site_id = stop_info_sp->GetValue();
231b9c1b51eSKate Stone           lldb::BreakpointSiteSP bp_site_sp(
232b9c1b51eSKate Stone               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
233b9c1b51eSKate Stone                   site_id));
234b9c1b51eSKate Stone           if (bp_site_sp) {
2354e78f606SGreg Clayton             uint32_t bp_index = idx / 2;
236b9c1b51eSKate Stone             BreakpointLocationSP bp_loc_sp(
237b9c1b51eSKate Stone                 bp_site_sp->GetOwnerAtIndex(bp_index));
238b9c1b51eSKate Stone             if (bp_loc_sp) {
239b9c1b51eSKate Stone               if (idx & 1) {
2404e78f606SGreg Clayton                 // Odd idx, return the breakpoint location ID
2414e78f606SGreg Clayton                 return bp_loc_sp->GetID();
242b9c1b51eSKate Stone               } else {
2434e78f606SGreg Clayton                 // Even idx, return the breakpoint ID
2444e78f606SGreg Clayton                 return bp_loc_sp->GetBreakpoint().GetID();
2454e78f606SGreg Clayton               }
2464e78f606SGreg Clayton             }
2474e78f606SGreg Clayton           }
2484e78f606SGreg Clayton           return LLDB_INVALID_BREAK_ID;
249b9c1b51eSKate Stone         } break;
2504e78f606SGreg Clayton 
2514e78f606SGreg Clayton         case eStopReasonWatchpoint:
252290fa41bSJohnny Chen           return stop_info_sp->GetValue();
2534e78f606SGreg Clayton 
2544e78f606SGreg Clayton         case eStopReasonSignal:
2554e78f606SGreg Clayton           return stop_info_sp->GetValue();
2564e78f606SGreg Clayton 
2574e78f606SGreg Clayton         case eStopReasonException:
2584e78f606SGreg Clayton           return stop_info_sp->GetValue();
2594e78f606SGreg Clayton         }
2604e78f606SGreg Clayton       }
261b9c1b51eSKate Stone     } else {
2625160ce5cSGreg Clayton       Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
263c9858e4dSGreg Clayton       if (log)
264b9c1b51eSKate Stone         log->Printf("SBThread(%p)::GetStopReasonDataAtIndex() => error: "
265b9c1b51eSKate Stone                     "process is running",
266324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
267c9858e4dSGreg Clayton     }
2687fdf9ef1SGreg Clayton   }
2694e78f606SGreg Clayton   return 0;
2704e78f606SGreg Clayton }
2714e78f606SGreg Clayton 
272b9c1b51eSKate Stone bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) {
273afdf842bSKuba Brecka   Stream &strm = stream.ref();
274afdf842bSKuba Brecka 
275b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
276b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
277b2e7d28eSJim Ingham 
278afdf842bSKuba Brecka   if (!exe_ctx.HasThreadScope())
279afdf842bSKuba Brecka     return false;
280afdf842bSKuba Brecka 
281afdf842bSKuba Brecka   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
282afdf842bSKuba Brecka   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
283afdf842bSKuba Brecka   if (!info)
284afdf842bSKuba Brecka     return false;
285afdf842bSKuba Brecka 
286afdf842bSKuba Brecka   info->Dump(strm);
287afdf842bSKuba Brecka 
288afdf842bSKuba Brecka   return true;
289afdf842bSKuba Brecka }
290afdf842bSKuba Brecka 
2916a831436SKuba Brecka SBThreadCollection
292b9c1b51eSKate Stone SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
2936a831436SKuba Brecka   ThreadCollectionSP threads;
2946a831436SKuba Brecka   threads.reset(new ThreadCollection());
2956a831436SKuba Brecka 
296b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
297b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
298b2e7d28eSJim Ingham 
2996a831436SKuba Brecka   if (!exe_ctx.HasThreadScope())
3001aad8fb7SKuba Brecka     return threads;
3016a831436SKuba Brecka 
3026a831436SKuba Brecka   ProcessSP process_sp = exe_ctx.GetProcessSP();
3036a831436SKuba Brecka 
3046a831436SKuba Brecka   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
3056a831436SKuba Brecka   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
3066a831436SKuba Brecka   if (!info)
3076a831436SKuba Brecka     return threads;
3086a831436SKuba Brecka 
309b9c1b51eSKate Stone   return process_sp->GetInstrumentationRuntime(type)
310b9c1b51eSKate Stone       ->GetBacktracesFromExtendedStopInfo(info);
3116a831436SKuba Brecka }
3126a831436SKuba Brecka 
313b9c1b51eSKate Stone size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
3145160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
315ceb6b139SCaroline Tice 
316bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
317bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3184fc6cb9cSJim Ingham 
319b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
3207fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
321b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
3227fdf9ef1SGreg Clayton 
3231ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
324b9c1b51eSKate Stone       if (stop_info_sp) {
325b15bfc75SJim Ingham         const char *stop_desc = stop_info_sp->GetDescription();
326b9c1b51eSKate Stone         if (stop_desc) {
327ceb6b139SCaroline Tice           if (log)
328b9c1b51eSKate Stone             log->Printf(
329b9c1b51eSKate Stone                 "SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
330b9c1b51eSKate Stone                 static_cast<void *>(exe_ctx.GetThreadPtr()), stop_desc);
33130fdc8d8SChris Lattner           if (dst)
33230fdc8d8SChris Lattner             return ::snprintf(dst, dst_len, "%s", stop_desc);
333b9c1b51eSKate Stone           else {
334b9c1b51eSKate Stone             // NULL dst passed in, return the length needed to contain the
335b9c1b51eSKate Stone             // description
33630fdc8d8SChris Lattner             return ::strlen(stop_desc) + 1; // Include the NULL byte for size
33730fdc8d8SChris Lattner           }
338b9c1b51eSKate Stone         } else {
33930fdc8d8SChris Lattner           size_t stop_desc_len = 0;
340b9c1b51eSKate Stone           switch (stop_info_sp->GetStopReason()) {
34130fdc8d8SChris Lattner           case eStopReasonTrace:
342b9c1b51eSKate Stone           case eStopReasonPlanComplete: {
34330fdc8d8SChris Lattner             static char trace_desc[] = "step";
34430fdc8d8SChris Lattner             stop_desc = trace_desc;
345b9c1b51eSKate Stone             stop_desc_len =
346b9c1b51eSKate Stone                 sizeof(trace_desc); // Include the NULL byte for size
347b9c1b51eSKate Stone           } break;
34830fdc8d8SChris Lattner 
349b9c1b51eSKate Stone           case eStopReasonBreakpoint: {
35030fdc8d8SChris Lattner             static char bp_desc[] = "breakpoint hit";
35130fdc8d8SChris Lattner             stop_desc = bp_desc;
35230fdc8d8SChris Lattner             stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
353b9c1b51eSKate Stone           } break;
35430fdc8d8SChris Lattner 
355b9c1b51eSKate Stone           case eStopReasonWatchpoint: {
35630fdc8d8SChris Lattner             static char wp_desc[] = "watchpoint hit";
35730fdc8d8SChris Lattner             stop_desc = wp_desc;
35830fdc8d8SChris Lattner             stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
359b9c1b51eSKate Stone           } break;
36030fdc8d8SChris Lattner 
361b9c1b51eSKate Stone           case eStopReasonSignal: {
362b9c1b51eSKate Stone             stop_desc =
363b9c1b51eSKate Stone                 exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString(
364b9c1b51eSKate Stone                     stop_info_sp->GetValue());
365b9c1b51eSKate Stone             if (stop_desc == NULL || stop_desc[0] == '\0') {
36630fdc8d8SChris Lattner               static char signal_desc[] = "signal";
36730fdc8d8SChris Lattner               stop_desc = signal_desc;
368b9c1b51eSKate Stone               stop_desc_len =
369b9c1b51eSKate Stone                   sizeof(signal_desc); // Include the NULL byte for size
37030fdc8d8SChris Lattner             }
371b9c1b51eSKate Stone           } break;
37230fdc8d8SChris Lattner 
373b9c1b51eSKate Stone           case eStopReasonException: {
37430fdc8d8SChris Lattner             char exc_desc[] = "exception";
37530fdc8d8SChris Lattner             stop_desc = exc_desc;
37630fdc8d8SChris Lattner             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
377b9c1b51eSKate Stone           } break;
378c982c768SGreg Clayton 
379b9c1b51eSKate Stone           case eStopReasonExec: {
38090ba8115SGreg Clayton             char exc_desc[] = "exec";
38190ba8115SGreg Clayton             stop_desc = exc_desc;
38290ba8115SGreg Clayton             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
383b9c1b51eSKate Stone           } break;
38490ba8115SGreg Clayton 
385b9c1b51eSKate Stone           case eStopReasonThreadExiting: {
386f85defaeSAndrew Kaylor             char limbo_desc[] = "thread exiting";
387f85defaeSAndrew Kaylor             stop_desc = limbo_desc;
388f85defaeSAndrew Kaylor             stop_desc_len = sizeof(limbo_desc);
389b9c1b51eSKate Stone           } break;
390c982c768SGreg Clayton           default:
391c982c768SGreg Clayton             break;
39230fdc8d8SChris Lattner           }
39330fdc8d8SChris Lattner 
394b9c1b51eSKate Stone           if (stop_desc && stop_desc[0]) {
395ceb6b139SCaroline Tice             if (log)
396b9c1b51eSKate Stone               log->Printf(
397b9c1b51eSKate Stone                   "SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
398b9c1b51eSKate Stone                   static_cast<void *>(exe_ctx.GetThreadPtr()), stop_desc);
399ceb6b139SCaroline Tice 
40030fdc8d8SChris Lattner             if (dst)
401b9c1b51eSKate Stone               return ::snprintf(dst, dst_len, "%s", stop_desc) +
402b9c1b51eSKate Stone                      1; // Include the NULL byte
40330fdc8d8SChris Lattner 
40430fdc8d8SChris Lattner             if (stop_desc_len == 0)
40530fdc8d8SChris Lattner               stop_desc_len = ::strlen(stop_desc) + 1; // Include the NULL byte
40630fdc8d8SChris Lattner 
40730fdc8d8SChris Lattner             return stop_desc_len;
40830fdc8d8SChris Lattner           }
40930fdc8d8SChris Lattner         }
41030fdc8d8SChris Lattner       }
411b9c1b51eSKate Stone     } else {
4125160ce5cSGreg Clayton       Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
413c9858e4dSGreg Clayton       if (log)
414b9c1b51eSKate Stone         log->Printf(
415b9c1b51eSKate Stone             "SBThread(%p)::GetStopDescription() => error: process is running",
416324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
417c9858e4dSGreg Clayton     }
4187fdf9ef1SGreg Clayton   }
41930fdc8d8SChris Lattner   if (dst)
42030fdc8d8SChris Lattner     *dst = 0;
42130fdc8d8SChris Lattner   return 0;
42230fdc8d8SChris Lattner }
42330fdc8d8SChris Lattner 
424b9c1b51eSKate Stone SBValue SBThread::GetStopReturnValue() {
4255160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
42673ca05a2SJim Ingham   ValueObjectSP return_valobj_sp;
427bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
428bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4294fc6cb9cSJim Ingham 
430b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4317fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
432b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4331ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
434b9c1b51eSKate Stone       if (stop_info_sp) {
43573ca05a2SJim Ingham         return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp);
43673ca05a2SJim Ingham       }
437b9c1b51eSKate Stone     } else {
438c9858e4dSGreg Clayton       if (log)
439b9c1b51eSKate Stone         log->Printf(
440b9c1b51eSKate Stone             "SBThread(%p)::GetStopReturnValue() => error: process is running",
441324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
442c9858e4dSGreg Clayton     }
4437fdf9ef1SGreg Clayton   }
44473ca05a2SJim Ingham 
44573ca05a2SJim Ingham   if (log)
446324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetStopReturnValue () => %s",
447324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
448b9c1b51eSKate Stone                 return_valobj_sp.get() ? return_valobj_sp->GetValueAsCString()
44973ca05a2SJim Ingham                                        : "<no return value>");
45073ca05a2SJim Ingham 
45173ca05a2SJim Ingham   return SBValue(return_valobj_sp);
45273ca05a2SJim Ingham }
45373ca05a2SJim Ingham 
454b9c1b51eSKate Stone void SBThread::SetThread(const ThreadSP &lldb_object_sp) {
4557fdf9ef1SGreg Clayton   m_opaque_sp->SetThreadSP(lldb_object_sp);
45630fdc8d8SChris Lattner }
45730fdc8d8SChris Lattner 
458b9c1b51eSKate Stone lldb::tid_t SBThread::GetThreadID() const {
4597fdf9ef1SGreg Clayton   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
46017a6ad05SGreg Clayton   if (thread_sp)
4611ac04c30SGreg Clayton     return thread_sp->GetID();
4621ac04c30SGreg Clayton   return LLDB_INVALID_THREAD_ID;
46330fdc8d8SChris Lattner }
46430fdc8d8SChris Lattner 
465b9c1b51eSKate Stone uint32_t SBThread::GetIndexID() const {
4667fdf9ef1SGreg Clayton   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
46717a6ad05SGreg Clayton   if (thread_sp)
46817a6ad05SGreg Clayton     return thread_sp->GetIndexID();
46930fdc8d8SChris Lattner   return LLDB_INVALID_INDEX32;
47030fdc8d8SChris Lattner }
4711ac04c30SGreg Clayton 
472b9c1b51eSKate Stone const char *SBThread::GetName() const {
4735160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
4744838131bSGreg Clayton   const char *name = NULL;
475bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
476bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4774fc6cb9cSJim Ingham 
478b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4797fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
480b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4811ac04c30SGreg Clayton       name = exe_ctx.GetThreadPtr()->GetName();
482b9c1b51eSKate Stone     } else {
483c9858e4dSGreg Clayton       if (log)
484324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::GetName() => error: process is running",
485324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
486c9858e4dSGreg Clayton     }
4877fdf9ef1SGreg Clayton   }
488ceb6b139SCaroline Tice 
489ceb6b139SCaroline Tice   if (log)
490324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetName () => %s",
491324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
492324a1036SSaleem Abdulrasool                 name ? name : "NULL");
493ceb6b139SCaroline Tice 
4944838131bSGreg Clayton   return name;
49530fdc8d8SChris Lattner }
49630fdc8d8SChris Lattner 
497b9c1b51eSKate Stone const char *SBThread::GetQueueName() const {
4984838131bSGreg Clayton   const char *name = NULL;
499bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
500bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
5014fc6cb9cSJim Ingham 
5025160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
503b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
5047fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
505b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
5061ac04c30SGreg Clayton       name = exe_ctx.GetThreadPtr()->GetQueueName();
507b9c1b51eSKate Stone     } else {
508c9858e4dSGreg Clayton       if (log)
509324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::GetQueueName() => error: process is running",
510324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
511c9858e4dSGreg Clayton     }
5127fdf9ef1SGreg Clayton   }
513ceb6b139SCaroline Tice 
514ceb6b139SCaroline Tice   if (log)
515324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetQueueName () => %s",
516324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
517324a1036SSaleem Abdulrasool                 name ? name : "NULL");
518ceb6b139SCaroline Tice 
5194838131bSGreg Clayton   return name;
52030fdc8d8SChris Lattner }
52130fdc8d8SChris Lattner 
522b9c1b51eSKate Stone lldb::queue_id_t SBThread::GetQueueID() const {
5234fdb5863SJason Molenda   queue_id_t id = LLDB_INVALID_QUEUE_ID;
524bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
525bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
5264fdb5863SJason Molenda 
5274fdb5863SJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
528b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
5294fdb5863SJason Molenda     Process::StopLocker stop_locker;
530b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
5314fdb5863SJason Molenda       id = exe_ctx.GetThreadPtr()->GetQueueID();
532b9c1b51eSKate Stone     } else {
5334fdb5863SJason Molenda       if (log)
534324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::GetQueueID() => error: process is running",
535324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
5364fdb5863SJason Molenda     }
5374fdb5863SJason Molenda   }
5384fdb5863SJason Molenda 
5394fdb5863SJason Molenda   if (log)
540324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetQueueID () => 0x%" PRIx64,
541324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), id);
5424fdb5863SJason Molenda 
5434fdb5863SJason Molenda   return id;
5444fdb5863SJason Molenda }
5454fdb5863SJason Molenda 
546b9c1b51eSKate Stone bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
547705b1809SJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
548705b1809SJason Molenda   bool success = false;
549bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
550bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
551705b1809SJason Molenda 
552b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
553705b1809SJason Molenda     Process::StopLocker stop_locker;
554b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
555705b1809SJason Molenda       Thread *thread = exe_ctx.GetThreadPtr();
556705b1809SJason Molenda       StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
557b9c1b51eSKate Stone       if (info_root_sp) {
558b9c1b51eSKate Stone         StructuredData::ObjectSP node =
559b9c1b51eSKate Stone             info_root_sp->GetObjectForDotSeparatedPath(path);
560b9c1b51eSKate Stone         if (node) {
5615bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeString) {
5622833321fSZachary Turner             strm.Printf("%s", node->GetAsString()->GetValue().str().c_str());
563705b1809SJason Molenda             success = true;
564705b1809SJason Molenda           }
5655bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeInteger) {
566705b1809SJason Molenda             strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue());
567705b1809SJason Molenda             success = true;
568705b1809SJason Molenda           }
5695bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeFloat) {
570705b1809SJason Molenda             strm.Printf("0x%f", node->GetAsFloat()->GetValue());
571705b1809SJason Molenda             success = true;
572705b1809SJason Molenda           }
5735bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeBoolean) {
574705b1809SJason Molenda             if (node->GetAsBoolean()->GetValue() == true)
575705b1809SJason Molenda               strm.Printf("true");
576705b1809SJason Molenda             else
577705b1809SJason Molenda               strm.Printf("false");
578705b1809SJason Molenda             success = true;
579705b1809SJason Molenda           }
5805bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeNull) {
581705b1809SJason Molenda             strm.Printf("null");
582705b1809SJason Molenda             success = true;
583705b1809SJason Molenda           }
584705b1809SJason Molenda         }
585705b1809SJason Molenda       }
586b9c1b51eSKate Stone     } else {
587705b1809SJason Molenda       if (log)
588b9c1b51eSKate Stone         log->Printf("SBThread(%p)::GetInfoItemByPathAsString() => error: "
589b9c1b51eSKate Stone                     "process is running",
590705b1809SJason Molenda                     static_cast<void *>(exe_ctx.GetThreadPtr()));
591705b1809SJason Molenda     }
592705b1809SJason Molenda   }
593705b1809SJason Molenda 
594705b1809SJason Molenda   if (log)
595753e13c0SJason Molenda     log->Printf("SBThread(%p)::GetInfoItemByPathAsString (\"%s\") => \"%s\"",
596753e13c0SJason Molenda                 static_cast<void *>(exe_ctx.GetThreadPtr()), path, strm.GetData());
597705b1809SJason Molenda 
598705b1809SJason Molenda   return success;
599705b1809SJason Molenda }
600705b1809SJason Molenda 
601b9c1b51eSKate Stone SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
602b9c1b51eSKate Stone                                 ThreadPlan *new_plan) {
60364e7ead1SJim Ingham   SBError sb_error;
60464e7ead1SJim Ingham 
60564e7ead1SJim Ingham   Process *process = exe_ctx.GetProcessPtr();
606b9c1b51eSKate Stone   if (!process) {
60764e7ead1SJim Ingham     sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
60864e7ead1SJim Ingham     return sb_error;
60964e7ead1SJim Ingham   }
61064e7ead1SJim Ingham 
61164e7ead1SJim Ingham   Thread *thread = exe_ctx.GetThreadPtr();
612b9c1b51eSKate Stone   if (!thread) {
61364e7ead1SJim Ingham     sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
61464e7ead1SJim Ingham     return sb_error;
61564e7ead1SJim Ingham   }
61664e7ead1SJim Ingham 
617b9c1b51eSKate Stone   // User level plans should be Master Plans so they can be interrupted, other
61805097246SAdrian Prantl   // plans executed, and then a "continue" will resume the plan.
619b9c1b51eSKate Stone   if (new_plan != NULL) {
62064e7ead1SJim Ingham     new_plan->SetIsMasterPlan(true);
62164e7ead1SJim Ingham     new_plan->SetOkayToDiscard(false);
62264e7ead1SJim Ingham   }
62364e7ead1SJim Ingham 
62464e7ead1SJim Ingham   // Why do we need to set the current thread by ID here???
62564e7ead1SJim Ingham   process->GetThreadList().SetSelectedThreadByID(thread->GetID());
62664e7ead1SJim Ingham 
627dc6224e0SGreg Clayton   if (process->GetTarget().GetDebugger().GetAsyncExecution())
628dc6224e0SGreg Clayton     sb_error.ref() = process->Resume();
629dc6224e0SGreg Clayton   else
630dc6224e0SGreg Clayton     sb_error.ref() = process->ResumeSynchronous(NULL);
63164e7ead1SJim Ingham 
63264e7ead1SJim Ingham   return sb_error;
63364e7ead1SJim Ingham }
63430fdc8d8SChris Lattner 
635b9c1b51eSKate Stone void SBThread::StepOver(lldb::RunMode stop_other_threads) {
636*859f54b3SAlexander Polyakov   SBError error; // Ignored
637*859f54b3SAlexander Polyakov   StepOver(stop_other_threads, error);
638*859f54b3SAlexander Polyakov }
639*859f54b3SAlexander Polyakov 
640*859f54b3SAlexander Polyakov void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
6415160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
642ceb6b139SCaroline Tice 
643bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
644bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
64517a6ad05SGreg Clayton 
646ceb6b139SCaroline Tice   if (log)
647324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::StepOver (stop_other_threads='%s')",
648324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
649ceb6b139SCaroline Tice                 Thread::RunModeAsCString(stop_other_threads));
650ceb6b139SCaroline Tice 
651*859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
652*859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
653*859f54b3SAlexander Polyakov     return;
654*859f54b3SAlexander Polyakov   }
655*859f54b3SAlexander Polyakov 
6561ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
6577ba6e991SJim Ingham   bool abort_other_plans = false;
658b57e4a1bSJason Molenda   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
65930fdc8d8SChris Lattner 
6604d56e9c1SJim Ingham   ThreadPlanSP new_plan_sp;
661b9c1b51eSKate Stone   if (frame_sp) {
662b9c1b51eSKate Stone     if (frame_sp->HasDebugInformation()) {
6634b4b2478SJim Ingham       const LazyBool avoid_no_debug = eLazyBoolCalculate;
66430fdc8d8SChris Lattner       SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
665b9c1b51eSKate Stone       new_plan_sp = thread->QueueThreadPlanForStepOverRange(
666b9c1b51eSKate Stone           abort_other_plans, sc.line_entry, sc, stop_other_threads,
6674b4b2478SJim Ingham           avoid_no_debug);
668b9c1b51eSKate Stone     } else {
669b9c1b51eSKate Stone       new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
670b9c1b51eSKate Stone           true, abort_other_plans, stop_other_threads);
67130fdc8d8SChris Lattner     }
67230fdc8d8SChris Lattner   }
673*859f54b3SAlexander Polyakov   error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
67430fdc8d8SChris Lattner }
67530fdc8d8SChris Lattner 
676b9c1b51eSKate Stone void SBThread::StepInto(lldb::RunMode stop_other_threads) {
677c627682eSJim Ingham   StepInto(NULL, stop_other_threads);
678c627682eSJim Ingham }
679c627682eSJim Ingham 
680b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name,
681b9c1b51eSKate Stone                         lldb::RunMode stop_other_threads) {
682*859f54b3SAlexander Polyakov   SBError error; // Ignored
683cbf6f9b2SJim Ingham   StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
684cbf6f9b2SJim Ingham }
685cbf6f9b2SJim Ingham 
686b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name, uint32_t end_line,
687b9c1b51eSKate Stone                         SBError &error, lldb::RunMode stop_other_threads) {
6885160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
689ceb6b139SCaroline Tice 
690bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
691bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
69217a6ad05SGreg Clayton 
69317a6ad05SGreg Clayton   if (log)
694b9c1b51eSKate Stone     log->Printf(
695b9c1b51eSKate Stone         "SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
696324a1036SSaleem Abdulrasool         static_cast<void *>(exe_ctx.GetThreadPtr()),
697c627682eSJim Ingham         target_name ? target_name : "<NULL>",
69817a6ad05SGreg Clayton         Thread::RunModeAsCString(stop_other_threads));
699c627682eSJim Ingham 
700*859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
701*859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
702*859f54b3SAlexander Polyakov     return;
703*859f54b3SAlexander Polyakov   }
704*859f54b3SAlexander Polyakov 
7057ba6e991SJim Ingham   bool abort_other_plans = false;
70630fdc8d8SChris Lattner 
7071ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
708b57e4a1bSJason Molenda   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
7094d56e9c1SJim Ingham   ThreadPlanSP new_plan_sp;
71030fdc8d8SChris Lattner 
711b9c1b51eSKate Stone   if (frame_sp && frame_sp->HasDebugInformation()) {
712cbf6f9b2SJim Ingham     SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
713cbf6f9b2SJim Ingham     AddressRange range;
714cbf6f9b2SJim Ingham     if (end_line == LLDB_INVALID_LINE_NUMBER)
715cbf6f9b2SJim Ingham       range = sc.line_entry.range;
716b9c1b51eSKate Stone     else {
717cbf6f9b2SJim Ingham       if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
718cbf6f9b2SJim Ingham         return;
719cbf6f9b2SJim Ingham     }
720cbf6f9b2SJim Ingham 
721b9c1b51eSKate Stone     const LazyBool step_out_avoids_code_without_debug_info =
722b9c1b51eSKate Stone         eLazyBoolCalculate;
723b9c1b51eSKate Stone     const LazyBool step_in_avoids_code_without_debug_info =
724b9c1b51eSKate Stone         eLazyBoolCalculate;
725b9c1b51eSKate Stone     new_plan_sp = thread->QueueThreadPlanForStepInRange(
726b9c1b51eSKate Stone         abort_other_plans, range, sc, target_name, stop_other_threads,
7274b4b2478SJim Ingham         step_in_avoids_code_without_debug_info,
7284b4b2478SJim Ingham         step_out_avoids_code_without_debug_info);
729b9c1b51eSKate Stone   } else {
730b9c1b51eSKate Stone     new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
731b9c1b51eSKate Stone         false, abort_other_plans, stop_other_threads);
73230fdc8d8SChris Lattner   }
733cbf6f9b2SJim Ingham   error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
73430fdc8d8SChris Lattner }
73530fdc8d8SChris Lattner 
736b9c1b51eSKate Stone void SBThread::StepOut() {
737*859f54b3SAlexander Polyakov   SBError error; // Ignored
738*859f54b3SAlexander Polyakov   StepOut(error);
739*859f54b3SAlexander Polyakov }
740*859f54b3SAlexander Polyakov 
741*859f54b3SAlexander Polyakov void SBThread::StepOut(SBError &error) {
7425160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
743ceb6b139SCaroline Tice 
744bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
745bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
7464fc6cb9cSJim Ingham 
74717a6ad05SGreg Clayton   if (log)
748324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::StepOut ()",
749324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()));
75017a6ad05SGreg Clayton 
751*859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
752*859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
753*859f54b3SAlexander Polyakov     return;
754*859f54b3SAlexander Polyakov   }
755*859f54b3SAlexander Polyakov 
7567ba6e991SJim Ingham   bool abort_other_plans = false;
75794b09246SJim Ingham   bool stop_other_threads = false;
75830fdc8d8SChris Lattner 
7591ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
7601ac04c30SGreg Clayton 
7614b4b2478SJim Ingham   const LazyBool avoid_no_debug = eLazyBoolCalculate;
762b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
763b9c1b51eSKate Stone       abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
764b9c1b51eSKate Stone       eVoteNoOpinion, 0, avoid_no_debug));
765481cef25SGreg Clayton 
766*859f54b3SAlexander Polyakov   error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
767481cef25SGreg Clayton }
768481cef25SGreg Clayton 
769*859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
770*859f54b3SAlexander Polyakov   SBError error; // Ignored
771*859f54b3SAlexander Polyakov   StepOutOfFrame(sb_frame, error);
772*859f54b3SAlexander Polyakov }
773*859f54b3SAlexander Polyakov 
774*859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
7755160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
776481cef25SGreg Clayton 
777bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
778bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
7794fc6cb9cSJim Ingham 
780b9c1b51eSKate Stone   if (!sb_frame.IsValid()) {
781989a7558SJim Ingham     if (log)
782b9c1b51eSKate Stone       log->Printf(
783b9c1b51eSKate Stone           "SBThread(%p)::StepOutOfFrame passed an invalid frame, returning.",
784989a7558SJim Ingham           static_cast<void *>(exe_ctx.GetThreadPtr()));
785*859f54b3SAlexander Polyakov     error.SetErrorString("passed invalid SBFrame object");
786989a7558SJim Ingham     return;
787989a7558SJim Ingham   }
788989a7558SJim Ingham 
789b57e4a1bSJason Molenda   StackFrameSP frame_sp(sb_frame.GetFrameSP());
790b9c1b51eSKate Stone   if (log) {
791481cef25SGreg Clayton     SBStream frame_desc_strm;
792481cef25SGreg Clayton     sb_frame.GetDescription(frame_desc_strm);
793324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)",
794324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
795b9c1b51eSKate Stone                 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
796481cef25SGreg Clayton   }
797481cef25SGreg Clayton 
798*859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
799*859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
800*859f54b3SAlexander Polyakov     return;
801*859f54b3SAlexander Polyakov   }
802*859f54b3SAlexander Polyakov 
8037ba6e991SJim Ingham   bool abort_other_plans = false;
80494b09246SJim Ingham   bool stop_other_threads = false;
8051ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
806b9c1b51eSKate Stone   if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
807b9c1b51eSKate Stone     log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another "
808b9c1b51eSKate Stone                 "thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.",
809989a7558SJim Ingham                 static_cast<void *>(exe_ctx.GetThreadPtr()),
810b9c1b51eSKate Stone                 sb_frame.GetThread().GetThreadID(), thread->GetID());
811*859f54b3SAlexander Polyakov     error.SetErrorString("passed a frame from another thread");
812*859f54b3SAlexander Polyakov     return;
813989a7558SJim Ingham   }
814481cef25SGreg Clayton 
815b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
816b9c1b51eSKate Stone       abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
817b9c1b51eSKate Stone       eVoteNoOpinion, frame_sp->GetFrameIndex()));
81830fdc8d8SChris Lattner 
819*859f54b3SAlexander Polyakov   error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
82030fdc8d8SChris Lattner }
82130fdc8d8SChris Lattner 
822b9c1b51eSKate Stone void SBThread::StepInstruction(bool step_over) {
823*859f54b3SAlexander Polyakov   SBError error; // Ignored
824*859f54b3SAlexander Polyakov   StepInstruction(step_over, error);
825*859f54b3SAlexander Polyakov }
826*859f54b3SAlexander Polyakov 
827*859f54b3SAlexander Polyakov void SBThread::StepInstruction(bool step_over, SBError &error) {
8285160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
829ceb6b139SCaroline Tice 
830bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
831bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
832ceb6b139SCaroline Tice 
83317a6ad05SGreg Clayton   if (log)
834324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::StepInstruction (step_over=%i)",
835324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), step_over);
83617a6ad05SGreg Clayton 
837*859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
838*859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
839*859f54b3SAlexander Polyakov     return;
840*859f54b3SAlexander Polyakov   }
841*859f54b3SAlexander Polyakov 
8421ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
843b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(
844b9c1b51eSKate Stone       thread->QueueThreadPlanForStepSingleInstruction(step_over, true, true));
84564e7ead1SJim Ingham 
846*859f54b3SAlexander Polyakov   error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
84730fdc8d8SChris Lattner }
84830fdc8d8SChris Lattner 
849b9c1b51eSKate Stone void SBThread::RunToAddress(lldb::addr_t addr) {
850*859f54b3SAlexander Polyakov   SBError error; // Ignored
851*859f54b3SAlexander Polyakov   RunToAddress(addr, error);
852*859f54b3SAlexander Polyakov }
853*859f54b3SAlexander Polyakov 
854*859f54b3SAlexander Polyakov void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
8555160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
856ceb6b139SCaroline Tice 
857bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
858bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
859ceb6b139SCaroline Tice 
86017a6ad05SGreg Clayton   if (log)
861324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")",
862324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), addr);
86317a6ad05SGreg Clayton 
864*859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
865*859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
866*859f54b3SAlexander Polyakov     return;
867*859f54b3SAlexander Polyakov   }
868*859f54b3SAlexander Polyakov 
8697ba6e991SJim Ingham   bool abort_other_plans = false;
87030fdc8d8SChris Lattner   bool stop_other_threads = true;
87130fdc8d8SChris Lattner 
872e72dfb32SGreg Clayton   Address target_addr(addr);
87330fdc8d8SChris Lattner 
8741ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
8751ac04c30SGreg Clayton 
876b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
877b9c1b51eSKate Stone       abort_other_plans, target_addr, stop_other_threads));
87864e7ead1SJim Ingham 
879*859f54b3SAlexander Polyakov   error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
88030fdc8d8SChris Lattner }
88130fdc8d8SChris Lattner 
882b9c1b51eSKate Stone SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
883b9c1b51eSKate Stone                                 lldb::SBFileSpec &sb_file_spec, uint32_t line) {
884481cef25SGreg Clayton   SBError sb_error;
8855160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
886481cef25SGreg Clayton   char path[PATH_MAX];
887481cef25SGreg Clayton 
888bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
889bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
8904fc6cb9cSJim Ingham 
891b57e4a1bSJason Molenda   StackFrameSP frame_sp(sb_frame.GetFrameSP());
89217a6ad05SGreg Clayton 
893b9c1b51eSKate Stone   if (log) {
894481cef25SGreg Clayton     SBStream frame_desc_strm;
895481cef25SGreg Clayton     sb_frame.GetDescription(frame_desc_strm);
896481cef25SGreg Clayton     sb_file_spec->GetPath(path, sizeof(path));
897b9c1b51eSKate Stone     log->Printf("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, "
898b9c1b51eSKate Stone                 "file+line = %s:%u)",
899324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
900b9c1b51eSKate Stone                 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData(),
901b9c1b51eSKate Stone                 path, line);
902481cef25SGreg Clayton   }
903481cef25SGreg Clayton 
904b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
9051ac04c30SGreg Clayton     Target *target = exe_ctx.GetTargetPtr();
9061ac04c30SGreg Clayton     Thread *thread = exe_ctx.GetThreadPtr();
907481cef25SGreg Clayton 
908b9c1b51eSKate Stone     if (line == 0) {
909481cef25SGreg Clayton       sb_error.SetErrorString("invalid line argument");
910481cef25SGreg Clayton       return sb_error;
911481cef25SGreg Clayton     }
912481cef25SGreg Clayton 
913b9c1b51eSKate Stone     if (!frame_sp) {
9141ac04c30SGreg Clayton       frame_sp = thread->GetSelectedFrame();
915481cef25SGreg Clayton       if (!frame_sp)
9161ac04c30SGreg Clayton         frame_sp = thread->GetStackFrameAtIndex(0);
917481cef25SGreg Clayton     }
918481cef25SGreg Clayton 
919481cef25SGreg Clayton     SymbolContext frame_sc;
920b9c1b51eSKate Stone     if (!frame_sp) {
921481cef25SGreg Clayton       sb_error.SetErrorString("no valid frames in thread to step");
922481cef25SGreg Clayton       return sb_error;
923481cef25SGreg Clayton     }
924481cef25SGreg Clayton 
925481cef25SGreg Clayton     // If we have a frame, get its line
926b9c1b51eSKate Stone     frame_sc = frame_sp->GetSymbolContext(
927b9c1b51eSKate Stone         eSymbolContextCompUnit | eSymbolContextFunction |
928b9c1b51eSKate Stone         eSymbolContextLineEntry | eSymbolContextSymbol);
929481cef25SGreg Clayton 
930b9c1b51eSKate Stone     if (frame_sc.comp_unit == NULL) {
931b9c1b51eSKate Stone       sb_error.SetErrorStringWithFormat(
932b9c1b51eSKate Stone           "frame %u doesn't have debug information", frame_sp->GetFrameIndex());
933481cef25SGreg Clayton       return sb_error;
934481cef25SGreg Clayton     }
935481cef25SGreg Clayton 
936481cef25SGreg Clayton     FileSpec step_file_spec;
937b9c1b51eSKate Stone     if (sb_file_spec.IsValid()) {
938481cef25SGreg Clayton       // The file spec passed in was valid, so use it
939481cef25SGreg Clayton       step_file_spec = sb_file_spec.ref();
940b9c1b51eSKate Stone     } else {
941481cef25SGreg Clayton       if (frame_sc.line_entry.IsValid())
942481cef25SGreg Clayton         step_file_spec = frame_sc.line_entry.file;
943b9c1b51eSKate Stone       else {
944481cef25SGreg Clayton         sb_error.SetErrorString("invalid file argument or no file for frame");
945481cef25SGreg Clayton         return sb_error;
946481cef25SGreg Clayton       }
947481cef25SGreg Clayton     }
948481cef25SGreg Clayton 
9499b70ddb3SJim Ingham     // Grab the current function, then we will make sure the "until" address is
9509b70ddb3SJim Ingham     // within the function.  We discard addresses that are out of the current
951b9c1b51eSKate Stone     // function, and then if there are no addresses remaining, give an
95205097246SAdrian Prantl     // appropriate error message.
9539b70ddb3SJim Ingham 
9549b70ddb3SJim Ingham     bool all_in_function = true;
9559b70ddb3SJim Ingham     AddressRange fun_range = frame_sc.function->GetAddressRange();
9569b70ddb3SJim Ingham 
957481cef25SGreg Clayton     std::vector<addr_t> step_over_until_addrs;
9587ba6e991SJim Ingham     const bool abort_other_plans = false;
959c02e3344SJim Ingham     const bool stop_other_threads = false;
960481cef25SGreg Clayton     const bool check_inlines = true;
961481cef25SGreg Clayton     const bool exact = false;
962481cef25SGreg Clayton 
963481cef25SGreg Clayton     SymbolContextList sc_list;
964b9c1b51eSKate Stone     const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext(
965b9c1b51eSKate Stone         step_file_spec, line, check_inlines, exact, eSymbolContextLineEntry,
9669b70ddb3SJim Ingham         sc_list);
967b9c1b51eSKate Stone     if (num_matches > 0) {
968481cef25SGreg Clayton       SymbolContext sc;
969b9c1b51eSKate Stone       for (uint32_t i = 0; i < num_matches; ++i) {
970b9c1b51eSKate Stone         if (sc_list.GetContextAtIndex(i, sc)) {
971b9c1b51eSKate Stone           addr_t step_addr =
972b9c1b51eSKate Stone               sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
973b9c1b51eSKate Stone           if (step_addr != LLDB_INVALID_ADDRESS) {
9749b70ddb3SJim Ingham             if (fun_range.ContainsLoadAddress(step_addr, target))
975481cef25SGreg Clayton               step_over_until_addrs.push_back(step_addr);
9769b70ddb3SJim Ingham             else
9779b70ddb3SJim Ingham               all_in_function = false;
978481cef25SGreg Clayton           }
979481cef25SGreg Clayton         }
980481cef25SGreg Clayton       }
981481cef25SGreg Clayton     }
982481cef25SGreg Clayton 
983b9c1b51eSKate Stone     if (step_over_until_addrs.empty()) {
984b9c1b51eSKate Stone       if (all_in_function) {
985481cef25SGreg Clayton         step_file_spec.GetPath(path, sizeof(path));
986b9c1b51eSKate Stone         sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path,
987b9c1b51eSKate Stone                                           line);
988b9c1b51eSKate Stone       } else
98986edbf41SGreg Clayton         sb_error.SetErrorString("step until target not in current function");
990b9c1b51eSKate Stone     } else {
991b9c1b51eSKate Stone       ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil(
992b9c1b51eSKate Stone           abort_other_plans, &step_over_until_addrs[0],
993b9c1b51eSKate Stone           step_over_until_addrs.size(), stop_other_threads,
9944d56e9c1SJim Ingham           frame_sp->GetFrameIndex()));
995481cef25SGreg Clayton 
9964d56e9c1SJim Ingham       sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
997481cef25SGreg Clayton     }
998b9c1b51eSKate Stone   } else {
999481cef25SGreg Clayton     sb_error.SetErrorString("this SBThread object is invalid");
1000481cef25SGreg Clayton   }
1001481cef25SGreg Clayton   return sb_error;
1002481cef25SGreg Clayton }
1003481cef25SGreg Clayton 
1004b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) {
1005000ca185SOleksiy Vyalov   return StepUsingScriptedThreadPlan(script_class_name, true);
1006c915a7d2SJim Ingham }
1007c915a7d2SJim Ingham 
1008b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
1009b9c1b51eSKate Stone                                               bool resume_immediately) {
10102bdbfd50SJim Ingham   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
10112bdbfd50SJim Ingham   SBError sb_error;
10122bdbfd50SJim Ingham 
1013bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1014bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
10152bdbfd50SJim Ingham 
1016b9c1b51eSKate Stone   if (log) {
10172bdbfd50SJim Ingham     log->Printf("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s",
1018b9c1b51eSKate Stone                 static_cast<void *>(exe_ctx.GetThreadPtr()), script_class_name);
10192bdbfd50SJim Ingham   }
10202bdbfd50SJim Ingham 
1021b9c1b51eSKate Stone   if (!exe_ctx.HasThreadScope()) {
10222bdbfd50SJim Ingham     sb_error.SetErrorString("this SBThread object is invalid");
10232bdbfd50SJim Ingham     return sb_error;
10242bdbfd50SJim Ingham   }
10252bdbfd50SJim Ingham 
10262bdbfd50SJim Ingham   Thread *thread = exe_ctx.GetThreadPtr();
1027b9c1b51eSKate Stone   ThreadPlanSP thread_plan_sp =
1028b9c1b51eSKate Stone       thread->QueueThreadPlanForStepScripted(false, script_class_name, false);
10292bdbfd50SJim Ingham 
1030b9c1b51eSKate Stone   if (!thread_plan_sp) {
1031b9c1b51eSKate Stone     sb_error.SetErrorStringWithFormat(
1032b9c1b51eSKate Stone         "Error queueing thread plan for class: %s", script_class_name);
1033c915a7d2SJim Ingham     return sb_error;
1034c915a7d2SJim Ingham   }
1035c915a7d2SJim Ingham 
1036b9c1b51eSKate Stone   if (!resume_immediately) {
1037c915a7d2SJim Ingham     return sb_error;
1038c915a7d2SJim Ingham   }
1039c915a7d2SJim Ingham 
10402bdbfd50SJim Ingham   if (thread_plan_sp)
10412bdbfd50SJim Ingham     sb_error = ResumeNewPlan(exe_ctx, thread_plan_sp.get());
1042b9c1b51eSKate Stone   else {
1043b9c1b51eSKate Stone     sb_error.SetErrorStringWithFormat(
1044b9c1b51eSKate Stone         "Error resuming thread plan for class: %s.", script_class_name);
10452bdbfd50SJim Ingham     if (log)
1046b9c1b51eSKate Stone       log->Printf("SBThread(%p)::StepUsingScriptedThreadPlan: Error queuing "
1047b9c1b51eSKate Stone                   "thread plan for class: %s",
10482bdbfd50SJim Ingham                   static_cast<void *>(exe_ctx.GetThreadPtr()),
10492bdbfd50SJim Ingham                   script_class_name);
10502bdbfd50SJim Ingham   }
10512bdbfd50SJim Ingham 
10522bdbfd50SJim Ingham   return sb_error;
10532bdbfd50SJim Ingham }
10542bdbfd50SJim Ingham 
1055b9c1b51eSKate Stone SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
1056f86248d9SRichard Mitton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1057f86248d9SRichard Mitton   SBError sb_error;
1058f86248d9SRichard Mitton 
1059bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1060bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1061f86248d9SRichard Mitton 
1062f86248d9SRichard Mitton   if (log)
1063324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::JumpToLine (file+line = %s:%u)",
1064324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
1065324a1036SSaleem Abdulrasool                 file_spec->GetPath().c_str(), line);
1066f86248d9SRichard Mitton 
1067b9c1b51eSKate Stone   if (!exe_ctx.HasThreadScope()) {
1068f86248d9SRichard Mitton     sb_error.SetErrorString("this SBThread object is invalid");
1069f86248d9SRichard Mitton     return sb_error;
1070f86248d9SRichard Mitton   }
1071f86248d9SRichard Mitton 
1072f86248d9SRichard Mitton   Thread *thread = exe_ctx.GetThreadPtr();
1073f86248d9SRichard Mitton 
107497206d57SZachary Turner   Status err = thread->JumpToLine(file_spec.get(), line, true);
1075f86248d9SRichard Mitton   sb_error.SetError(err);
1076f86248d9SRichard Mitton   return sb_error;
1077f86248d9SRichard Mitton }
1078f86248d9SRichard Mitton 
1079b9c1b51eSKate Stone SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
10804413758cSJim Ingham   SBError sb_error;
10814413758cSJim Ingham 
10825160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
10834413758cSJim Ingham 
1084bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1085bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
10864413758cSJim Ingham 
10874413758cSJim Ingham   if (log)
1088324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::ReturnFromFrame (frame=%d)",
1089324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
1090324a1036SSaleem Abdulrasool                 frame.GetFrameID());
10914413758cSJim Ingham 
1092b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
10934413758cSJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
1094b9c1b51eSKate Stone     sb_error.SetError(
1095b9c1b51eSKate Stone         thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
10964413758cSJim Ingham   }
10974413758cSJim Ingham 
10984413758cSJim Ingham   return sb_error;
10994413758cSJim Ingham }
11004413758cSJim Ingham 
1101b9c1b51eSKate Stone SBError SBThread::UnwindInnermostExpression() {
11024ac8e93aSJim Ingham   SBError sb_error;
11034ac8e93aSJim Ingham 
11044ac8e93aSJim Ingham   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
11054ac8e93aSJim Ingham 
11064ac8e93aSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
11074ac8e93aSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11084ac8e93aSJim Ingham 
11094ac8e93aSJim Ingham   if (log)
11104ac8e93aSJim Ingham     log->Printf("SBThread(%p)::UnwindExpressionEvaluation",
11114ac8e93aSJim Ingham                 static_cast<void *>(exe_ctx.GetThreadPtr()));
11124ac8e93aSJim Ingham 
1113b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11144ac8e93aSJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
11154ac8e93aSJim Ingham     sb_error.SetError(thread->UnwindInnermostExpression());
11164ac8e93aSJim Ingham     if (sb_error.Success())
11174ac8e93aSJim Ingham       thread->SetSelectedFrameByIndex(0, false);
11184ac8e93aSJim Ingham   }
11194ac8e93aSJim Ingham 
11204ac8e93aSJim Ingham   return sb_error;
11214ac8e93aSJim Ingham }
1122481cef25SGreg Clayton 
1123b9c1b51eSKate Stone bool SBThread::Suspend() {
1124*859f54b3SAlexander Polyakov   SBError error; // Ignored
1125*859f54b3SAlexander Polyakov   return Suspend(error);
1126*859f54b3SAlexander Polyakov }
1127*859f54b3SAlexander Polyakov 
1128*859f54b3SAlexander Polyakov bool SBThread::Suspend(SBError &error) {
11295160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1130b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1131b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1132b2e7d28eSJim Ingham 
1133c9858e4dSGreg Clayton   bool result = false;
1134b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1135c9858e4dSGreg Clayton     Process::StopLocker stop_locker;
1136b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11371ac04c30SGreg Clayton       exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
1138c9858e4dSGreg Clayton       result = true;
1139b9c1b51eSKate Stone     } else {
1140*859f54b3SAlexander Polyakov       error.SetErrorString("process is running");
1141c9858e4dSGreg Clayton       if (log)
1142324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::Suspend() => error: process is running",
1143324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
1144c9858e4dSGreg Clayton     }
1145*859f54b3SAlexander Polyakov   } else
1146*859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
1147c9858e4dSGreg Clayton   if (log)
1148324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::Suspend() => %i",
1149324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), result);
1150c9858e4dSGreg Clayton   return result;
1151722a0cdcSGreg Clayton }
1152722a0cdcSGreg Clayton 
1153b9c1b51eSKate Stone bool SBThread::Resume() {
1154*859f54b3SAlexander Polyakov   SBError error; // Ignored
1155*859f54b3SAlexander Polyakov   return Resume(error);
1156*859f54b3SAlexander Polyakov }
1157*859f54b3SAlexander Polyakov 
1158*859f54b3SAlexander Polyakov bool SBThread::Resume(SBError &error) {
11595160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1160b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1161b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1162b2e7d28eSJim Ingham 
1163c9858e4dSGreg Clayton   bool result = false;
1164b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1165c9858e4dSGreg Clayton     Process::StopLocker stop_locker;
1166b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11676c9ed91cSJim Ingham       const bool override_suspend = true;
11686c9ed91cSJim Ingham       exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
1169c9858e4dSGreg Clayton       result = true;
1170b9c1b51eSKate Stone     } else {
1171*859f54b3SAlexander Polyakov       error.SetErrorString("process is running");
1172c9858e4dSGreg Clayton       if (log)
1173324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::Resume() => error: process is running",
1174324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
1175c9858e4dSGreg Clayton     }
1176*859f54b3SAlexander Polyakov   } else
1177*859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
1178c9858e4dSGreg Clayton   if (log)
1179324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::Resume() => %i",
1180324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), result);
1181c9858e4dSGreg Clayton   return result;
1182722a0cdcSGreg Clayton }
1183722a0cdcSGreg Clayton 
1184b9c1b51eSKate Stone bool SBThread::IsSuspended() {
1185b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1186b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1187b2e7d28eSJim Ingham 
11881ac04c30SGreg Clayton   if (exe_ctx.HasThreadScope())
11891ac04c30SGreg Clayton     return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
1190722a0cdcSGreg Clayton   return false;
1191722a0cdcSGreg Clayton }
1192722a0cdcSGreg Clayton 
1193b9c1b51eSKate Stone bool SBThread::IsStopped() {
1194b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1195b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1196b2e7d28eSJim Ingham 
1197a75418dbSAndrew Kaylor   if (exe_ctx.HasThreadScope())
1198a75418dbSAndrew Kaylor     return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1199a75418dbSAndrew Kaylor   return false;
1200a75418dbSAndrew Kaylor }
1201a75418dbSAndrew Kaylor 
1202b9c1b51eSKate Stone SBProcess SBThread::GetProcess() {
1203b9556accSGreg Clayton   SBProcess sb_process;
1204b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1205b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1206b2e7d28eSJim Ingham 
1207b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1208b9c1b51eSKate Stone     // Have to go up to the target so we can get a shared pointer to our
1209b9c1b51eSKate Stone     // process...
12101ac04c30SGreg Clayton     sb_process.SetSP(exe_ctx.GetProcessSP());
121130fdc8d8SChris Lattner   }
1212ceb6b139SCaroline Tice 
12135160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1214b9c1b51eSKate Stone   if (log) {
1215481cef25SGreg Clayton     SBStream frame_desc_strm;
1216b9556accSGreg Clayton     sb_process.GetDescription(frame_desc_strm);
1217324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetProcess () => SBProcess(%p): %s",
1218324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
1219324a1036SSaleem Abdulrasool                 static_cast<void *>(sb_process.GetSP().get()),
1220324a1036SSaleem Abdulrasool                 frame_desc_strm.GetData());
1221ceb6b139SCaroline Tice   }
1222ceb6b139SCaroline Tice 
1223b9556accSGreg Clayton   return sb_process;
122430fdc8d8SChris Lattner }
122530fdc8d8SChris Lattner 
1226b9c1b51eSKate Stone uint32_t SBThread::GetNumFrames() {
12275160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1228ceb6b139SCaroline Tice 
1229ceb6b139SCaroline Tice   uint32_t num_frames = 0;
1230bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1231bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12324fc6cb9cSJim Ingham 
1233b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
12347fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1235b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
12361ac04c30SGreg Clayton       num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1237b9c1b51eSKate Stone     } else {
1238c9858e4dSGreg Clayton       if (log)
1239324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::GetNumFrames() => error: process is running",
1240324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
1241c9858e4dSGreg Clayton     }
12427fdf9ef1SGreg Clayton   }
1243ceb6b139SCaroline Tice 
1244ceb6b139SCaroline Tice   if (log)
1245324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetNumFrames () => %u",
1246324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), num_frames);
1247ceb6b139SCaroline Tice 
1248ceb6b139SCaroline Tice   return num_frames;
124930fdc8d8SChris Lattner }
125030fdc8d8SChris Lattner 
1251b9c1b51eSKate Stone SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
12525160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1253ceb6b139SCaroline Tice 
125430fdc8d8SChris Lattner   SBFrame sb_frame;
1255b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1256bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1257bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12584fc6cb9cSJim Ingham 
1259b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
12607fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1261b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
12621ac04c30SGreg Clayton       frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
1263b9556accSGreg Clayton       sb_frame.SetFrameSP(frame_sp);
1264b9c1b51eSKate Stone     } else {
1265c9858e4dSGreg Clayton       if (log)
1266b9c1b51eSKate Stone         log->Printf(
1267b9c1b51eSKate Stone             "SBThread(%p)::GetFrameAtIndex() => error: process is running",
1268324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
1269c9858e4dSGreg Clayton     }
12707fdf9ef1SGreg Clayton   }
1271ceb6b139SCaroline Tice 
1272b9c1b51eSKate Stone   if (log) {
1273481cef25SGreg Clayton     SBStream frame_desc_strm;
1274481cef25SGreg Clayton     sb_frame.GetDescription(frame_desc_strm);
12754838131bSGreg Clayton     log->Printf("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
1276324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), idx,
1277b9c1b51eSKate Stone                 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1278ceb6b139SCaroline Tice   }
1279ceb6b139SCaroline Tice 
128030fdc8d8SChris Lattner   return sb_frame;
128130fdc8d8SChris Lattner }
128230fdc8d8SChris Lattner 
1283b9c1b51eSKate Stone lldb::SBFrame SBThread::GetSelectedFrame() {
12845160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1285f028a1fbSGreg Clayton 
1286f028a1fbSGreg Clayton   SBFrame sb_frame;
1287b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1288bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1289bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12904fc6cb9cSJim Ingham 
1291b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
12927fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1293b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
12941ac04c30SGreg Clayton       frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame();
1295b9556accSGreg Clayton       sb_frame.SetFrameSP(frame_sp);
1296b9c1b51eSKate Stone     } else {
1297c9858e4dSGreg Clayton       if (log)
1298b9c1b51eSKate Stone         log->Printf(
1299b9c1b51eSKate Stone             "SBThread(%p)::GetSelectedFrame() => error: process is running",
1300324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
1301c9858e4dSGreg Clayton     }
13027fdf9ef1SGreg Clayton   }
1303f028a1fbSGreg Clayton 
1304b9c1b51eSKate Stone   if (log) {
1305481cef25SGreg Clayton     SBStream frame_desc_strm;
1306481cef25SGreg Clayton     sb_frame.GetDescription(frame_desc_strm);
1307f028a1fbSGreg Clayton     log->Printf("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
1308324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
1309b9c1b51eSKate Stone                 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1310f028a1fbSGreg Clayton   }
1311f028a1fbSGreg Clayton 
1312f028a1fbSGreg Clayton   return sb_frame;
1313f028a1fbSGreg Clayton }
1314f028a1fbSGreg Clayton 
1315b9c1b51eSKate Stone lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
13165160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1317f028a1fbSGreg Clayton 
1318f028a1fbSGreg Clayton   SBFrame sb_frame;
1319b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1320bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1321bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
13224fc6cb9cSJim Ingham 
1323b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
13247fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1325b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
13261ac04c30SGreg Clayton       Thread *thread = exe_ctx.GetThreadPtr();
13271ac04c30SGreg Clayton       frame_sp = thread->GetStackFrameAtIndex(idx);
1328b9c1b51eSKate Stone       if (frame_sp) {
13291ac04c30SGreg Clayton         thread->SetSelectedFrame(frame_sp.get());
1330b9556accSGreg Clayton         sb_frame.SetFrameSP(frame_sp);
1331f028a1fbSGreg Clayton       }
1332b9c1b51eSKate Stone     } else {
1333c9858e4dSGreg Clayton       if (log)
1334b9c1b51eSKate Stone         log->Printf(
1335b9c1b51eSKate Stone             "SBThread(%p)::SetSelectedFrame() => error: process is running",
1336324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
1337c9858e4dSGreg Clayton     }
13387fdf9ef1SGreg Clayton   }
1339f028a1fbSGreg Clayton 
1340b9c1b51eSKate Stone   if (log) {
1341481cef25SGreg Clayton     SBStream frame_desc_strm;
1342481cef25SGreg Clayton     sb_frame.GetDescription(frame_desc_strm);
1343f028a1fbSGreg Clayton     log->Printf("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
1344324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), idx,
1345b9c1b51eSKate Stone                 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1346f028a1fbSGreg Clayton   }
1347f028a1fbSGreg Clayton   return sb_frame;
1348f028a1fbSGreg Clayton }
1349f028a1fbSGreg Clayton 
1350b9c1b51eSKate Stone bool SBThread::EventIsThreadEvent(const SBEvent &event) {
13514f465cffSJim Ingham   return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
13524f465cffSJim Ingham }
13534f465cffSJim Ingham 
1354b9c1b51eSKate Stone SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) {
13554f465cffSJim Ingham   return Thread::ThreadEventData::GetStackFrameFromEvent(event.get());
13564f465cffSJim Ingham }
13574f465cffSJim Ingham 
1358b9c1b51eSKate Stone SBThread SBThread::GetThreadFromEvent(const SBEvent &event) {
13594f465cffSJim Ingham   return Thread::ThreadEventData::GetThreadFromEvent(event.get());
13604f465cffSJim Ingham }
1361f028a1fbSGreg Clayton 
1362b9c1b51eSKate Stone bool SBThread::operator==(const SBThread &rhs) const {
1363b9c1b51eSKate Stone   return m_opaque_sp->GetThreadSP().get() ==
1364b9c1b51eSKate Stone          rhs.m_opaque_sp->GetThreadSP().get();
136530fdc8d8SChris Lattner }
136630fdc8d8SChris Lattner 
1367b9c1b51eSKate Stone bool SBThread::operator!=(const SBThread &rhs) const {
1368b9c1b51eSKate Stone   return m_opaque_sp->GetThreadSP().get() !=
1369b9c1b51eSKate Stone          rhs.m_opaque_sp->GetThreadSP().get();
137030fdc8d8SChris Lattner }
1371dde9cff3SCaroline Tice 
1372b9c1b51eSKate Stone bool SBThread::GetStatus(SBStream &status) const {
13734f465cffSJim Ingham   Stream &strm = status.ref();
13744f465cffSJim Ingham 
1375b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1376b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1377b2e7d28eSJim Ingham 
1378b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
13796a9767c7SJim Ingham     exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true);
1380b9c1b51eSKate Stone   } else
13814f465cffSJim Ingham     strm.PutCString("No status");
13824f465cffSJim Ingham 
13834f465cffSJim Ingham   return true;
13844f465cffSJim Ingham }
13854f465cffSJim Ingham 
1386b9c1b51eSKate Stone bool SBThread::GetDescription(SBStream &description) const {
13876a9767c7SJim Ingham     return GetDescription(description, false);
13886a9767c7SJim Ingham }
13896a9767c7SJim Ingham 
13906a9767c7SJim Ingham bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
1391da7bc7d0SGreg Clayton   Stream &strm = description.ref();
1392da7bc7d0SGreg Clayton 
1393b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1394b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1395b2e7d28eSJim Ingham 
1396b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1397b9c1b51eSKate Stone     exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm,
13986a9767c7SJim Ingham                                                     LLDB_INVALID_THREAD_ID,
13996a9767c7SJim Ingham                                                     stop_format);
1400b9c1b51eSKate Stone     // strm.Printf("SBThread: tid = 0x%4.4" PRIx64,
1401b9c1b51eSKate Stone     // exe_ctx.GetThreadPtr()->GetID());
1402b9c1b51eSKate Stone   } else
1403da7bc7d0SGreg Clayton     strm.PutCString("No value");
1404ceb6b139SCaroline Tice 
1405ceb6b139SCaroline Tice   return true;
1406ceb6b139SCaroline Tice }
14075dd4916fSJason Molenda 
1408b9c1b51eSKate Stone SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
14095dd4916fSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1410bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1411bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
14125dd4916fSJason Molenda   SBThread sb_origin_thread;
14135dd4916fSJason Molenda 
1414b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
14155dd4916fSJason Molenda     Process::StopLocker stop_locker;
1416b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
14177a2f7904SJason Molenda       ThreadSP real_thread(exe_ctx.GetThreadSP());
1418b9c1b51eSKate Stone       if (real_thread) {
14195dd4916fSJason Molenda         ConstString type_const(type);
14207a2f7904SJason Molenda         Process *process = exe_ctx.GetProcessPtr();
1421b9c1b51eSKate Stone         if (process) {
14227a2f7904SJason Molenda           SystemRuntime *runtime = process->GetSystemRuntime();
1423b9c1b51eSKate Stone           if (runtime) {
1424b9c1b51eSKate Stone             ThreadSP new_thread_sp(
1425b9c1b51eSKate Stone                 runtime->GetExtendedBacktraceThread(real_thread, type_const));
1426b9c1b51eSKate Stone             if (new_thread_sp) {
1427b9c1b51eSKate Stone               // Save this in the Process' ExtendedThreadList so a strong
142805097246SAdrian Prantl               // pointer retains the object.
14297a2f7904SJason Molenda               process->GetExtendedThreadList().AddThread(new_thread_sp);
14307a2f7904SJason Molenda               sb_origin_thread.SetThread(new_thread_sp);
1431b9c1b51eSKate Stone               if (log) {
1432a6e9130dSJason Molenda                 const char *queue_name = new_thread_sp->GetQueueName();
1433a6e9130dSJason Molenda                 if (queue_name == NULL)
1434a6e9130dSJason Molenda                   queue_name = "";
1435b9c1b51eSKate Stone                 log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => new "
1436b9c1b51eSKate Stone                             "extended Thread "
1437b9c1b51eSKate Stone                             "created (%p) with queue_id 0x%" PRIx64
1438b9c1b51eSKate Stone                             " queue name '%s'",
1439324a1036SSaleem Abdulrasool                             static_cast<void *>(exe_ctx.GetThreadPtr()),
1440324a1036SSaleem Abdulrasool                             static_cast<void *>(new_thread_sp.get()),
1441b9c1b51eSKate Stone                             new_thread_sp->GetQueueID(), queue_name);
1442a6e9130dSJason Molenda               }
1443a6e9130dSJason Molenda             }
14447a2f7904SJason Molenda           }
14455dd4916fSJason Molenda         }
14465dd4916fSJason Molenda       }
1447b9c1b51eSKate Stone     } else {
14485dd4916fSJason Molenda       if (log)
1449b9c1b51eSKate Stone         log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => error: "
1450b9c1b51eSKate Stone                     "process is running",
1451324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
14525dd4916fSJason Molenda     }
14535dd4916fSJason Molenda   }
14545dd4916fSJason Molenda 
1455ac605f4aSJason Molenda   if (log && sb_origin_thread.IsValid() == false)
1456b9c1b51eSKate Stone     log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a "
1457b9c1b51eSKate Stone                 "Valid thread",
1458324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()));
14595dd4916fSJason Molenda   return sb_origin_thread;
14605dd4916fSJason Molenda }
14618ee9cb58SJason Molenda 
1462b9c1b51eSKate Stone uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
14638ee9cb58SJason Molenda   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
14648ee9cb58SJason Molenda   if (thread_sp)
14658ee9cb58SJason Molenda     return thread_sp->GetExtendedBacktraceOriginatingIndexID();
14668ee9cb58SJason Molenda   return LLDB_INVALID_INDEX32;
14678ee9cb58SJason Molenda }
1468b4892cd2SJason Molenda 
1469b9c1b51eSKate Stone bool SBThread::SafeToCallFunctions() {
1470b4892cd2SJason Molenda   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1471b4892cd2SJason Molenda   if (thread_sp)
1472b4892cd2SJason Molenda     return thread_sp->SafeToCallFunctions();
1473b4892cd2SJason Molenda   return true;
1474b4892cd2SJason Molenda }
14752bdbfd50SJim Ingham 
1476b9c1b51eSKate Stone lldb_private::Thread *SBThread::operator->() {
14772bdbfd50SJim Ingham   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
14782bdbfd50SJim Ingham   if (thread_sp)
14792bdbfd50SJim Ingham     return thread_sp.get();
14802bdbfd50SJim Ingham   else
14812bdbfd50SJim Ingham     return NULL;
14822bdbfd50SJim Ingham }
14832bdbfd50SJim Ingham 
1484b9c1b51eSKate Stone lldb_private::Thread *SBThread::get() {
14852bdbfd50SJim Ingham   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
14862bdbfd50SJim Ingham   if (thread_sp)
14872bdbfd50SJim Ingham     return thread_sp.get();
14882bdbfd50SJim Ingham   else
14892bdbfd50SJim Ingham     return NULL;
14902bdbfd50SJim Ingham }
1491