130fdc8d8SChris Lattner //===-- SBThread.cpp --------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner 
94c5de699SEli Friedman #include "lldb/API/SBThread.h"
1030fdc8d8SChris Lattner 
1130fdc8d8SChris Lattner #include "lldb/API/SBFileSpec.h"
12dde9cff3SCaroline Tice #include "lldb/API/SBStream.h"
13b9c1b51eSKate Stone #include "lldb/API/SBSymbolContext.h"
144e78f606SGreg Clayton #include "lldb/Breakpoint/BreakpointLocation.h"
156611103cSGreg Clayton #include "lldb/Core/Debugger.h"
1630fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h"
17a78bd7ffSZachary Turner #include "lldb/Core/ValueObject.h"
186611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
1993749ab3SZachary Turner #include "lldb/Symbol/CompileUnit.h"
20b9c1b51eSKate Stone #include "lldb/Symbol/SymbolContext.h"
2130fdc8d8SChris Lattner #include "lldb/Target/Process.h"
22b9ffa98cSJason Molenda #include "lldb/Target/Queue.h"
23f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h"
24b9c1b51eSKate Stone #include "lldb/Target/SystemRuntime.h"
2530fdc8d8SChris Lattner #include "lldb/Target/Target.h"
26b9c1b51eSKate Stone #include "lldb/Target/Thread.h"
2730fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h"
28b9c1b51eSKate Stone #include "lldb/Target/ThreadPlanStepInRange.h"
2930fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h"
3030fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h"
3130fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h"
32b9c1b51eSKate Stone #include "lldb/Target/UnixSignals.h"
33d821c997SPavel Labath #include "lldb/Utility/State.h"
34bf9a7730SZachary Turner #include "lldb/Utility/Stream.h"
35f2a8bccfSPavel Labath #include "lldb/Utility/StructuredData.h"
3630fdc8d8SChris Lattner 
374c5de699SEli Friedman #include "lldb/API/SBAddress.h"
384c5de699SEli Friedman #include "lldb/API/SBDebugger.h"
394f465cffSJim Ingham #include "lldb/API/SBEvent.h"
4073ca05a2SJim Ingham #include "lldb/API/SBFrame.h"
414c5de699SEli Friedman #include "lldb/API/SBProcess.h"
426a831436SKuba Brecka #include "lldb/API/SBThreadCollection.h"
432bdbfd50SJim Ingham #include "lldb/API/SBThreadPlan.h"
4473ca05a2SJim Ingham #include "lldb/API/SBValue.h"
455bfee5f1SAbhishek Aggarwal #include "lldb/lldb-enumerations.h"
4630fdc8d8SChris Lattner 
4730fdc8d8SChris Lattner using namespace lldb;
4830fdc8d8SChris Lattner using namespace lldb_private;
4930fdc8d8SChris Lattner 
50b9c1b51eSKate Stone const char *SBThread::GetBroadcasterClassName() {
514f465cffSJim Ingham   return Thread::GetStaticBroadcasterClass().AsCString();
524f465cffSJim Ingham }
534f465cffSJim Ingham 
54cfd1acedSGreg Clayton //----------------------------------------------------------------------
55cfd1acedSGreg Clayton // Constructors
56cfd1acedSGreg Clayton //----------------------------------------------------------------------
57b9c1b51eSKate Stone SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {}
5830fdc8d8SChris Lattner 
59b9c1b51eSKate Stone SBThread::SBThread(const ThreadSP &lldb_object_sp)
60b9c1b51eSKate Stone     : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {}
6130fdc8d8SChris Lattner 
62b9c1b51eSKate Stone SBThread::SBThread(const SBThread &rhs)
63b9c1b51eSKate Stone     : m_opaque_sp(new ExecutionContextRef(*rhs.m_opaque_sp)) {}
6430fdc8d8SChris Lattner 
6530fdc8d8SChris Lattner //----------------------------------------------------------------------
66cfd1acedSGreg Clayton // Assignment operator
67cfd1acedSGreg Clayton //----------------------------------------------------------------------
68cfd1acedSGreg Clayton 
69b9c1b51eSKate Stone const lldb::SBThread &SBThread::operator=(const SBThread &rhs) {
70cfd1acedSGreg Clayton   if (this != &rhs)
717fdf9ef1SGreg Clayton     *m_opaque_sp = *rhs.m_opaque_sp;
72cfd1acedSGreg Clayton   return *this;
73cfd1acedSGreg Clayton }
74cfd1acedSGreg Clayton 
75cfd1acedSGreg Clayton //----------------------------------------------------------------------
7630fdc8d8SChris Lattner // Destructor
7730fdc8d8SChris Lattner //----------------------------------------------------------------------
78b9c1b51eSKate Stone SBThread::~SBThread() {}
7930fdc8d8SChris Lattner 
80b9c1b51eSKate Stone lldb::SBQueue SBThread::GetQueue() const {
81b9ffa98cSJason Molenda   SBQueue sb_queue;
82b9ffa98cSJason Molenda   QueueSP queue_sp;
83bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
84bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
85b9ffa98cSJason Molenda 
86b9ffa98cSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
87b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
88b9ffa98cSJason Molenda     Process::StopLocker stop_locker;
89b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
90b9ffa98cSJason Molenda       queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
91b9c1b51eSKate Stone       if (queue_sp) {
92b9ffa98cSJason Molenda         sb_queue.SetQueue(queue_sp);
93b9ffa98cSJason Molenda       }
94b9c1b51eSKate Stone     } else {
95b9ffa98cSJason Molenda       if (log)
96358cf1eaSGreg Clayton         log->Printf("SBThread(%p)::GetQueue() => error: process is running",
97b9ffa98cSJason Molenda                     static_cast<void *>(exe_ctx.GetThreadPtr()));
98b9ffa98cSJason Molenda     }
99b9ffa98cSJason Molenda   }
100b9ffa98cSJason Molenda 
101b9ffa98cSJason Molenda   if (log)
102358cf1eaSGreg Clayton     log->Printf("SBThread(%p)::GetQueue () => SBQueue(%p)",
103b9c1b51eSKate Stone                 static_cast<void *>(exe_ctx.GetThreadPtr()),
104b9c1b51eSKate Stone                 static_cast<void *>(queue_sp.get()));
105b9ffa98cSJason Molenda 
106b9ffa98cSJason Molenda   return sb_queue;
107b9ffa98cSJason Molenda }
108b9ffa98cSJason Molenda 
109b9c1b51eSKate Stone bool SBThread::IsValid() const {
110bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
111bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1127fa7dc36SJim Ingham 
1137fa7dc36SJim Ingham   Target *target = exe_ctx.GetTargetPtr();
1147fa7dc36SJim Ingham   Process *process = exe_ctx.GetProcessPtr();
115b9c1b51eSKate Stone   if (target && process) {
1167fa7dc36SJim Ingham     Process::StopLocker stop_locker;
1177fa7dc36SJim Ingham     if (stop_locker.TryLock(&process->GetRunLock()))
1187fdf9ef1SGreg Clayton       return m_opaque_sp->GetThreadSP().get() != NULL;
11930fdc8d8SChris Lattner   }
1207fa7dc36SJim Ingham   // Without a valid target & process, this thread can't be valid.
1217fa7dc36SJim Ingham   return false;
1227fa7dc36SJim Ingham }
12330fdc8d8SChris Lattner 
124b9c1b51eSKate Stone void SBThread::Clear() { m_opaque_sp->Clear(); }
12548e42549SGreg Clayton 
126b9c1b51eSKate Stone StopReason SBThread::GetStopReason() {
1275160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
128ceb6b139SCaroline Tice 
129ceb6b139SCaroline Tice   StopReason reason = eStopReasonInvalid;
130bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
131bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1324fc6cb9cSJim Ingham 
133b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1347fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
135b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
13697d5cf05SGreg Clayton       return exe_ctx.GetThreadPtr()->GetStopReason();
137b9c1b51eSKate Stone     } else {
138c9858e4dSGreg Clayton       if (log)
139b9c1b51eSKate Stone         log->Printf(
140b9c1b51eSKate Stone             "SBThread(%p)::GetStopReason() => error: process is running",
141324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
142c9858e4dSGreg Clayton     }
1437fdf9ef1SGreg Clayton   }
144ceb6b139SCaroline Tice 
145ceb6b139SCaroline Tice   if (log)
146324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetStopReason () => %s",
147324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
148750cd175SCaroline Tice                 Thread::StopReasonAsCString(reason));
149ceb6b139SCaroline Tice 
150ceb6b139SCaroline Tice   return reason;
15130fdc8d8SChris Lattner }
15230fdc8d8SChris Lattner 
153b9c1b51eSKate Stone size_t SBThread::GetStopReasonDataCount() {
154bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
155bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1564fc6cb9cSJim Ingham 
157b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1587fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
159b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1601ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
161b9c1b51eSKate Stone       if (stop_info_sp) {
1624e78f606SGreg Clayton         StopReason reason = stop_info_sp->GetStopReason();
163b9c1b51eSKate Stone         switch (reason) {
1644e78f606SGreg Clayton         case eStopReasonInvalid:
1654e78f606SGreg Clayton         case eStopReasonNone:
1664e78f606SGreg Clayton         case eStopReasonTrace:
16790ba8115SGreg Clayton         case eStopReasonExec:
1684e78f606SGreg Clayton         case eStopReasonPlanComplete:
169f85defaeSAndrew Kaylor         case eStopReasonThreadExiting:
170afdf842bSKuba Brecka         case eStopReasonInstrumentation:
1714e78f606SGreg Clayton           // There is no data for these stop reasons.
1724e78f606SGreg Clayton           return 0;
1734e78f606SGreg Clayton 
174b9c1b51eSKate Stone         case eStopReasonBreakpoint: {
1754e78f606SGreg Clayton           break_id_t site_id = stop_info_sp->GetValue();
176b9c1b51eSKate Stone           lldb::BreakpointSiteSP bp_site_sp(
177b9c1b51eSKate Stone               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
178b9c1b51eSKate Stone                   site_id));
1794e78f606SGreg Clayton           if (bp_site_sp)
1804e78f606SGreg Clayton             return bp_site_sp->GetNumberOfOwners() * 2;
1814e78f606SGreg Clayton           else
1824e78f606SGreg Clayton             return 0; // Breakpoint must have cleared itself...
183b9c1b51eSKate Stone         } break;
1844e78f606SGreg Clayton 
1854e78f606SGreg Clayton         case eStopReasonWatchpoint:
186290fa41bSJohnny Chen           return 1;
1874e78f606SGreg Clayton 
1884e78f606SGreg Clayton         case eStopReasonSignal:
1894e78f606SGreg Clayton           return 1;
1904e78f606SGreg Clayton 
1914e78f606SGreg Clayton         case eStopReasonException:
1924e78f606SGreg Clayton           return 1;
1934e78f606SGreg Clayton         }
1944e78f606SGreg Clayton       }
195b9c1b51eSKate Stone     } else {
1965160ce5cSGreg Clayton       Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
197c9858e4dSGreg Clayton       if (log)
198b9c1b51eSKate Stone         log->Printf("SBThread(%p)::GetStopReasonDataCount() => error: process "
199b9c1b51eSKate Stone                     "is running",
200324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
201c9858e4dSGreg Clayton     }
2027fdf9ef1SGreg Clayton   }
2034e78f606SGreg Clayton   return 0;
2044e78f606SGreg Clayton }
2054e78f606SGreg Clayton 
206b9c1b51eSKate Stone uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
207bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
208bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
2094fc6cb9cSJim Ingham 
210b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
2117fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
212b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
2131ac04c30SGreg Clayton       Thread *thread = exe_ctx.GetThreadPtr();
2141ac04c30SGreg Clayton       StopInfoSP stop_info_sp = thread->GetStopInfo();
215b9c1b51eSKate Stone       if (stop_info_sp) {
2164e78f606SGreg Clayton         StopReason reason = stop_info_sp->GetStopReason();
217b9c1b51eSKate Stone         switch (reason) {
2184e78f606SGreg Clayton         case eStopReasonInvalid:
2194e78f606SGreg Clayton         case eStopReasonNone:
2204e78f606SGreg Clayton         case eStopReasonTrace:
22190ba8115SGreg Clayton         case eStopReasonExec:
2224e78f606SGreg Clayton         case eStopReasonPlanComplete:
223f85defaeSAndrew Kaylor         case eStopReasonThreadExiting:
224afdf842bSKuba Brecka         case eStopReasonInstrumentation:
2254e78f606SGreg Clayton           // There is no data for these stop reasons.
2264e78f606SGreg Clayton           return 0;
2274e78f606SGreg Clayton 
228b9c1b51eSKate Stone         case eStopReasonBreakpoint: {
2294e78f606SGreg Clayton           break_id_t site_id = stop_info_sp->GetValue();
230b9c1b51eSKate Stone           lldb::BreakpointSiteSP bp_site_sp(
231b9c1b51eSKate Stone               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
232b9c1b51eSKate Stone                   site_id));
233b9c1b51eSKate Stone           if (bp_site_sp) {
2344e78f606SGreg Clayton             uint32_t bp_index = idx / 2;
235b9c1b51eSKate Stone             BreakpointLocationSP bp_loc_sp(
236b9c1b51eSKate Stone                 bp_site_sp->GetOwnerAtIndex(bp_index));
237b9c1b51eSKate Stone             if (bp_loc_sp) {
238b9c1b51eSKate Stone               if (idx & 1) {
2394e78f606SGreg Clayton                 // Odd idx, return the breakpoint location ID
2404e78f606SGreg Clayton                 return bp_loc_sp->GetID();
241b9c1b51eSKate Stone               } else {
2424e78f606SGreg Clayton                 // Even idx, return the breakpoint ID
2434e78f606SGreg Clayton                 return bp_loc_sp->GetBreakpoint().GetID();
2444e78f606SGreg Clayton               }
2454e78f606SGreg Clayton             }
2464e78f606SGreg Clayton           }
2474e78f606SGreg Clayton           return LLDB_INVALID_BREAK_ID;
248b9c1b51eSKate Stone         } break;
2494e78f606SGreg Clayton 
2504e78f606SGreg Clayton         case eStopReasonWatchpoint:
251290fa41bSJohnny Chen           return stop_info_sp->GetValue();
2524e78f606SGreg Clayton 
2534e78f606SGreg Clayton         case eStopReasonSignal:
2544e78f606SGreg Clayton           return stop_info_sp->GetValue();
2554e78f606SGreg Clayton 
2564e78f606SGreg Clayton         case eStopReasonException:
2574e78f606SGreg Clayton           return stop_info_sp->GetValue();
2584e78f606SGreg Clayton         }
2594e78f606SGreg Clayton       }
260b9c1b51eSKate Stone     } else {
2615160ce5cSGreg Clayton       Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
262c9858e4dSGreg Clayton       if (log)
263b9c1b51eSKate Stone         log->Printf("SBThread(%p)::GetStopReasonDataAtIndex() => error: "
264b9c1b51eSKate Stone                     "process is running",
265324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
266c9858e4dSGreg Clayton     }
2677fdf9ef1SGreg Clayton   }
2684e78f606SGreg Clayton   return 0;
2694e78f606SGreg Clayton }
2704e78f606SGreg Clayton 
271b9c1b51eSKate Stone bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) {
272afdf842bSKuba Brecka   Stream &strm = stream.ref();
273afdf842bSKuba Brecka 
274b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
275b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
276b2e7d28eSJim Ingham 
277afdf842bSKuba Brecka   if (!exe_ctx.HasThreadScope())
278afdf842bSKuba Brecka     return false;
279afdf842bSKuba Brecka 
280afdf842bSKuba Brecka   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
281afdf842bSKuba Brecka   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
282afdf842bSKuba Brecka   if (!info)
283afdf842bSKuba Brecka     return false;
284afdf842bSKuba Brecka 
285afdf842bSKuba Brecka   info->Dump(strm);
286afdf842bSKuba Brecka 
287afdf842bSKuba Brecka   return true;
288afdf842bSKuba Brecka }
289afdf842bSKuba Brecka 
2906a831436SKuba Brecka SBThreadCollection
291b9c1b51eSKate Stone SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
2926a831436SKuba Brecka   ThreadCollectionSP threads;
2936a831436SKuba Brecka   threads.reset(new ThreadCollection());
2946a831436SKuba Brecka 
295b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
296b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
297b2e7d28eSJim Ingham 
2986a831436SKuba Brecka   if (!exe_ctx.HasThreadScope())
2991aad8fb7SKuba Brecka     return threads;
3006a831436SKuba Brecka 
3016a831436SKuba Brecka   ProcessSP process_sp = exe_ctx.GetProcessSP();
3026a831436SKuba Brecka 
3036a831436SKuba Brecka   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
3046a831436SKuba Brecka   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
3056a831436SKuba Brecka   if (!info)
3066a831436SKuba Brecka     return threads;
3076a831436SKuba Brecka 
308b9c1b51eSKate Stone   return process_sp->GetInstrumentationRuntime(type)
309b9c1b51eSKate Stone       ->GetBacktracesFromExtendedStopInfo(info);
3106a831436SKuba Brecka }
3116a831436SKuba Brecka 
312b9c1b51eSKate Stone size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
3135160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
314ceb6b139SCaroline Tice 
315bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
316bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3174fc6cb9cSJim Ingham 
318b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
3197fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
320b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
3217fdf9ef1SGreg Clayton 
3221ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
323b9c1b51eSKate Stone       if (stop_info_sp) {
324b15bfc75SJim Ingham         const char *stop_desc = stop_info_sp->GetDescription();
325b9c1b51eSKate Stone         if (stop_desc) {
326ceb6b139SCaroline Tice           if (log)
327b9c1b51eSKate Stone             log->Printf(
328b9c1b51eSKate Stone                 "SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
329b9c1b51eSKate Stone                 static_cast<void *>(exe_ctx.GetThreadPtr()), stop_desc);
33030fdc8d8SChris Lattner           if (dst)
33130fdc8d8SChris Lattner             return ::snprintf(dst, dst_len, "%s", stop_desc);
332b9c1b51eSKate Stone           else {
333b9c1b51eSKate Stone             // NULL dst passed in, return the length needed to contain the
334b9c1b51eSKate Stone             // description
33530fdc8d8SChris Lattner             return ::strlen(stop_desc) + 1; // Include the NULL byte for size
33630fdc8d8SChris Lattner           }
337b9c1b51eSKate Stone         } else {
33830fdc8d8SChris Lattner           size_t stop_desc_len = 0;
339b9c1b51eSKate Stone           switch (stop_info_sp->GetStopReason()) {
34030fdc8d8SChris Lattner           case eStopReasonTrace:
341b9c1b51eSKate Stone           case eStopReasonPlanComplete: {
34230fdc8d8SChris Lattner             static char trace_desc[] = "step";
34330fdc8d8SChris Lattner             stop_desc = trace_desc;
344b9c1b51eSKate Stone             stop_desc_len =
345b9c1b51eSKate Stone                 sizeof(trace_desc); // Include the NULL byte for size
346b9c1b51eSKate Stone           } break;
34730fdc8d8SChris Lattner 
348b9c1b51eSKate Stone           case eStopReasonBreakpoint: {
34930fdc8d8SChris Lattner             static char bp_desc[] = "breakpoint hit";
35030fdc8d8SChris Lattner             stop_desc = bp_desc;
35130fdc8d8SChris Lattner             stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
352b9c1b51eSKate Stone           } break;
35330fdc8d8SChris Lattner 
354b9c1b51eSKate Stone           case eStopReasonWatchpoint: {
35530fdc8d8SChris Lattner             static char wp_desc[] = "watchpoint hit";
35630fdc8d8SChris Lattner             stop_desc = wp_desc;
35730fdc8d8SChris Lattner             stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
358b9c1b51eSKate Stone           } break;
35930fdc8d8SChris Lattner 
360b9c1b51eSKate Stone           case eStopReasonSignal: {
361b9c1b51eSKate Stone             stop_desc =
362b9c1b51eSKate Stone                 exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString(
363b9c1b51eSKate Stone                     stop_info_sp->GetValue());
364b9c1b51eSKate Stone             if (stop_desc == NULL || stop_desc[0] == '\0') {
36530fdc8d8SChris Lattner               static char signal_desc[] = "signal";
36630fdc8d8SChris Lattner               stop_desc = signal_desc;
367b9c1b51eSKate Stone               stop_desc_len =
368b9c1b51eSKate Stone                   sizeof(signal_desc); // Include the NULL byte for size
36930fdc8d8SChris Lattner             }
370b9c1b51eSKate Stone           } break;
37130fdc8d8SChris Lattner 
372b9c1b51eSKate Stone           case eStopReasonException: {
37330fdc8d8SChris Lattner             char exc_desc[] = "exception";
37430fdc8d8SChris Lattner             stop_desc = exc_desc;
37530fdc8d8SChris Lattner             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
376b9c1b51eSKate Stone           } break;
377c982c768SGreg Clayton 
378b9c1b51eSKate Stone           case eStopReasonExec: {
37990ba8115SGreg Clayton             char exc_desc[] = "exec";
38090ba8115SGreg Clayton             stop_desc = exc_desc;
38190ba8115SGreg Clayton             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
382b9c1b51eSKate Stone           } break;
38390ba8115SGreg Clayton 
384b9c1b51eSKate Stone           case eStopReasonThreadExiting: {
385f85defaeSAndrew Kaylor             char limbo_desc[] = "thread exiting";
386f85defaeSAndrew Kaylor             stop_desc = limbo_desc;
387f85defaeSAndrew Kaylor             stop_desc_len = sizeof(limbo_desc);
388b9c1b51eSKate Stone           } break;
389c982c768SGreg Clayton           default:
390c982c768SGreg Clayton             break;
39130fdc8d8SChris Lattner           }
39230fdc8d8SChris Lattner 
393b9c1b51eSKate Stone           if (stop_desc && stop_desc[0]) {
394ceb6b139SCaroline Tice             if (log)
395b9c1b51eSKate Stone               log->Printf(
396b9c1b51eSKate Stone                   "SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
397b9c1b51eSKate Stone                   static_cast<void *>(exe_ctx.GetThreadPtr()), stop_desc);
398ceb6b139SCaroline Tice 
39930fdc8d8SChris Lattner             if (dst)
400b9c1b51eSKate Stone               return ::snprintf(dst, dst_len, "%s", stop_desc) +
401b9c1b51eSKate Stone                      1; // Include the NULL byte
40230fdc8d8SChris Lattner 
40330fdc8d8SChris Lattner             if (stop_desc_len == 0)
40430fdc8d8SChris Lattner               stop_desc_len = ::strlen(stop_desc) + 1; // Include the NULL byte
40530fdc8d8SChris Lattner 
40630fdc8d8SChris Lattner             return stop_desc_len;
40730fdc8d8SChris Lattner           }
40830fdc8d8SChris Lattner         }
40930fdc8d8SChris Lattner       }
410b9c1b51eSKate Stone     } else {
4115160ce5cSGreg Clayton       Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
412c9858e4dSGreg Clayton       if (log)
413b9c1b51eSKate Stone         log->Printf(
414b9c1b51eSKate Stone             "SBThread(%p)::GetStopDescription() => error: process is running",
415324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
416c9858e4dSGreg Clayton     }
4177fdf9ef1SGreg Clayton   }
41830fdc8d8SChris Lattner   if (dst)
41930fdc8d8SChris Lattner     *dst = 0;
42030fdc8d8SChris Lattner   return 0;
42130fdc8d8SChris Lattner }
42230fdc8d8SChris Lattner 
423b9c1b51eSKate Stone SBValue SBThread::GetStopReturnValue() {
4245160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
42573ca05a2SJim Ingham   ValueObjectSP return_valobj_sp;
426bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
427bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4284fc6cb9cSJim Ingham 
429b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4307fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
431b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4321ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
433b9c1b51eSKate Stone       if (stop_info_sp) {
43473ca05a2SJim Ingham         return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp);
43573ca05a2SJim Ingham       }
436b9c1b51eSKate Stone     } else {
437c9858e4dSGreg Clayton       if (log)
438b9c1b51eSKate Stone         log->Printf(
439b9c1b51eSKate Stone             "SBThread(%p)::GetStopReturnValue() => error: process is running",
440324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
441c9858e4dSGreg Clayton     }
4427fdf9ef1SGreg Clayton   }
44373ca05a2SJim Ingham 
44473ca05a2SJim Ingham   if (log)
445324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetStopReturnValue () => %s",
446324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
447b9c1b51eSKate Stone                 return_valobj_sp.get() ? return_valobj_sp->GetValueAsCString()
44873ca05a2SJim Ingham                                        : "<no return value>");
44973ca05a2SJim Ingham 
45073ca05a2SJim Ingham   return SBValue(return_valobj_sp);
45173ca05a2SJim Ingham }
45273ca05a2SJim Ingham 
453b9c1b51eSKate Stone void SBThread::SetThread(const ThreadSP &lldb_object_sp) {
4547fdf9ef1SGreg Clayton   m_opaque_sp->SetThreadSP(lldb_object_sp);
45530fdc8d8SChris Lattner }
45630fdc8d8SChris Lattner 
457b9c1b51eSKate Stone lldb::tid_t SBThread::GetThreadID() const {
4587fdf9ef1SGreg Clayton   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
45917a6ad05SGreg Clayton   if (thread_sp)
4601ac04c30SGreg Clayton     return thread_sp->GetID();
4611ac04c30SGreg Clayton   return LLDB_INVALID_THREAD_ID;
46230fdc8d8SChris Lattner }
46330fdc8d8SChris Lattner 
464b9c1b51eSKate Stone uint32_t SBThread::GetIndexID() const {
4657fdf9ef1SGreg Clayton   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
46617a6ad05SGreg Clayton   if (thread_sp)
46717a6ad05SGreg Clayton     return thread_sp->GetIndexID();
46830fdc8d8SChris Lattner   return LLDB_INVALID_INDEX32;
46930fdc8d8SChris Lattner }
4701ac04c30SGreg Clayton 
471b9c1b51eSKate Stone const char *SBThread::GetName() const {
4725160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
4734838131bSGreg Clayton   const char *name = NULL;
474bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
475bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4764fc6cb9cSJim Ingham 
477b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4787fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
479b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4801ac04c30SGreg Clayton       name = exe_ctx.GetThreadPtr()->GetName();
481b9c1b51eSKate Stone     } else {
482c9858e4dSGreg Clayton       if (log)
483324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::GetName() => error: process is running",
484324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
485c9858e4dSGreg Clayton     }
4867fdf9ef1SGreg Clayton   }
487ceb6b139SCaroline Tice 
488ceb6b139SCaroline Tice   if (log)
489324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetName () => %s",
490324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
491324a1036SSaleem Abdulrasool                 name ? name : "NULL");
492ceb6b139SCaroline Tice 
4934838131bSGreg Clayton   return name;
49430fdc8d8SChris Lattner }
49530fdc8d8SChris Lattner 
496b9c1b51eSKate Stone const char *SBThread::GetQueueName() const {
4974838131bSGreg Clayton   const char *name = NULL;
498bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
499bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
5004fc6cb9cSJim Ingham 
5015160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
502b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
5037fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
504b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
5051ac04c30SGreg Clayton       name = exe_ctx.GetThreadPtr()->GetQueueName();
506b9c1b51eSKate Stone     } else {
507c9858e4dSGreg Clayton       if (log)
508324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::GetQueueName() => error: process is running",
509324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
510c9858e4dSGreg Clayton     }
5117fdf9ef1SGreg Clayton   }
512ceb6b139SCaroline Tice 
513ceb6b139SCaroline Tice   if (log)
514324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetQueueName () => %s",
515324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
516324a1036SSaleem Abdulrasool                 name ? name : "NULL");
517ceb6b139SCaroline Tice 
5184838131bSGreg Clayton   return name;
51930fdc8d8SChris Lattner }
52030fdc8d8SChris Lattner 
521b9c1b51eSKate Stone lldb::queue_id_t SBThread::GetQueueID() const {
5224fdb5863SJason Molenda   queue_id_t id = LLDB_INVALID_QUEUE_ID;
523bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
524bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
5254fdb5863SJason Molenda 
5264fdb5863SJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
527b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
5284fdb5863SJason Molenda     Process::StopLocker stop_locker;
529b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
5304fdb5863SJason Molenda       id = exe_ctx.GetThreadPtr()->GetQueueID();
531b9c1b51eSKate Stone     } else {
5324fdb5863SJason Molenda       if (log)
533324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::GetQueueID() => error: process is running",
534324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
5354fdb5863SJason Molenda     }
5364fdb5863SJason Molenda   }
5374fdb5863SJason Molenda 
5384fdb5863SJason Molenda   if (log)
539324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetQueueID () => 0x%" PRIx64,
540324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), id);
5414fdb5863SJason Molenda 
5424fdb5863SJason Molenda   return id;
5434fdb5863SJason Molenda }
5444fdb5863SJason Molenda 
545b9c1b51eSKate Stone bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
546705b1809SJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
547705b1809SJason Molenda   bool success = false;
548bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
549bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
550705b1809SJason Molenda 
551b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
552705b1809SJason Molenda     Process::StopLocker stop_locker;
553b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
554705b1809SJason Molenda       Thread *thread = exe_ctx.GetThreadPtr();
555705b1809SJason Molenda       StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
556b9c1b51eSKate Stone       if (info_root_sp) {
557b9c1b51eSKate Stone         StructuredData::ObjectSP node =
558b9c1b51eSKate Stone             info_root_sp->GetObjectForDotSeparatedPath(path);
559b9c1b51eSKate Stone         if (node) {
5605bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeString) {
5612833321fSZachary Turner             strm.Printf("%s", node->GetAsString()->GetValue().str().c_str());
562705b1809SJason Molenda             success = true;
563705b1809SJason Molenda           }
5645bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeInteger) {
565705b1809SJason Molenda             strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue());
566705b1809SJason Molenda             success = true;
567705b1809SJason Molenda           }
5685bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeFloat) {
569705b1809SJason Molenda             strm.Printf("0x%f", node->GetAsFloat()->GetValue());
570705b1809SJason Molenda             success = true;
571705b1809SJason Molenda           }
5725bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeBoolean) {
573a6682a41SJonas Devlieghere             if (node->GetAsBoolean()->GetValue())
574705b1809SJason Molenda               strm.Printf("true");
575705b1809SJason Molenda             else
576705b1809SJason Molenda               strm.Printf("false");
577705b1809SJason Molenda             success = true;
578705b1809SJason Molenda           }
5795bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeNull) {
580705b1809SJason Molenda             strm.Printf("null");
581705b1809SJason Molenda             success = true;
582705b1809SJason Molenda           }
583705b1809SJason Molenda         }
584705b1809SJason Molenda       }
585b9c1b51eSKate Stone     } else {
586705b1809SJason Molenda       if (log)
587b9c1b51eSKate Stone         log->Printf("SBThread(%p)::GetInfoItemByPathAsString() => error: "
588b9c1b51eSKate Stone                     "process is running",
589705b1809SJason Molenda                     static_cast<void *>(exe_ctx.GetThreadPtr()));
590705b1809SJason Molenda     }
591705b1809SJason Molenda   }
592705b1809SJason Molenda 
593705b1809SJason Molenda   if (log)
594753e13c0SJason Molenda     log->Printf("SBThread(%p)::GetInfoItemByPathAsString (\"%s\") => \"%s\"",
595753e13c0SJason Molenda                 static_cast<void *>(exe_ctx.GetThreadPtr()), path, strm.GetData());
596705b1809SJason Molenda 
597705b1809SJason Molenda   return success;
598705b1809SJason Molenda }
599705b1809SJason Molenda 
600b9c1b51eSKate Stone SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
601b9c1b51eSKate Stone                                 ThreadPlan *new_plan) {
60264e7ead1SJim Ingham   SBError sb_error;
60364e7ead1SJim Ingham 
60464e7ead1SJim Ingham   Process *process = exe_ctx.GetProcessPtr();
605b9c1b51eSKate Stone   if (!process) {
60664e7ead1SJim Ingham     sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
60764e7ead1SJim Ingham     return sb_error;
60864e7ead1SJim Ingham   }
60964e7ead1SJim Ingham 
61064e7ead1SJim Ingham   Thread *thread = exe_ctx.GetThreadPtr();
611b9c1b51eSKate Stone   if (!thread) {
61264e7ead1SJim Ingham     sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
61364e7ead1SJim Ingham     return sb_error;
61464e7ead1SJim Ingham   }
61564e7ead1SJim Ingham 
616b9c1b51eSKate Stone   // User level plans should be Master Plans so they can be interrupted, other
61705097246SAdrian Prantl   // plans executed, and then a "continue" will resume the plan.
618b9c1b51eSKate Stone   if (new_plan != NULL) {
61964e7ead1SJim Ingham     new_plan->SetIsMasterPlan(true);
62064e7ead1SJim Ingham     new_plan->SetOkayToDiscard(false);
62164e7ead1SJim Ingham   }
62264e7ead1SJim Ingham 
62364e7ead1SJim Ingham   // Why do we need to set the current thread by ID here???
62464e7ead1SJim Ingham   process->GetThreadList().SetSelectedThreadByID(thread->GetID());
62564e7ead1SJim Ingham 
626dc6224e0SGreg Clayton   if (process->GetTarget().GetDebugger().GetAsyncExecution())
627dc6224e0SGreg Clayton     sb_error.ref() = process->Resume();
628dc6224e0SGreg Clayton   else
629dc6224e0SGreg Clayton     sb_error.ref() = process->ResumeSynchronous(NULL);
63064e7ead1SJim Ingham 
63164e7ead1SJim Ingham   return sb_error;
63264e7ead1SJim Ingham }
63330fdc8d8SChris Lattner 
634b9c1b51eSKate Stone void SBThread::StepOver(lldb::RunMode stop_other_threads) {
635859f54b3SAlexander Polyakov   SBError error; // Ignored
636859f54b3SAlexander Polyakov   StepOver(stop_other_threads, error);
637859f54b3SAlexander Polyakov }
638859f54b3SAlexander Polyakov 
639859f54b3SAlexander Polyakov void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
6405160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
641ceb6b139SCaroline Tice 
642bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
643bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
64417a6ad05SGreg Clayton 
645ceb6b139SCaroline Tice   if (log)
646324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::StepOver (stop_other_threads='%s')",
647324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
648ceb6b139SCaroline Tice                 Thread::RunModeAsCString(stop_other_threads));
649ceb6b139SCaroline Tice 
650859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
651859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
652859f54b3SAlexander Polyakov     return;
653859f54b3SAlexander Polyakov   }
654859f54b3SAlexander Polyakov 
6551ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
6567ba6e991SJim Ingham   bool abort_other_plans = false;
657b57e4a1bSJason Molenda   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
65830fdc8d8SChris Lattner 
659e103ae92SJonas Devlieghere   Status new_plan_status;
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,
667e103ae92SJonas Devlieghere           new_plan_status, avoid_no_debug);
668b9c1b51eSKate Stone     } else {
669b9c1b51eSKate Stone       new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
670e103ae92SJonas Devlieghere           true, abort_other_plans, stop_other_threads, new_plan_status);
67130fdc8d8SChris Lattner     }
67230fdc8d8SChris Lattner   }
673859f54b3SAlexander 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) {
682859f54b3SAlexander 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 
700859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
701859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
702859f54b3SAlexander Polyakov     return;
703859f54b3SAlexander Polyakov   }
704859f54b3SAlexander 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;
710e103ae92SJonas Devlieghere   Status new_plan_status;
71130fdc8d8SChris Lattner 
712b9c1b51eSKate Stone   if (frame_sp && frame_sp->HasDebugInformation()) {
713cbf6f9b2SJim Ingham     SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
714cbf6f9b2SJim Ingham     AddressRange range;
715cbf6f9b2SJim Ingham     if (end_line == LLDB_INVALID_LINE_NUMBER)
716cbf6f9b2SJim Ingham       range = sc.line_entry.range;
717b9c1b51eSKate Stone     else {
718cbf6f9b2SJim Ingham       if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
719cbf6f9b2SJim Ingham         return;
720cbf6f9b2SJim Ingham     }
721cbf6f9b2SJim Ingham 
722b9c1b51eSKate Stone     const LazyBool step_out_avoids_code_without_debug_info =
723b9c1b51eSKate Stone         eLazyBoolCalculate;
724b9c1b51eSKate Stone     const LazyBool step_in_avoids_code_without_debug_info =
725b9c1b51eSKate Stone         eLazyBoolCalculate;
726b9c1b51eSKate Stone     new_plan_sp = thread->QueueThreadPlanForStepInRange(
727b9c1b51eSKate Stone         abort_other_plans, range, sc, target_name, stop_other_threads,
728e103ae92SJonas Devlieghere         new_plan_status, step_in_avoids_code_without_debug_info,
7294b4b2478SJim Ingham         step_out_avoids_code_without_debug_info);
730b9c1b51eSKate Stone   } else {
731b9c1b51eSKate Stone     new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
732e103ae92SJonas Devlieghere         false, abort_other_plans, stop_other_threads, new_plan_status);
73330fdc8d8SChris Lattner   }
734e103ae92SJonas Devlieghere 
735e103ae92SJonas Devlieghere   if (new_plan_status.Success())
736cbf6f9b2SJim Ingham     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
737e103ae92SJonas Devlieghere   else
738e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
73930fdc8d8SChris Lattner }
74030fdc8d8SChris Lattner 
741b9c1b51eSKate Stone void SBThread::StepOut() {
742859f54b3SAlexander Polyakov   SBError error; // Ignored
743859f54b3SAlexander Polyakov   StepOut(error);
744859f54b3SAlexander Polyakov }
745859f54b3SAlexander Polyakov 
746859f54b3SAlexander Polyakov void SBThread::StepOut(SBError &error) {
7475160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
748ceb6b139SCaroline Tice 
749bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
750bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
7514fc6cb9cSJim Ingham 
75217a6ad05SGreg Clayton   if (log)
753324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::StepOut ()",
754324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()));
75517a6ad05SGreg Clayton 
756859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
757859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
758859f54b3SAlexander Polyakov     return;
759859f54b3SAlexander Polyakov   }
760859f54b3SAlexander Polyakov 
7617ba6e991SJim Ingham   bool abort_other_plans = false;
76294b09246SJim Ingham   bool stop_other_threads = false;
76330fdc8d8SChris Lattner 
7641ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
7651ac04c30SGreg Clayton 
7664b4b2478SJim Ingham   const LazyBool avoid_no_debug = eLazyBoolCalculate;
767e103ae92SJonas Devlieghere   Status new_plan_status;
768b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
769b9c1b51eSKate Stone       abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
770e103ae92SJonas Devlieghere       eVoteNoOpinion, 0, new_plan_status, avoid_no_debug));
771481cef25SGreg Clayton 
772e103ae92SJonas Devlieghere   if (new_plan_status.Success())
773859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
774e103ae92SJonas Devlieghere   else
775e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
776481cef25SGreg Clayton }
777481cef25SGreg Clayton 
778859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
779859f54b3SAlexander Polyakov   SBError error; // Ignored
780859f54b3SAlexander Polyakov   StepOutOfFrame(sb_frame, error);
781859f54b3SAlexander Polyakov }
782859f54b3SAlexander Polyakov 
783859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
7845160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
785481cef25SGreg Clayton 
786bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
787bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
7884fc6cb9cSJim Ingham 
789b9c1b51eSKate Stone   if (!sb_frame.IsValid()) {
790989a7558SJim Ingham     if (log)
791b9c1b51eSKate Stone       log->Printf(
792b9c1b51eSKate Stone           "SBThread(%p)::StepOutOfFrame passed an invalid frame, returning.",
793989a7558SJim Ingham           static_cast<void *>(exe_ctx.GetThreadPtr()));
794859f54b3SAlexander Polyakov     error.SetErrorString("passed invalid SBFrame object");
795989a7558SJim Ingham     return;
796989a7558SJim Ingham   }
797989a7558SJim Ingham 
798b57e4a1bSJason Molenda   StackFrameSP frame_sp(sb_frame.GetFrameSP());
799b9c1b51eSKate Stone   if (log) {
800481cef25SGreg Clayton     SBStream frame_desc_strm;
801481cef25SGreg Clayton     sb_frame.GetDescription(frame_desc_strm);
802324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)",
803324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
804b9c1b51eSKate Stone                 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
805481cef25SGreg Clayton   }
806481cef25SGreg Clayton 
807859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
808859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
809859f54b3SAlexander Polyakov     return;
810859f54b3SAlexander Polyakov   }
811859f54b3SAlexander Polyakov 
8127ba6e991SJim Ingham   bool abort_other_plans = false;
81394b09246SJim Ingham   bool stop_other_threads = false;
8141ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
815b9c1b51eSKate Stone   if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
816b9c1b51eSKate Stone     log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another "
817b9c1b51eSKate Stone                 "thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.",
818989a7558SJim Ingham                 static_cast<void *>(exe_ctx.GetThreadPtr()),
819b9c1b51eSKate Stone                 sb_frame.GetThread().GetThreadID(), thread->GetID());
820859f54b3SAlexander Polyakov     error.SetErrorString("passed a frame from another thread");
821859f54b3SAlexander Polyakov     return;
822989a7558SJim Ingham   }
823481cef25SGreg Clayton 
824e103ae92SJonas Devlieghere   Status new_plan_status;
825b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
826b9c1b51eSKate Stone       abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
827e103ae92SJonas Devlieghere       eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status));
82830fdc8d8SChris Lattner 
829e103ae92SJonas Devlieghere   if (new_plan_status.Success())
830859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
831e103ae92SJonas Devlieghere   else
832e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
83330fdc8d8SChris Lattner }
83430fdc8d8SChris Lattner 
835b9c1b51eSKate Stone void SBThread::StepInstruction(bool step_over) {
836859f54b3SAlexander Polyakov   SBError error; // Ignored
837859f54b3SAlexander Polyakov   StepInstruction(step_over, error);
838859f54b3SAlexander Polyakov }
839859f54b3SAlexander Polyakov 
840859f54b3SAlexander Polyakov void SBThread::StepInstruction(bool step_over, SBError &error) {
8415160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
842ceb6b139SCaroline Tice 
843bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
844bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
845ceb6b139SCaroline Tice 
84617a6ad05SGreg Clayton   if (log)
847324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::StepInstruction (step_over=%i)",
848324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), step_over);
84917a6ad05SGreg Clayton 
850859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
851859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
852859f54b3SAlexander Polyakov     return;
853859f54b3SAlexander Polyakov   }
854859f54b3SAlexander Polyakov 
8551ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
856e103ae92SJonas Devlieghere   Status new_plan_status;
857e103ae92SJonas Devlieghere   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction(
858e103ae92SJonas Devlieghere       step_over, true, true, new_plan_status));
85964e7ead1SJim Ingham 
860e103ae92SJonas Devlieghere   if (new_plan_status.Success())
861859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
862e103ae92SJonas Devlieghere   else
863e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
86430fdc8d8SChris Lattner }
86530fdc8d8SChris Lattner 
866b9c1b51eSKate Stone void SBThread::RunToAddress(lldb::addr_t addr) {
867859f54b3SAlexander Polyakov   SBError error; // Ignored
868859f54b3SAlexander Polyakov   RunToAddress(addr, error);
869859f54b3SAlexander Polyakov }
870859f54b3SAlexander Polyakov 
871859f54b3SAlexander Polyakov void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
8725160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
873ceb6b139SCaroline Tice 
874bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
875bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
876ceb6b139SCaroline Tice 
87717a6ad05SGreg Clayton   if (log)
878324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")",
879324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), addr);
88017a6ad05SGreg Clayton 
881859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
882859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
883859f54b3SAlexander Polyakov     return;
884859f54b3SAlexander Polyakov   }
885859f54b3SAlexander Polyakov 
8867ba6e991SJim Ingham   bool abort_other_plans = false;
88730fdc8d8SChris Lattner   bool stop_other_threads = true;
88830fdc8d8SChris Lattner 
889e72dfb32SGreg Clayton   Address target_addr(addr);
89030fdc8d8SChris Lattner 
8911ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
8921ac04c30SGreg Clayton 
893e103ae92SJonas Devlieghere   Status new_plan_status;
894b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
895e103ae92SJonas Devlieghere       abort_other_plans, target_addr, stop_other_threads, new_plan_status));
89664e7ead1SJim Ingham 
897e103ae92SJonas Devlieghere   if (new_plan_status.Success())
898859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
899e103ae92SJonas Devlieghere   else
900e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
90130fdc8d8SChris Lattner }
90230fdc8d8SChris Lattner 
903b9c1b51eSKate Stone SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
904b9c1b51eSKate Stone                                 lldb::SBFileSpec &sb_file_spec, uint32_t line) {
905481cef25SGreg Clayton   SBError sb_error;
9065160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
907481cef25SGreg Clayton   char path[PATH_MAX];
908481cef25SGreg Clayton 
909bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
910bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
9114fc6cb9cSJim Ingham 
912b57e4a1bSJason Molenda   StackFrameSP frame_sp(sb_frame.GetFrameSP());
91317a6ad05SGreg Clayton 
914b9c1b51eSKate Stone   if (log) {
915481cef25SGreg Clayton     SBStream frame_desc_strm;
916481cef25SGreg Clayton     sb_frame.GetDescription(frame_desc_strm);
917481cef25SGreg Clayton     sb_file_spec->GetPath(path, sizeof(path));
918b9c1b51eSKate Stone     log->Printf("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, "
919b9c1b51eSKate Stone                 "file+line = %s:%u)",
920324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
921b9c1b51eSKate Stone                 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData(),
922b9c1b51eSKate Stone                 path, line);
923481cef25SGreg Clayton   }
924481cef25SGreg Clayton 
925b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
9261ac04c30SGreg Clayton     Target *target = exe_ctx.GetTargetPtr();
9271ac04c30SGreg Clayton     Thread *thread = exe_ctx.GetThreadPtr();
928481cef25SGreg Clayton 
929b9c1b51eSKate Stone     if (line == 0) {
930481cef25SGreg Clayton       sb_error.SetErrorString("invalid line argument");
931481cef25SGreg Clayton       return sb_error;
932481cef25SGreg Clayton     }
933481cef25SGreg Clayton 
934b9c1b51eSKate Stone     if (!frame_sp) {
9351ac04c30SGreg Clayton       frame_sp = thread->GetSelectedFrame();
936481cef25SGreg Clayton       if (!frame_sp)
9371ac04c30SGreg Clayton         frame_sp = thread->GetStackFrameAtIndex(0);
938481cef25SGreg Clayton     }
939481cef25SGreg Clayton 
940481cef25SGreg Clayton     SymbolContext frame_sc;
941b9c1b51eSKate Stone     if (!frame_sp) {
942481cef25SGreg Clayton       sb_error.SetErrorString("no valid frames in thread to step");
943481cef25SGreg Clayton       return sb_error;
944481cef25SGreg Clayton     }
945481cef25SGreg Clayton 
946481cef25SGreg Clayton     // If we have a frame, get its line
947b9c1b51eSKate Stone     frame_sc = frame_sp->GetSymbolContext(
948b9c1b51eSKate Stone         eSymbolContextCompUnit | eSymbolContextFunction |
949b9c1b51eSKate Stone         eSymbolContextLineEntry | eSymbolContextSymbol);
950481cef25SGreg Clayton 
951b9c1b51eSKate Stone     if (frame_sc.comp_unit == NULL) {
952b9c1b51eSKate Stone       sb_error.SetErrorStringWithFormat(
953b9c1b51eSKate Stone           "frame %u doesn't have debug information", frame_sp->GetFrameIndex());
954481cef25SGreg Clayton       return sb_error;
955481cef25SGreg Clayton     }
956481cef25SGreg Clayton 
957481cef25SGreg Clayton     FileSpec step_file_spec;
958b9c1b51eSKate Stone     if (sb_file_spec.IsValid()) {
959481cef25SGreg Clayton       // The file spec passed in was valid, so use it
960481cef25SGreg Clayton       step_file_spec = sb_file_spec.ref();
961b9c1b51eSKate Stone     } else {
962481cef25SGreg Clayton       if (frame_sc.line_entry.IsValid())
963481cef25SGreg Clayton         step_file_spec = frame_sc.line_entry.file;
964b9c1b51eSKate Stone       else {
965481cef25SGreg Clayton         sb_error.SetErrorString("invalid file argument or no file for frame");
966481cef25SGreg Clayton         return sb_error;
967481cef25SGreg Clayton       }
968481cef25SGreg Clayton     }
969481cef25SGreg Clayton 
9709b70ddb3SJim Ingham     // Grab the current function, then we will make sure the "until" address is
9719b70ddb3SJim Ingham     // within the function.  We discard addresses that are out of the current
972b9c1b51eSKate Stone     // function, and then if there are no addresses remaining, give an
97305097246SAdrian Prantl     // appropriate error message.
9749b70ddb3SJim Ingham 
9759b70ddb3SJim Ingham     bool all_in_function = true;
9769b70ddb3SJim Ingham     AddressRange fun_range = frame_sc.function->GetAddressRange();
9779b70ddb3SJim Ingham 
978481cef25SGreg Clayton     std::vector<addr_t> step_over_until_addrs;
9797ba6e991SJim Ingham     const bool abort_other_plans = false;
980c02e3344SJim Ingham     const bool stop_other_threads = false;
981481cef25SGreg Clayton     const bool check_inlines = true;
982481cef25SGreg Clayton     const bool exact = false;
983481cef25SGreg Clayton 
984481cef25SGreg Clayton     SymbolContextList sc_list;
985b9c1b51eSKate Stone     const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext(
986b9c1b51eSKate Stone         step_file_spec, line, check_inlines, exact, eSymbolContextLineEntry,
9879b70ddb3SJim Ingham         sc_list);
988b9c1b51eSKate Stone     if (num_matches > 0) {
989481cef25SGreg Clayton       SymbolContext sc;
990b9c1b51eSKate Stone       for (uint32_t i = 0; i < num_matches; ++i) {
991b9c1b51eSKate Stone         if (sc_list.GetContextAtIndex(i, sc)) {
992b9c1b51eSKate Stone           addr_t step_addr =
993b9c1b51eSKate Stone               sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
994b9c1b51eSKate Stone           if (step_addr != LLDB_INVALID_ADDRESS) {
9959b70ddb3SJim Ingham             if (fun_range.ContainsLoadAddress(step_addr, target))
996481cef25SGreg Clayton               step_over_until_addrs.push_back(step_addr);
9979b70ddb3SJim Ingham             else
9989b70ddb3SJim Ingham               all_in_function = false;
999481cef25SGreg Clayton           }
1000481cef25SGreg Clayton         }
1001481cef25SGreg Clayton       }
1002481cef25SGreg Clayton     }
1003481cef25SGreg Clayton 
1004b9c1b51eSKate Stone     if (step_over_until_addrs.empty()) {
1005b9c1b51eSKate Stone       if (all_in_function) {
1006481cef25SGreg Clayton         step_file_spec.GetPath(path, sizeof(path));
1007b9c1b51eSKate Stone         sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path,
1008b9c1b51eSKate Stone                                           line);
1009b9c1b51eSKate Stone       } else
101086edbf41SGreg Clayton         sb_error.SetErrorString("step until target not in current function");
1011b9c1b51eSKate Stone     } else {
1012e103ae92SJonas Devlieghere       Status new_plan_status;
1013b9c1b51eSKate Stone       ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil(
1014b9c1b51eSKate Stone           abort_other_plans, &step_over_until_addrs[0],
1015b9c1b51eSKate Stone           step_over_until_addrs.size(), stop_other_threads,
1016e103ae92SJonas Devlieghere           frame_sp->GetFrameIndex(), new_plan_status));
1017481cef25SGreg Clayton 
1018e103ae92SJonas Devlieghere       if (new_plan_status.Success())
10194d56e9c1SJim Ingham         sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
1020e103ae92SJonas Devlieghere       else
1021e103ae92SJonas Devlieghere         sb_error.SetErrorString(new_plan_status.AsCString());
1022481cef25SGreg Clayton     }
1023b9c1b51eSKate Stone   } else {
1024481cef25SGreg Clayton     sb_error.SetErrorString("this SBThread object is invalid");
1025481cef25SGreg Clayton   }
1026481cef25SGreg Clayton   return sb_error;
1027481cef25SGreg Clayton }
1028481cef25SGreg Clayton 
1029b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) {
1030000ca185SOleksiy Vyalov   return StepUsingScriptedThreadPlan(script_class_name, true);
1031c915a7d2SJim Ingham }
1032c915a7d2SJim Ingham 
1033b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
1034b9c1b51eSKate Stone                                               bool resume_immediately) {
10352bdbfd50SJim Ingham   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1036e103ae92SJonas Devlieghere   SBError error;
10372bdbfd50SJim Ingham 
1038bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1039bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
10402bdbfd50SJim Ingham 
1041b9c1b51eSKate Stone   if (log) {
10422bdbfd50SJim Ingham     log->Printf("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s",
1043b9c1b51eSKate Stone                 static_cast<void *>(exe_ctx.GetThreadPtr()), script_class_name);
10442bdbfd50SJim Ingham   }
10452bdbfd50SJim Ingham 
1046b9c1b51eSKate Stone   if (!exe_ctx.HasThreadScope()) {
1047e103ae92SJonas Devlieghere     error.SetErrorString("this SBThread object is invalid");
1048e103ae92SJonas Devlieghere     return error;
10492bdbfd50SJim Ingham   }
10502bdbfd50SJim Ingham 
10512bdbfd50SJim Ingham   Thread *thread = exe_ctx.GetThreadPtr();
1052e103ae92SJonas Devlieghere   Status new_plan_status;
1053e103ae92SJonas Devlieghere   ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted(
1054e103ae92SJonas Devlieghere       false, script_class_name, false, new_plan_status);
10552bdbfd50SJim Ingham 
1056e103ae92SJonas Devlieghere   if (new_plan_status.Fail()) {
1057e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
1058e103ae92SJonas Devlieghere     return error;
1059c915a7d2SJim Ingham   }
1060c915a7d2SJim Ingham 
1061e103ae92SJonas Devlieghere   if (!resume_immediately)
1062e103ae92SJonas Devlieghere     return error;
1063c915a7d2SJim Ingham 
1064e103ae92SJonas Devlieghere   if (new_plan_status.Success())
1065e103ae92SJonas Devlieghere     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
1066e103ae92SJonas Devlieghere   else
1067e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
10682bdbfd50SJim Ingham 
1069e103ae92SJonas Devlieghere   return error;
10702bdbfd50SJim Ingham }
10712bdbfd50SJim Ingham 
1072b9c1b51eSKate Stone SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
1073f86248d9SRichard Mitton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1074f86248d9SRichard Mitton   SBError sb_error;
1075f86248d9SRichard Mitton 
1076bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1077bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1078f86248d9SRichard Mitton 
1079f86248d9SRichard Mitton   if (log)
1080324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::JumpToLine (file+line = %s:%u)",
1081324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
1082324a1036SSaleem Abdulrasool                 file_spec->GetPath().c_str(), line);
1083f86248d9SRichard Mitton 
1084b9c1b51eSKate Stone   if (!exe_ctx.HasThreadScope()) {
1085f86248d9SRichard Mitton     sb_error.SetErrorString("this SBThread object is invalid");
1086f86248d9SRichard Mitton     return sb_error;
1087f86248d9SRichard Mitton   }
1088f86248d9SRichard Mitton 
1089f86248d9SRichard Mitton   Thread *thread = exe_ctx.GetThreadPtr();
1090f86248d9SRichard Mitton 
109197206d57SZachary Turner   Status err = thread->JumpToLine(file_spec.get(), line, true);
1092f86248d9SRichard Mitton   sb_error.SetError(err);
1093f86248d9SRichard Mitton   return sb_error;
1094f86248d9SRichard Mitton }
1095f86248d9SRichard Mitton 
1096b9c1b51eSKate Stone SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
10974413758cSJim Ingham   SBError sb_error;
10984413758cSJim Ingham 
10995160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
11004413758cSJim Ingham 
1101bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1102bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11034413758cSJim Ingham 
11044413758cSJim Ingham   if (log)
1105324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::ReturnFromFrame (frame=%d)",
1106324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
1107324a1036SSaleem Abdulrasool                 frame.GetFrameID());
11084413758cSJim Ingham 
1109b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11104413758cSJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
1111b9c1b51eSKate Stone     sb_error.SetError(
1112b9c1b51eSKate Stone         thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
11134413758cSJim Ingham   }
11144413758cSJim Ingham 
11154413758cSJim Ingham   return sb_error;
11164413758cSJim Ingham }
11174413758cSJim Ingham 
1118b9c1b51eSKate Stone SBError SBThread::UnwindInnermostExpression() {
11194ac8e93aSJim Ingham   SBError sb_error;
11204ac8e93aSJim Ingham 
11214ac8e93aSJim Ingham   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
11224ac8e93aSJim Ingham 
11234ac8e93aSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
11244ac8e93aSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11254ac8e93aSJim Ingham 
11264ac8e93aSJim Ingham   if (log)
11274ac8e93aSJim Ingham     log->Printf("SBThread(%p)::UnwindExpressionEvaluation",
11284ac8e93aSJim Ingham                 static_cast<void *>(exe_ctx.GetThreadPtr()));
11294ac8e93aSJim Ingham 
1130b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11314ac8e93aSJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
11324ac8e93aSJim Ingham     sb_error.SetError(thread->UnwindInnermostExpression());
11334ac8e93aSJim Ingham     if (sb_error.Success())
11344ac8e93aSJim Ingham       thread->SetSelectedFrameByIndex(0, false);
11354ac8e93aSJim Ingham   }
11364ac8e93aSJim Ingham 
11374ac8e93aSJim Ingham   return sb_error;
11384ac8e93aSJim Ingham }
1139481cef25SGreg Clayton 
1140b9c1b51eSKate Stone bool SBThread::Suspend() {
1141859f54b3SAlexander Polyakov   SBError error; // Ignored
1142859f54b3SAlexander Polyakov   return Suspend(error);
1143859f54b3SAlexander Polyakov }
1144859f54b3SAlexander Polyakov 
1145859f54b3SAlexander Polyakov bool SBThread::Suspend(SBError &error) {
11465160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1147b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1148b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1149b2e7d28eSJim Ingham 
1150c9858e4dSGreg Clayton   bool result = false;
1151b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1152c9858e4dSGreg Clayton     Process::StopLocker stop_locker;
1153b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11541ac04c30SGreg Clayton       exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
1155c9858e4dSGreg Clayton       result = true;
1156b9c1b51eSKate Stone     } else {
1157859f54b3SAlexander Polyakov       error.SetErrorString("process is running");
1158c9858e4dSGreg Clayton       if (log)
1159324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::Suspend() => error: process is running",
1160324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
1161c9858e4dSGreg Clayton     }
1162859f54b3SAlexander Polyakov   } else
1163859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
1164c9858e4dSGreg Clayton   if (log)
1165324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::Suspend() => %i",
1166324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), result);
1167c9858e4dSGreg Clayton   return result;
1168722a0cdcSGreg Clayton }
1169722a0cdcSGreg Clayton 
1170b9c1b51eSKate Stone bool SBThread::Resume() {
1171859f54b3SAlexander Polyakov   SBError error; // Ignored
1172859f54b3SAlexander Polyakov   return Resume(error);
1173859f54b3SAlexander Polyakov }
1174859f54b3SAlexander Polyakov 
1175859f54b3SAlexander Polyakov bool SBThread::Resume(SBError &error) {
11765160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1177b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1178b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1179b2e7d28eSJim Ingham 
1180c9858e4dSGreg Clayton   bool result = false;
1181b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1182c9858e4dSGreg Clayton     Process::StopLocker stop_locker;
1183b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11846c9ed91cSJim Ingham       const bool override_suspend = true;
11856c9ed91cSJim Ingham       exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
1186c9858e4dSGreg Clayton       result = true;
1187b9c1b51eSKate Stone     } else {
1188859f54b3SAlexander Polyakov       error.SetErrorString("process is running");
1189c9858e4dSGreg Clayton       if (log)
1190324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::Resume() => error: process is running",
1191324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
1192c9858e4dSGreg Clayton     }
1193859f54b3SAlexander Polyakov   } else
1194859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
1195c9858e4dSGreg Clayton   if (log)
1196324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::Resume() => %i",
1197324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), result);
1198c9858e4dSGreg Clayton   return result;
1199722a0cdcSGreg Clayton }
1200722a0cdcSGreg Clayton 
1201b9c1b51eSKate Stone bool SBThread::IsSuspended() {
1202b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1203b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1204b2e7d28eSJim Ingham 
12051ac04c30SGreg Clayton   if (exe_ctx.HasThreadScope())
12061ac04c30SGreg Clayton     return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
1207722a0cdcSGreg Clayton   return false;
1208722a0cdcSGreg Clayton }
1209722a0cdcSGreg Clayton 
1210b9c1b51eSKate Stone bool SBThread::IsStopped() {
1211b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1212b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1213b2e7d28eSJim Ingham 
1214a75418dbSAndrew Kaylor   if (exe_ctx.HasThreadScope())
1215a75418dbSAndrew Kaylor     return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1216a75418dbSAndrew Kaylor   return false;
1217a75418dbSAndrew Kaylor }
1218a75418dbSAndrew Kaylor 
1219b9c1b51eSKate Stone SBProcess SBThread::GetProcess() {
1220b9556accSGreg Clayton   SBProcess sb_process;
1221b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1222b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1223b2e7d28eSJim Ingham 
1224b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1225b9c1b51eSKate Stone     // Have to go up to the target so we can get a shared pointer to our
1226b9c1b51eSKate Stone     // process...
12271ac04c30SGreg Clayton     sb_process.SetSP(exe_ctx.GetProcessSP());
122830fdc8d8SChris Lattner   }
1229ceb6b139SCaroline Tice 
12305160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1231b9c1b51eSKate Stone   if (log) {
1232481cef25SGreg Clayton     SBStream frame_desc_strm;
1233b9556accSGreg Clayton     sb_process.GetDescription(frame_desc_strm);
1234324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetProcess () => SBProcess(%p): %s",
1235324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
1236324a1036SSaleem Abdulrasool                 static_cast<void *>(sb_process.GetSP().get()),
1237324a1036SSaleem Abdulrasool                 frame_desc_strm.GetData());
1238ceb6b139SCaroline Tice   }
1239ceb6b139SCaroline Tice 
1240b9556accSGreg Clayton   return sb_process;
124130fdc8d8SChris Lattner }
124230fdc8d8SChris Lattner 
1243b9c1b51eSKate Stone uint32_t SBThread::GetNumFrames() {
12445160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1245ceb6b139SCaroline Tice 
1246ceb6b139SCaroline Tice   uint32_t num_frames = 0;
1247bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1248bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12494fc6cb9cSJim Ingham 
1250b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
12517fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1252b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
12531ac04c30SGreg Clayton       num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1254b9c1b51eSKate Stone     } else {
1255c9858e4dSGreg Clayton       if (log)
1256324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::GetNumFrames() => error: process is running",
1257324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
1258c9858e4dSGreg Clayton     }
12597fdf9ef1SGreg Clayton   }
1260ceb6b139SCaroline Tice 
1261ceb6b139SCaroline Tice   if (log)
1262324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetNumFrames () => %u",
1263324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), num_frames);
1264ceb6b139SCaroline Tice 
1265ceb6b139SCaroline Tice   return num_frames;
126630fdc8d8SChris Lattner }
126730fdc8d8SChris Lattner 
1268b9c1b51eSKate Stone SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
12695160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1270ceb6b139SCaroline Tice 
127130fdc8d8SChris Lattner   SBFrame sb_frame;
1272b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1273bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1274bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12754fc6cb9cSJim Ingham 
1276b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
12777fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1278b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
12791ac04c30SGreg Clayton       frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
1280b9556accSGreg Clayton       sb_frame.SetFrameSP(frame_sp);
1281b9c1b51eSKate Stone     } else {
1282c9858e4dSGreg Clayton       if (log)
1283b9c1b51eSKate Stone         log->Printf(
1284b9c1b51eSKate Stone             "SBThread(%p)::GetFrameAtIndex() => error: process is running",
1285324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
1286c9858e4dSGreg Clayton     }
12877fdf9ef1SGreg Clayton   }
1288ceb6b139SCaroline Tice 
1289b9c1b51eSKate Stone   if (log) {
1290481cef25SGreg Clayton     SBStream frame_desc_strm;
1291481cef25SGreg Clayton     sb_frame.GetDescription(frame_desc_strm);
12924838131bSGreg Clayton     log->Printf("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
1293324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), idx,
1294b9c1b51eSKate Stone                 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1295ceb6b139SCaroline Tice   }
1296ceb6b139SCaroline Tice 
129730fdc8d8SChris Lattner   return sb_frame;
129830fdc8d8SChris Lattner }
129930fdc8d8SChris Lattner 
1300b9c1b51eSKate Stone lldb::SBFrame SBThread::GetSelectedFrame() {
13015160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1302f028a1fbSGreg Clayton 
1303f028a1fbSGreg Clayton   SBFrame sb_frame;
1304b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1305bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1306bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
13074fc6cb9cSJim Ingham 
1308b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
13097fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1310b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
13111ac04c30SGreg Clayton       frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame();
1312b9556accSGreg Clayton       sb_frame.SetFrameSP(frame_sp);
1313b9c1b51eSKate Stone     } else {
1314c9858e4dSGreg Clayton       if (log)
1315b9c1b51eSKate Stone         log->Printf(
1316b9c1b51eSKate Stone             "SBThread(%p)::GetSelectedFrame() => error: process is running",
1317324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
1318c9858e4dSGreg Clayton     }
13197fdf9ef1SGreg Clayton   }
1320f028a1fbSGreg Clayton 
1321b9c1b51eSKate Stone   if (log) {
1322481cef25SGreg Clayton     SBStream frame_desc_strm;
1323481cef25SGreg Clayton     sb_frame.GetDescription(frame_desc_strm);
1324f028a1fbSGreg Clayton     log->Printf("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
1325324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
1326b9c1b51eSKate Stone                 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1327f028a1fbSGreg Clayton   }
1328f028a1fbSGreg Clayton 
1329f028a1fbSGreg Clayton   return sb_frame;
1330f028a1fbSGreg Clayton }
1331f028a1fbSGreg Clayton 
1332b9c1b51eSKate Stone lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
13335160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1334f028a1fbSGreg Clayton 
1335f028a1fbSGreg Clayton   SBFrame sb_frame;
1336b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1337bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1338bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
13394fc6cb9cSJim Ingham 
1340b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
13417fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1342b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
13431ac04c30SGreg Clayton       Thread *thread = exe_ctx.GetThreadPtr();
13441ac04c30SGreg Clayton       frame_sp = thread->GetStackFrameAtIndex(idx);
1345b9c1b51eSKate Stone       if (frame_sp) {
13461ac04c30SGreg Clayton         thread->SetSelectedFrame(frame_sp.get());
1347b9556accSGreg Clayton         sb_frame.SetFrameSP(frame_sp);
1348f028a1fbSGreg Clayton       }
1349b9c1b51eSKate Stone     } else {
1350c9858e4dSGreg Clayton       if (log)
1351b9c1b51eSKate Stone         log->Printf(
1352b9c1b51eSKate Stone             "SBThread(%p)::SetSelectedFrame() => error: process is running",
1353324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
1354c9858e4dSGreg Clayton     }
13557fdf9ef1SGreg Clayton   }
1356f028a1fbSGreg Clayton 
1357b9c1b51eSKate Stone   if (log) {
1358481cef25SGreg Clayton     SBStream frame_desc_strm;
1359481cef25SGreg Clayton     sb_frame.GetDescription(frame_desc_strm);
1360f028a1fbSGreg Clayton     log->Printf("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
1361324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), idx,
1362b9c1b51eSKate Stone                 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1363f028a1fbSGreg Clayton   }
1364f028a1fbSGreg Clayton   return sb_frame;
1365f028a1fbSGreg Clayton }
1366f028a1fbSGreg Clayton 
1367b9c1b51eSKate Stone bool SBThread::EventIsThreadEvent(const SBEvent &event) {
13684f465cffSJim Ingham   return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
13694f465cffSJim Ingham }
13704f465cffSJim Ingham 
1371b9c1b51eSKate Stone SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) {
13724f465cffSJim Ingham   return Thread::ThreadEventData::GetStackFrameFromEvent(event.get());
13734f465cffSJim Ingham }
13744f465cffSJim Ingham 
1375b9c1b51eSKate Stone SBThread SBThread::GetThreadFromEvent(const SBEvent &event) {
13764f465cffSJim Ingham   return Thread::ThreadEventData::GetThreadFromEvent(event.get());
13774f465cffSJim Ingham }
1378f028a1fbSGreg Clayton 
1379b9c1b51eSKate Stone bool SBThread::operator==(const SBThread &rhs) const {
1380b9c1b51eSKate Stone   return m_opaque_sp->GetThreadSP().get() ==
1381b9c1b51eSKate Stone          rhs.m_opaque_sp->GetThreadSP().get();
138230fdc8d8SChris Lattner }
138330fdc8d8SChris Lattner 
1384b9c1b51eSKate Stone bool SBThread::operator!=(const SBThread &rhs) const {
1385b9c1b51eSKate Stone   return m_opaque_sp->GetThreadSP().get() !=
1386b9c1b51eSKate Stone          rhs.m_opaque_sp->GetThreadSP().get();
138730fdc8d8SChris Lattner }
1388dde9cff3SCaroline Tice 
1389b9c1b51eSKate Stone bool SBThread::GetStatus(SBStream &status) const {
13904f465cffSJim Ingham   Stream &strm = status.ref();
13914f465cffSJim Ingham 
1392b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1393b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1394b2e7d28eSJim Ingham 
1395b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
13966a9767c7SJim Ingham     exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true);
1397b9c1b51eSKate Stone   } else
13984f465cffSJim Ingham     strm.PutCString("No status");
13994f465cffSJim Ingham 
14004f465cffSJim Ingham   return true;
14014f465cffSJim Ingham }
14024f465cffSJim Ingham 
1403b9c1b51eSKate Stone bool SBThread::GetDescription(SBStream &description) const {
14046a9767c7SJim Ingham     return GetDescription(description, false);
14056a9767c7SJim Ingham }
14066a9767c7SJim Ingham 
14076a9767c7SJim Ingham bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
1408da7bc7d0SGreg Clayton   Stream &strm = description.ref();
1409da7bc7d0SGreg Clayton 
1410b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1411b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1412b2e7d28eSJim Ingham 
1413b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1414b9c1b51eSKate Stone     exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm,
14156a9767c7SJim Ingham                                                     LLDB_INVALID_THREAD_ID,
14166a9767c7SJim Ingham                                                     stop_format);
1417b9c1b51eSKate Stone     // strm.Printf("SBThread: tid = 0x%4.4" PRIx64,
1418b9c1b51eSKate Stone     // exe_ctx.GetThreadPtr()->GetID());
1419b9c1b51eSKate Stone   } else
1420da7bc7d0SGreg Clayton     strm.PutCString("No value");
1421ceb6b139SCaroline Tice 
1422ceb6b139SCaroline Tice   return true;
1423ceb6b139SCaroline Tice }
14245dd4916fSJason Molenda 
1425b9c1b51eSKate Stone SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
14265dd4916fSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1427bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1428bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
14295dd4916fSJason Molenda   SBThread sb_origin_thread;
14305dd4916fSJason Molenda 
1431b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
14325dd4916fSJason Molenda     Process::StopLocker stop_locker;
1433b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
14347a2f7904SJason Molenda       ThreadSP real_thread(exe_ctx.GetThreadSP());
1435b9c1b51eSKate Stone       if (real_thread) {
14365dd4916fSJason Molenda         ConstString type_const(type);
14377a2f7904SJason Molenda         Process *process = exe_ctx.GetProcessPtr();
1438b9c1b51eSKate Stone         if (process) {
14397a2f7904SJason Molenda           SystemRuntime *runtime = process->GetSystemRuntime();
1440b9c1b51eSKate Stone           if (runtime) {
1441b9c1b51eSKate Stone             ThreadSP new_thread_sp(
1442b9c1b51eSKate Stone                 runtime->GetExtendedBacktraceThread(real_thread, type_const));
1443b9c1b51eSKate Stone             if (new_thread_sp) {
1444b9c1b51eSKate Stone               // Save this in the Process' ExtendedThreadList so a strong
144505097246SAdrian Prantl               // pointer retains the object.
14467a2f7904SJason Molenda               process->GetExtendedThreadList().AddThread(new_thread_sp);
14477a2f7904SJason Molenda               sb_origin_thread.SetThread(new_thread_sp);
1448b9c1b51eSKate Stone               if (log) {
1449a6e9130dSJason Molenda                 const char *queue_name = new_thread_sp->GetQueueName();
1450a6e9130dSJason Molenda                 if (queue_name == NULL)
1451a6e9130dSJason Molenda                   queue_name = "";
1452b9c1b51eSKate Stone                 log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => new "
1453b9c1b51eSKate Stone                             "extended Thread "
1454b9c1b51eSKate Stone                             "created (%p) with queue_id 0x%" PRIx64
1455b9c1b51eSKate Stone                             " queue name '%s'",
1456324a1036SSaleem Abdulrasool                             static_cast<void *>(exe_ctx.GetThreadPtr()),
1457324a1036SSaleem Abdulrasool                             static_cast<void *>(new_thread_sp.get()),
1458b9c1b51eSKate Stone                             new_thread_sp->GetQueueID(), queue_name);
1459a6e9130dSJason Molenda               }
1460a6e9130dSJason Molenda             }
14617a2f7904SJason Molenda           }
14625dd4916fSJason Molenda         }
14635dd4916fSJason Molenda       }
1464b9c1b51eSKate Stone     } else {
14655dd4916fSJason Molenda       if (log)
1466b9c1b51eSKate Stone         log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => error: "
1467b9c1b51eSKate Stone                     "process is running",
1468324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
14695dd4916fSJason Molenda     }
14705dd4916fSJason Molenda   }
14715dd4916fSJason Molenda 
1472a6682a41SJonas Devlieghere   if (log && !sb_origin_thread.IsValid())
1473b9c1b51eSKate Stone     log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a "
1474b9c1b51eSKate Stone                 "Valid thread",
1475324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()));
14765dd4916fSJason Molenda   return sb_origin_thread;
14775dd4916fSJason Molenda }
14788ee9cb58SJason Molenda 
1479b9c1b51eSKate Stone uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
14808ee9cb58SJason Molenda   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
14818ee9cb58SJason Molenda   if (thread_sp)
14828ee9cb58SJason Molenda     return thread_sp->GetExtendedBacktraceOriginatingIndexID();
14838ee9cb58SJason Molenda   return LLDB_INVALID_INDEX32;
14848ee9cb58SJason Molenda }
1485b4892cd2SJason Molenda 
1486e60bc53bSKuba Mracek SBValue SBThread::GetCurrentException() {
1487e60bc53bSKuba Mracek   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1488e60bc53bSKuba Mracek   if (!thread_sp) return SBValue();
1489e60bc53bSKuba Mracek 
1490e60bc53bSKuba Mracek   return SBValue(thread_sp->GetCurrentException());
1491e60bc53bSKuba Mracek }
1492e60bc53bSKuba Mracek 
1493e60bc53bSKuba Mracek SBThread SBThread::GetCurrentExceptionBacktrace() {
1494e60bc53bSKuba Mracek   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1495e60bc53bSKuba Mracek   if (!thread_sp) return SBThread();
1496e60bc53bSKuba Mracek 
1497e60bc53bSKuba Mracek   return SBThread(thread_sp->GetCurrentExceptionBacktrace());
1498c9e1190aSKuba Mracek }
1499e60bc53bSKuba Mracek 
1500b9c1b51eSKate Stone bool SBThread::SafeToCallFunctions() {
1501b4892cd2SJason Molenda   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1502b4892cd2SJason Molenda   if (thread_sp)
1503b4892cd2SJason Molenda     return thread_sp->SafeToCallFunctions();
1504b4892cd2SJason Molenda   return true;
1505b4892cd2SJason Molenda }
15062bdbfd50SJim Ingham 
1507b9c1b51eSKate Stone lldb_private::Thread *SBThread::operator->() {
15082bdbfd50SJim Ingham   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
15092bdbfd50SJim Ingham   if (thread_sp)
15102bdbfd50SJim Ingham     return thread_sp.get();
15112bdbfd50SJim Ingham   else
15122bdbfd50SJim Ingham     return NULL;
15132bdbfd50SJim Ingham }
15142bdbfd50SJim Ingham 
1515b9c1b51eSKate Stone lldb_private::Thread *SBThread::get() {
15162bdbfd50SJim Ingham   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
15172bdbfd50SJim Ingham   if (thread_sp)
15182bdbfd50SJim Ingham     return thread_sp.get();
15192bdbfd50SJim Ingham   else
15202bdbfd50SJim Ingham     return NULL;
15212bdbfd50SJim Ingham }
1522