130fdc8d8SChris Lattner //===-- SBThread.cpp --------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner 
94c5de699SEli Friedman #include "lldb/API/SBThread.h"
10*bd4bf82aSJonas Devlieghere #include "Utils.h"
11*bd4bf82aSJonas Devlieghere #include "lldb/API/SBAddress.h"
12*bd4bf82aSJonas Devlieghere #include "lldb/API/SBDebugger.h"
13*bd4bf82aSJonas Devlieghere #include "lldb/API/SBEvent.h"
1430fdc8d8SChris Lattner #include "lldb/API/SBFileSpec.h"
15*bd4bf82aSJonas Devlieghere #include "lldb/API/SBFrame.h"
16*bd4bf82aSJonas Devlieghere #include "lldb/API/SBProcess.h"
17dde9cff3SCaroline Tice #include "lldb/API/SBStream.h"
18b9c1b51eSKate Stone #include "lldb/API/SBSymbolContext.h"
19*bd4bf82aSJonas Devlieghere #include "lldb/API/SBThreadCollection.h"
20*bd4bf82aSJonas Devlieghere #include "lldb/API/SBThreadPlan.h"
21*bd4bf82aSJonas Devlieghere #include "lldb/API/SBValue.h"
224e78f606SGreg Clayton #include "lldb/Breakpoint/BreakpointLocation.h"
236611103cSGreg Clayton #include "lldb/Core/Debugger.h"
2430fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h"
25a78bd7ffSZachary Turner #include "lldb/Core/ValueObject.h"
266611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
2793749ab3SZachary Turner #include "lldb/Symbol/CompileUnit.h"
28b9c1b51eSKate Stone #include "lldb/Symbol/SymbolContext.h"
2930fdc8d8SChris Lattner #include "lldb/Target/Process.h"
30b9ffa98cSJason Molenda #include "lldb/Target/Queue.h"
31f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h"
32b9c1b51eSKate Stone #include "lldb/Target/SystemRuntime.h"
3330fdc8d8SChris Lattner #include "lldb/Target/Target.h"
34b9c1b51eSKate Stone #include "lldb/Target/Thread.h"
3530fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h"
36b9c1b51eSKate Stone #include "lldb/Target/ThreadPlanStepInRange.h"
3730fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h"
3830fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h"
3930fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h"
40b9c1b51eSKate Stone #include "lldb/Target/UnixSignals.h"
41d821c997SPavel Labath #include "lldb/Utility/State.h"
42bf9a7730SZachary Turner #include "lldb/Utility/Stream.h"
43f2a8bccfSPavel Labath #include "lldb/Utility/StructuredData.h"
445bfee5f1SAbhishek Aggarwal #include "lldb/lldb-enumerations.h"
4530fdc8d8SChris Lattner 
46796ac80bSJonas Devlieghere #include <memory>
47796ac80bSJonas Devlieghere 
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 
63*bd4bf82aSJonas Devlieghere SBThread::SBThread(const SBThread &rhs) : m_opaque_sp() {
64*bd4bf82aSJonas Devlieghere   m_opaque_sp = clone(rhs.m_opaque_sp);
65*bd4bf82aSJonas Devlieghere }
6630fdc8d8SChris Lattner 
6730fdc8d8SChris Lattner //----------------------------------------------------------------------
68cfd1acedSGreg Clayton // Assignment operator
69cfd1acedSGreg Clayton //----------------------------------------------------------------------
70cfd1acedSGreg Clayton 
71b9c1b51eSKate Stone const lldb::SBThread &SBThread::operator=(const SBThread &rhs) {
72cfd1acedSGreg Clayton   if (this != &rhs)
73*bd4bf82aSJonas Devlieghere     m_opaque_sp = clone(rhs.m_opaque_sp);
74cfd1acedSGreg Clayton   return *this;
75cfd1acedSGreg Clayton }
76cfd1acedSGreg Clayton 
77cfd1acedSGreg Clayton //----------------------------------------------------------------------
7830fdc8d8SChris Lattner // Destructor
7930fdc8d8SChris Lattner //----------------------------------------------------------------------
80b9c1b51eSKate Stone SBThread::~SBThread() {}
8130fdc8d8SChris Lattner 
82b9c1b51eSKate Stone lldb::SBQueue SBThread::GetQueue() const {
83b9ffa98cSJason Molenda   SBQueue sb_queue;
84b9ffa98cSJason Molenda   QueueSP queue_sp;
85bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
86bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
87b9ffa98cSJason Molenda 
88b9ffa98cSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
89b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
90b9ffa98cSJason Molenda     Process::StopLocker stop_locker;
91b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
92b9ffa98cSJason Molenda       queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
93b9c1b51eSKate Stone       if (queue_sp) {
94b9ffa98cSJason Molenda         sb_queue.SetQueue(queue_sp);
95b9ffa98cSJason Molenda       }
96b9c1b51eSKate Stone     } else {
97b9ffa98cSJason Molenda       if (log)
98358cf1eaSGreg Clayton         log->Printf("SBThread(%p)::GetQueue() => error: process is running",
99b9ffa98cSJason Molenda                     static_cast<void *>(exe_ctx.GetThreadPtr()));
100b9ffa98cSJason Molenda     }
101b9ffa98cSJason Molenda   }
102b9ffa98cSJason Molenda 
103b9ffa98cSJason Molenda   if (log)
104358cf1eaSGreg Clayton     log->Printf("SBThread(%p)::GetQueue () => SBQueue(%p)",
105b9c1b51eSKate Stone                 static_cast<void *>(exe_ctx.GetThreadPtr()),
106b9c1b51eSKate Stone                 static_cast<void *>(queue_sp.get()));
107b9ffa98cSJason Molenda 
108b9ffa98cSJason Molenda   return sb_queue;
109b9ffa98cSJason Molenda }
110b9ffa98cSJason Molenda 
111b9c1b51eSKate Stone bool SBThread::IsValid() const {
112bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
113bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1147fa7dc36SJim Ingham 
1157fa7dc36SJim Ingham   Target *target = exe_ctx.GetTargetPtr();
1167fa7dc36SJim Ingham   Process *process = exe_ctx.GetProcessPtr();
117b9c1b51eSKate Stone   if (target && process) {
1187fa7dc36SJim Ingham     Process::StopLocker stop_locker;
1197fa7dc36SJim Ingham     if (stop_locker.TryLock(&process->GetRunLock()))
1207fdf9ef1SGreg Clayton       return m_opaque_sp->GetThreadSP().get() != NULL;
12130fdc8d8SChris Lattner   }
1227fa7dc36SJim Ingham   // Without a valid target & process, this thread can't be valid.
1237fa7dc36SJim Ingham   return false;
1247fa7dc36SJim Ingham }
12530fdc8d8SChris Lattner 
126b9c1b51eSKate Stone void SBThread::Clear() { m_opaque_sp->Clear(); }
12748e42549SGreg Clayton 
128b9c1b51eSKate Stone StopReason SBThread::GetStopReason() {
1295160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
130ceb6b139SCaroline Tice 
131ceb6b139SCaroline Tice   StopReason reason = eStopReasonInvalid;
132bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
133bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1344fc6cb9cSJim Ingham 
135b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1367fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
137b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
13897d5cf05SGreg Clayton       return exe_ctx.GetThreadPtr()->GetStopReason();
139b9c1b51eSKate Stone     } else {
140c9858e4dSGreg Clayton       if (log)
141b9c1b51eSKate Stone         log->Printf(
142b9c1b51eSKate Stone             "SBThread(%p)::GetStopReason() => error: process is running",
143324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
144c9858e4dSGreg Clayton     }
1457fdf9ef1SGreg Clayton   }
146ceb6b139SCaroline Tice 
147ceb6b139SCaroline Tice   if (log)
148324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetStopReason () => %s",
149324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
150750cd175SCaroline Tice                 Thread::StopReasonAsCString(reason));
151ceb6b139SCaroline Tice 
152ceb6b139SCaroline Tice   return reason;
15330fdc8d8SChris Lattner }
15430fdc8d8SChris Lattner 
155b9c1b51eSKate Stone size_t SBThread::GetStopReasonDataCount() {
156bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
157bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1584fc6cb9cSJim Ingham 
159b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1607fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
161b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1621ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
163b9c1b51eSKate Stone       if (stop_info_sp) {
1644e78f606SGreg Clayton         StopReason reason = stop_info_sp->GetStopReason();
165b9c1b51eSKate Stone         switch (reason) {
1664e78f606SGreg Clayton         case eStopReasonInvalid:
1674e78f606SGreg Clayton         case eStopReasonNone:
1684e78f606SGreg Clayton         case eStopReasonTrace:
16990ba8115SGreg Clayton         case eStopReasonExec:
1704e78f606SGreg Clayton         case eStopReasonPlanComplete:
171f85defaeSAndrew Kaylor         case eStopReasonThreadExiting:
172afdf842bSKuba Brecka         case eStopReasonInstrumentation:
1734e78f606SGreg Clayton           // There is no data for these stop reasons.
1744e78f606SGreg Clayton           return 0;
1754e78f606SGreg Clayton 
176b9c1b51eSKate Stone         case eStopReasonBreakpoint: {
1774e78f606SGreg Clayton           break_id_t site_id = stop_info_sp->GetValue();
178b9c1b51eSKate Stone           lldb::BreakpointSiteSP bp_site_sp(
179b9c1b51eSKate Stone               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
180b9c1b51eSKate Stone                   site_id));
1814e78f606SGreg Clayton           if (bp_site_sp)
1824e78f606SGreg Clayton             return bp_site_sp->GetNumberOfOwners() * 2;
1834e78f606SGreg Clayton           else
1844e78f606SGreg Clayton             return 0; // Breakpoint must have cleared itself...
185b9c1b51eSKate Stone         } break;
1864e78f606SGreg Clayton 
1874e78f606SGreg Clayton         case eStopReasonWatchpoint:
188290fa41bSJohnny Chen           return 1;
1894e78f606SGreg Clayton 
1904e78f606SGreg Clayton         case eStopReasonSignal:
1914e78f606SGreg Clayton           return 1;
1924e78f606SGreg Clayton 
1934e78f606SGreg Clayton         case eStopReasonException:
1944e78f606SGreg Clayton           return 1;
1954e78f606SGreg Clayton         }
1964e78f606SGreg Clayton       }
197b9c1b51eSKate Stone     } else {
1985160ce5cSGreg Clayton       Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
199c9858e4dSGreg Clayton       if (log)
200b9c1b51eSKate Stone         log->Printf("SBThread(%p)::GetStopReasonDataCount() => error: process "
201b9c1b51eSKate Stone                     "is running",
202324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
203c9858e4dSGreg Clayton     }
2047fdf9ef1SGreg Clayton   }
2054e78f606SGreg Clayton   return 0;
2064e78f606SGreg Clayton }
2074e78f606SGreg Clayton 
208b9c1b51eSKate Stone uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
209bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
210bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
2114fc6cb9cSJim Ingham 
212b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
2137fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
214b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
2151ac04c30SGreg Clayton       Thread *thread = exe_ctx.GetThreadPtr();
2161ac04c30SGreg Clayton       StopInfoSP stop_info_sp = thread->GetStopInfo();
217b9c1b51eSKate Stone       if (stop_info_sp) {
2184e78f606SGreg Clayton         StopReason reason = stop_info_sp->GetStopReason();
219b9c1b51eSKate Stone         switch (reason) {
2204e78f606SGreg Clayton         case eStopReasonInvalid:
2214e78f606SGreg Clayton         case eStopReasonNone:
2224e78f606SGreg Clayton         case eStopReasonTrace:
22390ba8115SGreg Clayton         case eStopReasonExec:
2244e78f606SGreg Clayton         case eStopReasonPlanComplete:
225f85defaeSAndrew Kaylor         case eStopReasonThreadExiting:
226afdf842bSKuba Brecka         case eStopReasonInstrumentation:
2274e78f606SGreg Clayton           // There is no data for these stop reasons.
2284e78f606SGreg Clayton           return 0;
2294e78f606SGreg Clayton 
230b9c1b51eSKate Stone         case eStopReasonBreakpoint: {
2314e78f606SGreg Clayton           break_id_t site_id = stop_info_sp->GetValue();
232b9c1b51eSKate Stone           lldb::BreakpointSiteSP bp_site_sp(
233b9c1b51eSKate Stone               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
234b9c1b51eSKate Stone                   site_id));
235b9c1b51eSKate Stone           if (bp_site_sp) {
2364e78f606SGreg Clayton             uint32_t bp_index = idx / 2;
237b9c1b51eSKate Stone             BreakpointLocationSP bp_loc_sp(
238b9c1b51eSKate Stone                 bp_site_sp->GetOwnerAtIndex(bp_index));
239b9c1b51eSKate Stone             if (bp_loc_sp) {
240b9c1b51eSKate Stone               if (idx & 1) {
2414e78f606SGreg Clayton                 // Odd idx, return the breakpoint location ID
2424e78f606SGreg Clayton                 return bp_loc_sp->GetID();
243b9c1b51eSKate Stone               } else {
2444e78f606SGreg Clayton                 // Even idx, return the breakpoint ID
2454e78f606SGreg Clayton                 return bp_loc_sp->GetBreakpoint().GetID();
2464e78f606SGreg Clayton               }
2474e78f606SGreg Clayton             }
2484e78f606SGreg Clayton           }
2494e78f606SGreg Clayton           return LLDB_INVALID_BREAK_ID;
250b9c1b51eSKate Stone         } break;
2514e78f606SGreg Clayton 
2524e78f606SGreg Clayton         case eStopReasonWatchpoint:
253290fa41bSJohnny Chen           return stop_info_sp->GetValue();
2544e78f606SGreg Clayton 
2554e78f606SGreg Clayton         case eStopReasonSignal:
2564e78f606SGreg Clayton           return stop_info_sp->GetValue();
2574e78f606SGreg Clayton 
2584e78f606SGreg Clayton         case eStopReasonException:
2594e78f606SGreg Clayton           return stop_info_sp->GetValue();
2604e78f606SGreg Clayton         }
2614e78f606SGreg Clayton       }
262b9c1b51eSKate Stone     } else {
2635160ce5cSGreg Clayton       Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
264c9858e4dSGreg Clayton       if (log)
265b9c1b51eSKate Stone         log->Printf("SBThread(%p)::GetStopReasonDataAtIndex() => error: "
266b9c1b51eSKate Stone                     "process is running",
267324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
268c9858e4dSGreg Clayton     }
2697fdf9ef1SGreg Clayton   }
2704e78f606SGreg Clayton   return 0;
2714e78f606SGreg Clayton }
2724e78f606SGreg Clayton 
273b9c1b51eSKate Stone bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) {
274afdf842bSKuba Brecka   Stream &strm = stream.ref();
275afdf842bSKuba Brecka 
276b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
277b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
278b2e7d28eSJim Ingham 
279afdf842bSKuba Brecka   if (!exe_ctx.HasThreadScope())
280afdf842bSKuba Brecka     return false;
281afdf842bSKuba Brecka 
282afdf842bSKuba Brecka   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
283afdf842bSKuba Brecka   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
284afdf842bSKuba Brecka   if (!info)
285afdf842bSKuba Brecka     return false;
286afdf842bSKuba Brecka 
287afdf842bSKuba Brecka   info->Dump(strm);
288afdf842bSKuba Brecka 
289afdf842bSKuba Brecka   return true;
290afdf842bSKuba Brecka }
291afdf842bSKuba Brecka 
2926a831436SKuba Brecka SBThreadCollection
293b9c1b51eSKate Stone SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
2946a831436SKuba Brecka   ThreadCollectionSP threads;
295796ac80bSJonas Devlieghere   threads = std::make_shared<ThreadCollection>();
2966a831436SKuba Brecka 
297b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
298b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
299b2e7d28eSJim Ingham 
3006a831436SKuba Brecka   if (!exe_ctx.HasThreadScope())
3011aad8fb7SKuba Brecka     return threads;
3026a831436SKuba Brecka 
3036a831436SKuba Brecka   ProcessSP process_sp = exe_ctx.GetProcessSP();
3046a831436SKuba Brecka 
3056a831436SKuba Brecka   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
3066a831436SKuba Brecka   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
3076a831436SKuba Brecka   if (!info)
3086a831436SKuba Brecka     return threads;
3096a831436SKuba Brecka 
310b9c1b51eSKate Stone   return process_sp->GetInstrumentationRuntime(type)
311b9c1b51eSKate Stone       ->GetBacktracesFromExtendedStopInfo(info);
3126a831436SKuba Brecka }
3136a831436SKuba Brecka 
314b9c1b51eSKate Stone size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
3155160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
316ceb6b139SCaroline Tice 
317bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
318bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3194fc6cb9cSJim Ingham 
320b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
3217fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
322b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
3237fdf9ef1SGreg Clayton 
3241ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
325b9c1b51eSKate Stone       if (stop_info_sp) {
326b15bfc75SJim Ingham         const char *stop_desc = stop_info_sp->GetDescription();
327b9c1b51eSKate Stone         if (stop_desc) {
328ceb6b139SCaroline Tice           if (log)
329b9c1b51eSKate Stone             log->Printf(
330b9c1b51eSKate Stone                 "SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
331b9c1b51eSKate Stone                 static_cast<void *>(exe_ctx.GetThreadPtr()), stop_desc);
33230fdc8d8SChris Lattner           if (dst)
33330fdc8d8SChris Lattner             return ::snprintf(dst, dst_len, "%s", stop_desc);
334b9c1b51eSKate Stone           else {
335b9c1b51eSKate Stone             // NULL dst passed in, return the length needed to contain the
336b9c1b51eSKate Stone             // description
33730fdc8d8SChris Lattner             return ::strlen(stop_desc) + 1; // Include the NULL byte for size
33830fdc8d8SChris Lattner           }
339b9c1b51eSKate Stone         } else {
34030fdc8d8SChris Lattner           size_t stop_desc_len = 0;
341b9c1b51eSKate Stone           switch (stop_info_sp->GetStopReason()) {
34230fdc8d8SChris Lattner           case eStopReasonTrace:
343b9c1b51eSKate Stone           case eStopReasonPlanComplete: {
34430fdc8d8SChris Lattner             static char trace_desc[] = "step";
34530fdc8d8SChris Lattner             stop_desc = trace_desc;
346b9c1b51eSKate Stone             stop_desc_len =
347b9c1b51eSKate Stone                 sizeof(trace_desc); // Include the NULL byte for size
348b9c1b51eSKate Stone           } break;
34930fdc8d8SChris Lattner 
350b9c1b51eSKate Stone           case eStopReasonBreakpoint: {
35130fdc8d8SChris Lattner             static char bp_desc[] = "breakpoint hit";
35230fdc8d8SChris Lattner             stop_desc = bp_desc;
35330fdc8d8SChris Lattner             stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
354b9c1b51eSKate Stone           } break;
35530fdc8d8SChris Lattner 
356b9c1b51eSKate Stone           case eStopReasonWatchpoint: {
35730fdc8d8SChris Lattner             static char wp_desc[] = "watchpoint hit";
35830fdc8d8SChris Lattner             stop_desc = wp_desc;
35930fdc8d8SChris Lattner             stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
360b9c1b51eSKate Stone           } break;
36130fdc8d8SChris Lattner 
362b9c1b51eSKate Stone           case eStopReasonSignal: {
363b9c1b51eSKate Stone             stop_desc =
364b9c1b51eSKate Stone                 exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString(
365b9c1b51eSKate Stone                     stop_info_sp->GetValue());
366b9c1b51eSKate Stone             if (stop_desc == NULL || stop_desc[0] == '\0') {
36730fdc8d8SChris Lattner               static char signal_desc[] = "signal";
36830fdc8d8SChris Lattner               stop_desc = signal_desc;
369b9c1b51eSKate Stone               stop_desc_len =
370b9c1b51eSKate Stone                   sizeof(signal_desc); // Include the NULL byte for size
37130fdc8d8SChris Lattner             }
372b9c1b51eSKate Stone           } break;
37330fdc8d8SChris Lattner 
374b9c1b51eSKate Stone           case eStopReasonException: {
37530fdc8d8SChris Lattner             char exc_desc[] = "exception";
37630fdc8d8SChris Lattner             stop_desc = exc_desc;
37730fdc8d8SChris Lattner             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
378b9c1b51eSKate Stone           } break;
379c982c768SGreg Clayton 
380b9c1b51eSKate Stone           case eStopReasonExec: {
38190ba8115SGreg Clayton             char exc_desc[] = "exec";
38290ba8115SGreg Clayton             stop_desc = exc_desc;
38390ba8115SGreg Clayton             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
384b9c1b51eSKate Stone           } break;
38590ba8115SGreg Clayton 
386b9c1b51eSKate Stone           case eStopReasonThreadExiting: {
387f85defaeSAndrew Kaylor             char limbo_desc[] = "thread exiting";
388f85defaeSAndrew Kaylor             stop_desc = limbo_desc;
389f85defaeSAndrew Kaylor             stop_desc_len = sizeof(limbo_desc);
390b9c1b51eSKate Stone           } break;
391c982c768SGreg Clayton           default:
392c982c768SGreg Clayton             break;
39330fdc8d8SChris Lattner           }
39430fdc8d8SChris Lattner 
395b9c1b51eSKate Stone           if (stop_desc && stop_desc[0]) {
396ceb6b139SCaroline Tice             if (log)
397b9c1b51eSKate Stone               log->Printf(
398b9c1b51eSKate Stone                   "SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
399b9c1b51eSKate Stone                   static_cast<void *>(exe_ctx.GetThreadPtr()), stop_desc);
400ceb6b139SCaroline Tice 
40130fdc8d8SChris Lattner             if (dst)
402b9c1b51eSKate Stone               return ::snprintf(dst, dst_len, "%s", stop_desc) +
403b9c1b51eSKate Stone                      1; // Include the NULL byte
40430fdc8d8SChris Lattner 
40530fdc8d8SChris Lattner             if (stop_desc_len == 0)
40630fdc8d8SChris Lattner               stop_desc_len = ::strlen(stop_desc) + 1; // Include the NULL byte
40730fdc8d8SChris Lattner 
40830fdc8d8SChris Lattner             return stop_desc_len;
40930fdc8d8SChris Lattner           }
41030fdc8d8SChris Lattner         }
41130fdc8d8SChris Lattner       }
412b9c1b51eSKate Stone     } else {
4135160ce5cSGreg Clayton       Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
414c9858e4dSGreg Clayton       if (log)
415b9c1b51eSKate Stone         log->Printf(
416b9c1b51eSKate Stone             "SBThread(%p)::GetStopDescription() => error: process is running",
417324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
418c9858e4dSGreg Clayton     }
4197fdf9ef1SGreg Clayton   }
42030fdc8d8SChris Lattner   if (dst)
42130fdc8d8SChris Lattner     *dst = 0;
42230fdc8d8SChris Lattner   return 0;
42330fdc8d8SChris Lattner }
42430fdc8d8SChris Lattner 
425b9c1b51eSKate Stone SBValue SBThread::GetStopReturnValue() {
4265160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
42773ca05a2SJim Ingham   ValueObjectSP return_valobj_sp;
428bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
429bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4304fc6cb9cSJim Ingham 
431b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4327fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
433b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4341ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
435b9c1b51eSKate Stone       if (stop_info_sp) {
43673ca05a2SJim Ingham         return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp);
43773ca05a2SJim Ingham       }
438b9c1b51eSKate Stone     } else {
439c9858e4dSGreg Clayton       if (log)
440b9c1b51eSKate Stone         log->Printf(
441b9c1b51eSKate Stone             "SBThread(%p)::GetStopReturnValue() => error: process is running",
442324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
443c9858e4dSGreg Clayton     }
4447fdf9ef1SGreg Clayton   }
44573ca05a2SJim Ingham 
44673ca05a2SJim Ingham   if (log)
447324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetStopReturnValue () => %s",
448324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
449b9c1b51eSKate Stone                 return_valobj_sp.get() ? return_valobj_sp->GetValueAsCString()
45073ca05a2SJim Ingham                                        : "<no return value>");
45173ca05a2SJim Ingham 
45273ca05a2SJim Ingham   return SBValue(return_valobj_sp);
45373ca05a2SJim Ingham }
45473ca05a2SJim Ingham 
455b9c1b51eSKate Stone void SBThread::SetThread(const ThreadSP &lldb_object_sp) {
4567fdf9ef1SGreg Clayton   m_opaque_sp->SetThreadSP(lldb_object_sp);
45730fdc8d8SChris Lattner }
45830fdc8d8SChris Lattner 
459b9c1b51eSKate Stone lldb::tid_t SBThread::GetThreadID() const {
4607fdf9ef1SGreg Clayton   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
46117a6ad05SGreg Clayton   if (thread_sp)
4621ac04c30SGreg Clayton     return thread_sp->GetID();
4631ac04c30SGreg Clayton   return LLDB_INVALID_THREAD_ID;
46430fdc8d8SChris Lattner }
46530fdc8d8SChris Lattner 
466b9c1b51eSKate Stone uint32_t SBThread::GetIndexID() const {
4677fdf9ef1SGreg Clayton   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
46817a6ad05SGreg Clayton   if (thread_sp)
46917a6ad05SGreg Clayton     return thread_sp->GetIndexID();
47030fdc8d8SChris Lattner   return LLDB_INVALID_INDEX32;
47130fdc8d8SChris Lattner }
4721ac04c30SGreg Clayton 
473b9c1b51eSKate Stone const char *SBThread::GetName() const {
4745160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
4754838131bSGreg Clayton   const char *name = NULL;
476bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
477bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4784fc6cb9cSJim Ingham 
479b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4807fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
481b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4821ac04c30SGreg Clayton       name = exe_ctx.GetThreadPtr()->GetName();
483b9c1b51eSKate Stone     } else {
484c9858e4dSGreg Clayton       if (log)
485324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::GetName() => error: process is running",
486324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
487c9858e4dSGreg Clayton     }
4887fdf9ef1SGreg Clayton   }
489ceb6b139SCaroline Tice 
490ceb6b139SCaroline Tice   if (log)
491324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetName () => %s",
492324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
493324a1036SSaleem Abdulrasool                 name ? name : "NULL");
494ceb6b139SCaroline Tice 
4954838131bSGreg Clayton   return name;
49630fdc8d8SChris Lattner }
49730fdc8d8SChris Lattner 
498b9c1b51eSKate Stone const char *SBThread::GetQueueName() const {
4994838131bSGreg Clayton   const char *name = NULL;
500bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
501bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
5024fc6cb9cSJim Ingham 
5035160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
504b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
5057fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
506b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
5071ac04c30SGreg Clayton       name = exe_ctx.GetThreadPtr()->GetQueueName();
508b9c1b51eSKate Stone     } else {
509c9858e4dSGreg Clayton       if (log)
510324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::GetQueueName() => error: process is running",
511324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
512c9858e4dSGreg Clayton     }
5137fdf9ef1SGreg Clayton   }
514ceb6b139SCaroline Tice 
515ceb6b139SCaroline Tice   if (log)
516324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetQueueName () => %s",
517324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
518324a1036SSaleem Abdulrasool                 name ? name : "NULL");
519ceb6b139SCaroline Tice 
5204838131bSGreg Clayton   return name;
52130fdc8d8SChris Lattner }
52230fdc8d8SChris Lattner 
523b9c1b51eSKate Stone lldb::queue_id_t SBThread::GetQueueID() const {
5244fdb5863SJason Molenda   queue_id_t id = LLDB_INVALID_QUEUE_ID;
525bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
526bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
5274fdb5863SJason Molenda 
5284fdb5863SJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
529b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
5304fdb5863SJason Molenda     Process::StopLocker stop_locker;
531b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
5324fdb5863SJason Molenda       id = exe_ctx.GetThreadPtr()->GetQueueID();
533b9c1b51eSKate Stone     } else {
5344fdb5863SJason Molenda       if (log)
535324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::GetQueueID() => error: process is running",
536324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
5374fdb5863SJason Molenda     }
5384fdb5863SJason Molenda   }
5394fdb5863SJason Molenda 
5404fdb5863SJason Molenda   if (log)
541324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetQueueID () => 0x%" PRIx64,
542324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), id);
5434fdb5863SJason Molenda 
5444fdb5863SJason Molenda   return id;
5454fdb5863SJason Molenda }
5464fdb5863SJason Molenda 
547b9c1b51eSKate Stone bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
548705b1809SJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
549705b1809SJason Molenda   bool success = false;
550bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
551bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
552705b1809SJason Molenda 
553b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
554705b1809SJason Molenda     Process::StopLocker stop_locker;
555b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
556705b1809SJason Molenda       Thread *thread = exe_ctx.GetThreadPtr();
557705b1809SJason Molenda       StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
558b9c1b51eSKate Stone       if (info_root_sp) {
559b9c1b51eSKate Stone         StructuredData::ObjectSP node =
560b9c1b51eSKate Stone             info_root_sp->GetObjectForDotSeparatedPath(path);
561b9c1b51eSKate Stone         if (node) {
5625bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeString) {
5632833321fSZachary Turner             strm.Printf("%s", node->GetAsString()->GetValue().str().c_str());
564705b1809SJason Molenda             success = true;
565705b1809SJason Molenda           }
5665bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeInteger) {
567705b1809SJason Molenda             strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue());
568705b1809SJason Molenda             success = true;
569705b1809SJason Molenda           }
5705bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeFloat) {
571705b1809SJason Molenda             strm.Printf("0x%f", node->GetAsFloat()->GetValue());
572705b1809SJason Molenda             success = true;
573705b1809SJason Molenda           }
5745bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeBoolean) {
575a6682a41SJonas Devlieghere             if (node->GetAsBoolean()->GetValue())
576705b1809SJason Molenda               strm.Printf("true");
577705b1809SJason Molenda             else
578705b1809SJason Molenda               strm.Printf("false");
579705b1809SJason Molenda             success = true;
580705b1809SJason Molenda           }
5815bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeNull) {
582705b1809SJason Molenda             strm.Printf("null");
583705b1809SJason Molenda             success = true;
584705b1809SJason Molenda           }
585705b1809SJason Molenda         }
586705b1809SJason Molenda       }
587b9c1b51eSKate Stone     } else {
588705b1809SJason Molenda       if (log)
589b9c1b51eSKate Stone         log->Printf("SBThread(%p)::GetInfoItemByPathAsString() => error: "
590b9c1b51eSKate Stone                     "process is running",
591705b1809SJason Molenda                     static_cast<void *>(exe_ctx.GetThreadPtr()));
592705b1809SJason Molenda     }
593705b1809SJason Molenda   }
594705b1809SJason Molenda 
595705b1809SJason Molenda   if (log)
596753e13c0SJason Molenda     log->Printf("SBThread(%p)::GetInfoItemByPathAsString (\"%s\") => \"%s\"",
597753e13c0SJason Molenda                 static_cast<void *>(exe_ctx.GetThreadPtr()), path, strm.GetData());
598705b1809SJason Molenda 
599705b1809SJason Molenda   return success;
600705b1809SJason Molenda }
601705b1809SJason Molenda 
602b9c1b51eSKate Stone SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
603b9c1b51eSKate Stone                                 ThreadPlan *new_plan) {
60464e7ead1SJim Ingham   SBError sb_error;
60564e7ead1SJim Ingham 
60664e7ead1SJim Ingham   Process *process = exe_ctx.GetProcessPtr();
607b9c1b51eSKate Stone   if (!process) {
60864e7ead1SJim Ingham     sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
60964e7ead1SJim Ingham     return sb_error;
61064e7ead1SJim Ingham   }
61164e7ead1SJim Ingham 
61264e7ead1SJim Ingham   Thread *thread = exe_ctx.GetThreadPtr();
613b9c1b51eSKate Stone   if (!thread) {
61464e7ead1SJim Ingham     sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
61564e7ead1SJim Ingham     return sb_error;
61664e7ead1SJim Ingham   }
61764e7ead1SJim Ingham 
618b9c1b51eSKate Stone   // User level plans should be Master Plans so they can be interrupted, other
61905097246SAdrian Prantl   // plans executed, and then a "continue" will resume the plan.
620b9c1b51eSKate Stone   if (new_plan != NULL) {
62164e7ead1SJim Ingham     new_plan->SetIsMasterPlan(true);
62264e7ead1SJim Ingham     new_plan->SetOkayToDiscard(false);
62364e7ead1SJim Ingham   }
62464e7ead1SJim Ingham 
62564e7ead1SJim Ingham   // Why do we need to set the current thread by ID here???
62664e7ead1SJim Ingham   process->GetThreadList().SetSelectedThreadByID(thread->GetID());
62764e7ead1SJim Ingham 
628dc6224e0SGreg Clayton   if (process->GetTarget().GetDebugger().GetAsyncExecution())
629dc6224e0SGreg Clayton     sb_error.ref() = process->Resume();
630dc6224e0SGreg Clayton   else
631dc6224e0SGreg Clayton     sb_error.ref() = process->ResumeSynchronous(NULL);
63264e7ead1SJim Ingham 
63364e7ead1SJim Ingham   return sb_error;
63464e7ead1SJim Ingham }
63530fdc8d8SChris Lattner 
636b9c1b51eSKate Stone void SBThread::StepOver(lldb::RunMode stop_other_threads) {
637859f54b3SAlexander Polyakov   SBError error; // Ignored
638859f54b3SAlexander Polyakov   StepOver(stop_other_threads, error);
639859f54b3SAlexander Polyakov }
640859f54b3SAlexander Polyakov 
641859f54b3SAlexander Polyakov void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
6425160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
643ceb6b139SCaroline Tice 
644bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
645bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
64617a6ad05SGreg Clayton 
647ceb6b139SCaroline Tice   if (log)
648324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::StepOver (stop_other_threads='%s')",
649324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
650ceb6b139SCaroline Tice                 Thread::RunModeAsCString(stop_other_threads));
651ceb6b139SCaroline Tice 
652859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
653859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
654859f54b3SAlexander Polyakov     return;
655859f54b3SAlexander Polyakov   }
656859f54b3SAlexander Polyakov 
6571ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
6587ba6e991SJim Ingham   bool abort_other_plans = false;
659b57e4a1bSJason Molenda   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
66030fdc8d8SChris Lattner 
661e103ae92SJonas Devlieghere   Status new_plan_status;
6624d56e9c1SJim Ingham   ThreadPlanSP new_plan_sp;
663b9c1b51eSKate Stone   if (frame_sp) {
664b9c1b51eSKate Stone     if (frame_sp->HasDebugInformation()) {
6654b4b2478SJim Ingham       const LazyBool avoid_no_debug = eLazyBoolCalculate;
66630fdc8d8SChris Lattner       SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
667b9c1b51eSKate Stone       new_plan_sp = thread->QueueThreadPlanForStepOverRange(
668b9c1b51eSKate Stone           abort_other_plans, sc.line_entry, sc, stop_other_threads,
669e103ae92SJonas Devlieghere           new_plan_status, avoid_no_debug);
670b9c1b51eSKate Stone     } else {
671b9c1b51eSKate Stone       new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
672e103ae92SJonas Devlieghere           true, abort_other_plans, stop_other_threads, new_plan_status);
67330fdc8d8SChris Lattner     }
67430fdc8d8SChris Lattner   }
675859f54b3SAlexander Polyakov   error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
67630fdc8d8SChris Lattner }
67730fdc8d8SChris Lattner 
678b9c1b51eSKate Stone void SBThread::StepInto(lldb::RunMode stop_other_threads) {
679c627682eSJim Ingham   StepInto(NULL, stop_other_threads);
680c627682eSJim Ingham }
681c627682eSJim Ingham 
682b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name,
683b9c1b51eSKate Stone                         lldb::RunMode stop_other_threads) {
684859f54b3SAlexander Polyakov   SBError error; // Ignored
685cbf6f9b2SJim Ingham   StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
686cbf6f9b2SJim Ingham }
687cbf6f9b2SJim Ingham 
688b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name, uint32_t end_line,
689b9c1b51eSKate Stone                         SBError &error, lldb::RunMode stop_other_threads) {
6905160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
691ceb6b139SCaroline Tice 
692bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
693bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
69417a6ad05SGreg Clayton 
69517a6ad05SGreg Clayton   if (log)
696b9c1b51eSKate Stone     log->Printf(
697b9c1b51eSKate Stone         "SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
698324a1036SSaleem Abdulrasool         static_cast<void *>(exe_ctx.GetThreadPtr()),
699c627682eSJim Ingham         target_name ? target_name : "<NULL>",
70017a6ad05SGreg Clayton         Thread::RunModeAsCString(stop_other_threads));
701c627682eSJim Ingham 
702859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
703859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
704859f54b3SAlexander Polyakov     return;
705859f54b3SAlexander Polyakov   }
706859f54b3SAlexander Polyakov 
7077ba6e991SJim Ingham   bool abort_other_plans = false;
70830fdc8d8SChris Lattner 
7091ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
710b57e4a1bSJason Molenda   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
7114d56e9c1SJim Ingham   ThreadPlanSP new_plan_sp;
712e103ae92SJonas Devlieghere   Status new_plan_status;
71330fdc8d8SChris Lattner 
714b9c1b51eSKate Stone   if (frame_sp && frame_sp->HasDebugInformation()) {
715cbf6f9b2SJim Ingham     SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
716cbf6f9b2SJim Ingham     AddressRange range;
717cbf6f9b2SJim Ingham     if (end_line == LLDB_INVALID_LINE_NUMBER)
718cbf6f9b2SJim Ingham       range = sc.line_entry.range;
719b9c1b51eSKate Stone     else {
720cbf6f9b2SJim Ingham       if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
721cbf6f9b2SJim Ingham         return;
722cbf6f9b2SJim Ingham     }
723cbf6f9b2SJim Ingham 
724b9c1b51eSKate Stone     const LazyBool step_out_avoids_code_without_debug_info =
725b9c1b51eSKate Stone         eLazyBoolCalculate;
726b9c1b51eSKate Stone     const LazyBool step_in_avoids_code_without_debug_info =
727b9c1b51eSKate Stone         eLazyBoolCalculate;
728b9c1b51eSKate Stone     new_plan_sp = thread->QueueThreadPlanForStepInRange(
729b9c1b51eSKate Stone         abort_other_plans, range, sc, target_name, stop_other_threads,
730e103ae92SJonas Devlieghere         new_plan_status, step_in_avoids_code_without_debug_info,
7314b4b2478SJim Ingham         step_out_avoids_code_without_debug_info);
732b9c1b51eSKate Stone   } else {
733b9c1b51eSKate Stone     new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
734e103ae92SJonas Devlieghere         false, abort_other_plans, stop_other_threads, new_plan_status);
73530fdc8d8SChris Lattner   }
736e103ae92SJonas Devlieghere 
737e103ae92SJonas Devlieghere   if (new_plan_status.Success())
738cbf6f9b2SJim Ingham     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
739e103ae92SJonas Devlieghere   else
740e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
74130fdc8d8SChris Lattner }
74230fdc8d8SChris Lattner 
743b9c1b51eSKate Stone void SBThread::StepOut() {
744859f54b3SAlexander Polyakov   SBError error; // Ignored
745859f54b3SAlexander Polyakov   StepOut(error);
746859f54b3SAlexander Polyakov }
747859f54b3SAlexander Polyakov 
748859f54b3SAlexander Polyakov void SBThread::StepOut(SBError &error) {
7495160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
750ceb6b139SCaroline Tice 
751bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
752bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
7534fc6cb9cSJim Ingham 
75417a6ad05SGreg Clayton   if (log)
755324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::StepOut ()",
756324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()));
75717a6ad05SGreg Clayton 
758859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
759859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
760859f54b3SAlexander Polyakov     return;
761859f54b3SAlexander Polyakov   }
762859f54b3SAlexander Polyakov 
7637ba6e991SJim Ingham   bool abort_other_plans = false;
76494b09246SJim Ingham   bool stop_other_threads = false;
76530fdc8d8SChris Lattner 
7661ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
7671ac04c30SGreg Clayton 
7684b4b2478SJim Ingham   const LazyBool avoid_no_debug = eLazyBoolCalculate;
769e103ae92SJonas Devlieghere   Status new_plan_status;
770b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
771b9c1b51eSKate Stone       abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
772e103ae92SJonas Devlieghere       eVoteNoOpinion, 0, new_plan_status, avoid_no_debug));
773481cef25SGreg Clayton 
774e103ae92SJonas Devlieghere   if (new_plan_status.Success())
775859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
776e103ae92SJonas Devlieghere   else
777e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
778481cef25SGreg Clayton }
779481cef25SGreg Clayton 
780859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
781859f54b3SAlexander Polyakov   SBError error; // Ignored
782859f54b3SAlexander Polyakov   StepOutOfFrame(sb_frame, error);
783859f54b3SAlexander Polyakov }
784859f54b3SAlexander Polyakov 
785859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
7865160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
787481cef25SGreg Clayton 
788bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
789bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
7904fc6cb9cSJim Ingham 
791b9c1b51eSKate Stone   if (!sb_frame.IsValid()) {
792989a7558SJim Ingham     if (log)
793b9c1b51eSKate Stone       log->Printf(
794b9c1b51eSKate Stone           "SBThread(%p)::StepOutOfFrame passed an invalid frame, returning.",
795989a7558SJim Ingham           static_cast<void *>(exe_ctx.GetThreadPtr()));
796859f54b3SAlexander Polyakov     error.SetErrorString("passed invalid SBFrame object");
797989a7558SJim Ingham     return;
798989a7558SJim Ingham   }
799989a7558SJim Ingham 
800b57e4a1bSJason Molenda   StackFrameSP frame_sp(sb_frame.GetFrameSP());
801b9c1b51eSKate Stone   if (log) {
802481cef25SGreg Clayton     SBStream frame_desc_strm;
803481cef25SGreg Clayton     sb_frame.GetDescription(frame_desc_strm);
804324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)",
805324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
806b9c1b51eSKate Stone                 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
807481cef25SGreg Clayton   }
808481cef25SGreg Clayton 
809859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
810859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
811859f54b3SAlexander Polyakov     return;
812859f54b3SAlexander Polyakov   }
813859f54b3SAlexander Polyakov 
8147ba6e991SJim Ingham   bool abort_other_plans = false;
81594b09246SJim Ingham   bool stop_other_threads = false;
8161ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
817b9c1b51eSKate Stone   if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
818b9c1b51eSKate Stone     log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another "
819b9c1b51eSKate Stone                 "thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.",
820989a7558SJim Ingham                 static_cast<void *>(exe_ctx.GetThreadPtr()),
821b9c1b51eSKate Stone                 sb_frame.GetThread().GetThreadID(), thread->GetID());
822859f54b3SAlexander Polyakov     error.SetErrorString("passed a frame from another thread");
823859f54b3SAlexander Polyakov     return;
824989a7558SJim Ingham   }
825481cef25SGreg Clayton 
826e103ae92SJonas Devlieghere   Status new_plan_status;
827b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
828b9c1b51eSKate Stone       abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
829e103ae92SJonas Devlieghere       eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status));
83030fdc8d8SChris Lattner 
831e103ae92SJonas Devlieghere   if (new_plan_status.Success())
832859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
833e103ae92SJonas Devlieghere   else
834e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
83530fdc8d8SChris Lattner }
83630fdc8d8SChris Lattner 
837b9c1b51eSKate Stone void SBThread::StepInstruction(bool step_over) {
838859f54b3SAlexander Polyakov   SBError error; // Ignored
839859f54b3SAlexander Polyakov   StepInstruction(step_over, error);
840859f54b3SAlexander Polyakov }
841859f54b3SAlexander Polyakov 
842859f54b3SAlexander Polyakov void SBThread::StepInstruction(bool step_over, SBError &error) {
8435160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
844ceb6b139SCaroline Tice 
845bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
846bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
847ceb6b139SCaroline Tice 
84817a6ad05SGreg Clayton   if (log)
849324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::StepInstruction (step_over=%i)",
850324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), step_over);
85117a6ad05SGreg Clayton 
852859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
853859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
854859f54b3SAlexander Polyakov     return;
855859f54b3SAlexander Polyakov   }
856859f54b3SAlexander Polyakov 
8571ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
858e103ae92SJonas Devlieghere   Status new_plan_status;
859e103ae92SJonas Devlieghere   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction(
860e103ae92SJonas Devlieghere       step_over, true, true, new_plan_status));
86164e7ead1SJim Ingham 
862e103ae92SJonas Devlieghere   if (new_plan_status.Success())
863859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
864e103ae92SJonas Devlieghere   else
865e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
86630fdc8d8SChris Lattner }
86730fdc8d8SChris Lattner 
868b9c1b51eSKate Stone void SBThread::RunToAddress(lldb::addr_t addr) {
869859f54b3SAlexander Polyakov   SBError error; // Ignored
870859f54b3SAlexander Polyakov   RunToAddress(addr, error);
871859f54b3SAlexander Polyakov }
872859f54b3SAlexander Polyakov 
873859f54b3SAlexander Polyakov void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
8745160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
875ceb6b139SCaroline Tice 
876bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
877bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
878ceb6b139SCaroline Tice 
87917a6ad05SGreg Clayton   if (log)
880324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")",
881324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), addr);
88217a6ad05SGreg Clayton 
883859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
884859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
885859f54b3SAlexander Polyakov     return;
886859f54b3SAlexander Polyakov   }
887859f54b3SAlexander Polyakov 
8887ba6e991SJim Ingham   bool abort_other_plans = false;
88930fdc8d8SChris Lattner   bool stop_other_threads = true;
89030fdc8d8SChris Lattner 
891e72dfb32SGreg Clayton   Address target_addr(addr);
89230fdc8d8SChris Lattner 
8931ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
8941ac04c30SGreg Clayton 
895e103ae92SJonas Devlieghere   Status new_plan_status;
896b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
897e103ae92SJonas Devlieghere       abort_other_plans, target_addr, stop_other_threads, new_plan_status));
89864e7ead1SJim Ingham 
899e103ae92SJonas Devlieghere   if (new_plan_status.Success())
900859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
901e103ae92SJonas Devlieghere   else
902e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
90330fdc8d8SChris Lattner }
90430fdc8d8SChris Lattner 
905b9c1b51eSKate Stone SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
906b9c1b51eSKate Stone                                 lldb::SBFileSpec &sb_file_spec, uint32_t line) {
907481cef25SGreg Clayton   SBError sb_error;
9085160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
909481cef25SGreg Clayton   char path[PATH_MAX];
910481cef25SGreg Clayton 
911bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
912bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
9134fc6cb9cSJim Ingham 
914b57e4a1bSJason Molenda   StackFrameSP frame_sp(sb_frame.GetFrameSP());
91517a6ad05SGreg Clayton 
916b9c1b51eSKate Stone   if (log) {
917481cef25SGreg Clayton     SBStream frame_desc_strm;
918481cef25SGreg Clayton     sb_frame.GetDescription(frame_desc_strm);
919481cef25SGreg Clayton     sb_file_spec->GetPath(path, sizeof(path));
920b9c1b51eSKate Stone     log->Printf("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, "
921b9c1b51eSKate Stone                 "file+line = %s:%u)",
922324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
923b9c1b51eSKate Stone                 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData(),
924b9c1b51eSKate Stone                 path, line);
925481cef25SGreg Clayton   }
926481cef25SGreg Clayton 
927b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
9281ac04c30SGreg Clayton     Target *target = exe_ctx.GetTargetPtr();
9291ac04c30SGreg Clayton     Thread *thread = exe_ctx.GetThreadPtr();
930481cef25SGreg Clayton 
931b9c1b51eSKate Stone     if (line == 0) {
932481cef25SGreg Clayton       sb_error.SetErrorString("invalid line argument");
933481cef25SGreg Clayton       return sb_error;
934481cef25SGreg Clayton     }
935481cef25SGreg Clayton 
936b9c1b51eSKate Stone     if (!frame_sp) {
9371ac04c30SGreg Clayton       frame_sp = thread->GetSelectedFrame();
938481cef25SGreg Clayton       if (!frame_sp)
9391ac04c30SGreg Clayton         frame_sp = thread->GetStackFrameAtIndex(0);
940481cef25SGreg Clayton     }
941481cef25SGreg Clayton 
942481cef25SGreg Clayton     SymbolContext frame_sc;
943b9c1b51eSKate Stone     if (!frame_sp) {
944481cef25SGreg Clayton       sb_error.SetErrorString("no valid frames in thread to step");
945481cef25SGreg Clayton       return sb_error;
946481cef25SGreg Clayton     }
947481cef25SGreg Clayton 
948481cef25SGreg Clayton     // If we have a frame, get its line
949b9c1b51eSKate Stone     frame_sc = frame_sp->GetSymbolContext(
950b9c1b51eSKate Stone         eSymbolContextCompUnit | eSymbolContextFunction |
951b9c1b51eSKate Stone         eSymbolContextLineEntry | eSymbolContextSymbol);
952481cef25SGreg Clayton 
953b9c1b51eSKate Stone     if (frame_sc.comp_unit == NULL) {
954b9c1b51eSKate Stone       sb_error.SetErrorStringWithFormat(
955b9c1b51eSKate Stone           "frame %u doesn't have debug information", frame_sp->GetFrameIndex());
956481cef25SGreg Clayton       return sb_error;
957481cef25SGreg Clayton     }
958481cef25SGreg Clayton 
959481cef25SGreg Clayton     FileSpec step_file_spec;
960b9c1b51eSKate Stone     if (sb_file_spec.IsValid()) {
961481cef25SGreg Clayton       // The file spec passed in was valid, so use it
962481cef25SGreg Clayton       step_file_spec = sb_file_spec.ref();
963b9c1b51eSKate Stone     } else {
964481cef25SGreg Clayton       if (frame_sc.line_entry.IsValid())
965481cef25SGreg Clayton         step_file_spec = frame_sc.line_entry.file;
966b9c1b51eSKate Stone       else {
967481cef25SGreg Clayton         sb_error.SetErrorString("invalid file argument or no file for frame");
968481cef25SGreg Clayton         return sb_error;
969481cef25SGreg Clayton       }
970481cef25SGreg Clayton     }
971481cef25SGreg Clayton 
9729b70ddb3SJim Ingham     // Grab the current function, then we will make sure the "until" address is
9739b70ddb3SJim Ingham     // within the function.  We discard addresses that are out of the current
974b9c1b51eSKate Stone     // function, and then if there are no addresses remaining, give an
97505097246SAdrian Prantl     // appropriate error message.
9769b70ddb3SJim Ingham 
9779b70ddb3SJim Ingham     bool all_in_function = true;
9789b70ddb3SJim Ingham     AddressRange fun_range = frame_sc.function->GetAddressRange();
9799b70ddb3SJim Ingham 
980481cef25SGreg Clayton     std::vector<addr_t> step_over_until_addrs;
9817ba6e991SJim Ingham     const bool abort_other_plans = false;
982c02e3344SJim Ingham     const bool stop_other_threads = false;
983481cef25SGreg Clayton     const bool check_inlines = true;
984481cef25SGreg Clayton     const bool exact = false;
985481cef25SGreg Clayton 
986481cef25SGreg Clayton     SymbolContextList sc_list;
987b9c1b51eSKate Stone     const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext(
988b9c1b51eSKate Stone         step_file_spec, line, check_inlines, exact, eSymbolContextLineEntry,
9899b70ddb3SJim Ingham         sc_list);
990b9c1b51eSKate Stone     if (num_matches > 0) {
991481cef25SGreg Clayton       SymbolContext sc;
992b9c1b51eSKate Stone       for (uint32_t i = 0; i < num_matches; ++i) {
993b9c1b51eSKate Stone         if (sc_list.GetContextAtIndex(i, sc)) {
994b9c1b51eSKate Stone           addr_t step_addr =
995b9c1b51eSKate Stone               sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
996b9c1b51eSKate Stone           if (step_addr != LLDB_INVALID_ADDRESS) {
9979b70ddb3SJim Ingham             if (fun_range.ContainsLoadAddress(step_addr, target))
998481cef25SGreg Clayton               step_over_until_addrs.push_back(step_addr);
9999b70ddb3SJim Ingham             else
10009b70ddb3SJim Ingham               all_in_function = false;
1001481cef25SGreg Clayton           }
1002481cef25SGreg Clayton         }
1003481cef25SGreg Clayton       }
1004481cef25SGreg Clayton     }
1005481cef25SGreg Clayton 
1006b9c1b51eSKate Stone     if (step_over_until_addrs.empty()) {
1007b9c1b51eSKate Stone       if (all_in_function) {
1008481cef25SGreg Clayton         step_file_spec.GetPath(path, sizeof(path));
1009b9c1b51eSKate Stone         sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path,
1010b9c1b51eSKate Stone                                           line);
1011b9c1b51eSKate Stone       } else
101286edbf41SGreg Clayton         sb_error.SetErrorString("step until target not in current function");
1013b9c1b51eSKate Stone     } else {
1014e103ae92SJonas Devlieghere       Status new_plan_status;
1015b9c1b51eSKate Stone       ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil(
1016b9c1b51eSKate Stone           abort_other_plans, &step_over_until_addrs[0],
1017b9c1b51eSKate Stone           step_over_until_addrs.size(), stop_other_threads,
1018e103ae92SJonas Devlieghere           frame_sp->GetFrameIndex(), new_plan_status));
1019481cef25SGreg Clayton 
1020e103ae92SJonas Devlieghere       if (new_plan_status.Success())
10214d56e9c1SJim Ingham         sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
1022e103ae92SJonas Devlieghere       else
1023e103ae92SJonas Devlieghere         sb_error.SetErrorString(new_plan_status.AsCString());
1024481cef25SGreg Clayton     }
1025b9c1b51eSKate Stone   } else {
1026481cef25SGreg Clayton     sb_error.SetErrorString("this SBThread object is invalid");
1027481cef25SGreg Clayton   }
1028481cef25SGreg Clayton   return sb_error;
1029481cef25SGreg Clayton }
1030481cef25SGreg Clayton 
1031b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) {
1032000ca185SOleksiy Vyalov   return StepUsingScriptedThreadPlan(script_class_name, true);
1033c915a7d2SJim Ingham }
1034c915a7d2SJim Ingham 
1035b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
1036b9c1b51eSKate Stone                                               bool resume_immediately) {
10372bdbfd50SJim Ingham   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1038e103ae92SJonas Devlieghere   SBError error;
10392bdbfd50SJim Ingham 
1040bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1041bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
10422bdbfd50SJim Ingham 
1043b9c1b51eSKate Stone   if (log) {
10442bdbfd50SJim Ingham     log->Printf("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s",
1045b9c1b51eSKate Stone                 static_cast<void *>(exe_ctx.GetThreadPtr()), script_class_name);
10462bdbfd50SJim Ingham   }
10472bdbfd50SJim Ingham 
1048b9c1b51eSKate Stone   if (!exe_ctx.HasThreadScope()) {
1049e103ae92SJonas Devlieghere     error.SetErrorString("this SBThread object is invalid");
1050e103ae92SJonas Devlieghere     return error;
10512bdbfd50SJim Ingham   }
10522bdbfd50SJim Ingham 
10532bdbfd50SJim Ingham   Thread *thread = exe_ctx.GetThreadPtr();
1054e103ae92SJonas Devlieghere   Status new_plan_status;
1055e103ae92SJonas Devlieghere   ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted(
1056e103ae92SJonas Devlieghere       false, script_class_name, false, new_plan_status);
10572bdbfd50SJim Ingham 
1058e103ae92SJonas Devlieghere   if (new_plan_status.Fail()) {
1059e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
1060e103ae92SJonas Devlieghere     return error;
1061c915a7d2SJim Ingham   }
1062c915a7d2SJim Ingham 
1063e103ae92SJonas Devlieghere   if (!resume_immediately)
1064e103ae92SJonas Devlieghere     return error;
1065c915a7d2SJim Ingham 
1066e103ae92SJonas Devlieghere   if (new_plan_status.Success())
1067e103ae92SJonas Devlieghere     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
1068e103ae92SJonas Devlieghere   else
1069e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
10702bdbfd50SJim Ingham 
1071e103ae92SJonas Devlieghere   return error;
10722bdbfd50SJim Ingham }
10732bdbfd50SJim Ingham 
1074b9c1b51eSKate Stone SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
1075f86248d9SRichard Mitton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1076f86248d9SRichard Mitton   SBError sb_error;
1077f86248d9SRichard Mitton 
1078bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1079bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1080f86248d9SRichard Mitton 
1081f86248d9SRichard Mitton   if (log)
1082324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::JumpToLine (file+line = %s:%u)",
1083324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
1084324a1036SSaleem Abdulrasool                 file_spec->GetPath().c_str(), line);
1085f86248d9SRichard Mitton 
1086b9c1b51eSKate Stone   if (!exe_ctx.HasThreadScope()) {
1087f86248d9SRichard Mitton     sb_error.SetErrorString("this SBThread object is invalid");
1088f86248d9SRichard Mitton     return sb_error;
1089f86248d9SRichard Mitton   }
1090f86248d9SRichard Mitton 
1091f86248d9SRichard Mitton   Thread *thread = exe_ctx.GetThreadPtr();
1092f86248d9SRichard Mitton 
109397206d57SZachary Turner   Status err = thread->JumpToLine(file_spec.get(), line, true);
1094f86248d9SRichard Mitton   sb_error.SetError(err);
1095f86248d9SRichard Mitton   return sb_error;
1096f86248d9SRichard Mitton }
1097f86248d9SRichard Mitton 
1098b9c1b51eSKate Stone SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
10994413758cSJim Ingham   SBError sb_error;
11004413758cSJim Ingham 
11015160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
11024413758cSJim Ingham 
1103bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1104bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11054413758cSJim Ingham 
11064413758cSJim Ingham   if (log)
1107324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::ReturnFromFrame (frame=%d)",
1108324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
1109324a1036SSaleem Abdulrasool                 frame.GetFrameID());
11104413758cSJim Ingham 
1111b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11124413758cSJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
1113b9c1b51eSKate Stone     sb_error.SetError(
1114b9c1b51eSKate Stone         thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
11154413758cSJim Ingham   }
11164413758cSJim Ingham 
11174413758cSJim Ingham   return sb_error;
11184413758cSJim Ingham }
11194413758cSJim Ingham 
1120b9c1b51eSKate Stone SBError SBThread::UnwindInnermostExpression() {
11214ac8e93aSJim Ingham   SBError sb_error;
11224ac8e93aSJim Ingham 
11234ac8e93aSJim Ingham   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
11244ac8e93aSJim Ingham 
11254ac8e93aSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
11264ac8e93aSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11274ac8e93aSJim Ingham 
11284ac8e93aSJim Ingham   if (log)
11294ac8e93aSJim Ingham     log->Printf("SBThread(%p)::UnwindExpressionEvaluation",
11304ac8e93aSJim Ingham                 static_cast<void *>(exe_ctx.GetThreadPtr()));
11314ac8e93aSJim Ingham 
1132b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11334ac8e93aSJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
11344ac8e93aSJim Ingham     sb_error.SetError(thread->UnwindInnermostExpression());
11354ac8e93aSJim Ingham     if (sb_error.Success())
11364ac8e93aSJim Ingham       thread->SetSelectedFrameByIndex(0, false);
11374ac8e93aSJim Ingham   }
11384ac8e93aSJim Ingham 
11394ac8e93aSJim Ingham   return sb_error;
11404ac8e93aSJim Ingham }
1141481cef25SGreg Clayton 
1142b9c1b51eSKate Stone bool SBThread::Suspend() {
1143859f54b3SAlexander Polyakov   SBError error; // Ignored
1144859f54b3SAlexander Polyakov   return Suspend(error);
1145859f54b3SAlexander Polyakov }
1146859f54b3SAlexander Polyakov 
1147859f54b3SAlexander Polyakov bool SBThread::Suspend(SBError &error) {
11485160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1149b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1150b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1151b2e7d28eSJim Ingham 
1152c9858e4dSGreg Clayton   bool result = false;
1153b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1154c9858e4dSGreg Clayton     Process::StopLocker stop_locker;
1155b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11561ac04c30SGreg Clayton       exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
1157c9858e4dSGreg Clayton       result = true;
1158b9c1b51eSKate Stone     } else {
1159859f54b3SAlexander Polyakov       error.SetErrorString("process is running");
1160c9858e4dSGreg Clayton       if (log)
1161324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::Suspend() => error: process is running",
1162324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
1163c9858e4dSGreg Clayton     }
1164859f54b3SAlexander Polyakov   } else
1165859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
1166c9858e4dSGreg Clayton   if (log)
1167324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::Suspend() => %i",
1168324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), result);
1169c9858e4dSGreg Clayton   return result;
1170722a0cdcSGreg Clayton }
1171722a0cdcSGreg Clayton 
1172b9c1b51eSKate Stone bool SBThread::Resume() {
1173859f54b3SAlexander Polyakov   SBError error; // Ignored
1174859f54b3SAlexander Polyakov   return Resume(error);
1175859f54b3SAlexander Polyakov }
1176859f54b3SAlexander Polyakov 
1177859f54b3SAlexander Polyakov bool SBThread::Resume(SBError &error) {
11785160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1179b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1180b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1181b2e7d28eSJim Ingham 
1182c9858e4dSGreg Clayton   bool result = false;
1183b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1184c9858e4dSGreg Clayton     Process::StopLocker stop_locker;
1185b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11866c9ed91cSJim Ingham       const bool override_suspend = true;
11876c9ed91cSJim Ingham       exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
1188c9858e4dSGreg Clayton       result = true;
1189b9c1b51eSKate Stone     } else {
1190859f54b3SAlexander Polyakov       error.SetErrorString("process is running");
1191c9858e4dSGreg Clayton       if (log)
1192324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::Resume() => error: process is running",
1193324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
1194c9858e4dSGreg Clayton     }
1195859f54b3SAlexander Polyakov   } else
1196859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
1197c9858e4dSGreg Clayton   if (log)
1198324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::Resume() => %i",
1199324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), result);
1200c9858e4dSGreg Clayton   return result;
1201722a0cdcSGreg Clayton }
1202722a0cdcSGreg Clayton 
1203b9c1b51eSKate Stone bool SBThread::IsSuspended() {
1204b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1205b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1206b2e7d28eSJim Ingham 
12071ac04c30SGreg Clayton   if (exe_ctx.HasThreadScope())
12081ac04c30SGreg Clayton     return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
1209722a0cdcSGreg Clayton   return false;
1210722a0cdcSGreg Clayton }
1211722a0cdcSGreg Clayton 
1212b9c1b51eSKate Stone bool SBThread::IsStopped() {
1213b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1214b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1215b2e7d28eSJim Ingham 
1216a75418dbSAndrew Kaylor   if (exe_ctx.HasThreadScope())
1217a75418dbSAndrew Kaylor     return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1218a75418dbSAndrew Kaylor   return false;
1219a75418dbSAndrew Kaylor }
1220a75418dbSAndrew Kaylor 
1221b9c1b51eSKate Stone SBProcess SBThread::GetProcess() {
1222b9556accSGreg Clayton   SBProcess sb_process;
1223b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1224b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1225b2e7d28eSJim Ingham 
1226b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1227b9c1b51eSKate Stone     // Have to go up to the target so we can get a shared pointer to our
1228b9c1b51eSKate Stone     // process...
12291ac04c30SGreg Clayton     sb_process.SetSP(exe_ctx.GetProcessSP());
123030fdc8d8SChris Lattner   }
1231ceb6b139SCaroline Tice 
12325160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1233b9c1b51eSKate Stone   if (log) {
1234481cef25SGreg Clayton     SBStream frame_desc_strm;
1235b9556accSGreg Clayton     sb_process.GetDescription(frame_desc_strm);
1236324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetProcess () => SBProcess(%p): %s",
1237324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
1238324a1036SSaleem Abdulrasool                 static_cast<void *>(sb_process.GetSP().get()),
1239324a1036SSaleem Abdulrasool                 frame_desc_strm.GetData());
1240ceb6b139SCaroline Tice   }
1241ceb6b139SCaroline Tice 
1242b9556accSGreg Clayton   return sb_process;
124330fdc8d8SChris Lattner }
124430fdc8d8SChris Lattner 
1245b9c1b51eSKate Stone uint32_t SBThread::GetNumFrames() {
12465160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1247ceb6b139SCaroline Tice 
1248ceb6b139SCaroline Tice   uint32_t num_frames = 0;
1249bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1250bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12514fc6cb9cSJim Ingham 
1252b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
12537fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1254b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
12551ac04c30SGreg Clayton       num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1256b9c1b51eSKate Stone     } else {
1257c9858e4dSGreg Clayton       if (log)
1258324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::GetNumFrames() => error: process is running",
1259324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
1260c9858e4dSGreg Clayton     }
12617fdf9ef1SGreg Clayton   }
1262ceb6b139SCaroline Tice 
1263ceb6b139SCaroline Tice   if (log)
1264324a1036SSaleem Abdulrasool     log->Printf("SBThread(%p)::GetNumFrames () => %u",
1265324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), num_frames);
1266ceb6b139SCaroline Tice 
1267ceb6b139SCaroline Tice   return num_frames;
126830fdc8d8SChris Lattner }
126930fdc8d8SChris Lattner 
1270b9c1b51eSKate Stone SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
12715160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1272ceb6b139SCaroline Tice 
127330fdc8d8SChris Lattner   SBFrame sb_frame;
1274b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1275bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1276bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12774fc6cb9cSJim Ingham 
1278b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
12797fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1280b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
12811ac04c30SGreg Clayton       frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
1282b9556accSGreg Clayton       sb_frame.SetFrameSP(frame_sp);
1283b9c1b51eSKate Stone     } else {
1284c9858e4dSGreg Clayton       if (log)
1285b9c1b51eSKate Stone         log->Printf(
1286b9c1b51eSKate Stone             "SBThread(%p)::GetFrameAtIndex() => error: process is running",
1287324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
1288c9858e4dSGreg Clayton     }
12897fdf9ef1SGreg Clayton   }
1290ceb6b139SCaroline Tice 
1291b9c1b51eSKate Stone   if (log) {
1292481cef25SGreg Clayton     SBStream frame_desc_strm;
1293481cef25SGreg Clayton     sb_frame.GetDescription(frame_desc_strm);
12944838131bSGreg Clayton     log->Printf("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
1295324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), idx,
1296b9c1b51eSKate Stone                 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1297ceb6b139SCaroline Tice   }
1298ceb6b139SCaroline Tice 
129930fdc8d8SChris Lattner   return sb_frame;
130030fdc8d8SChris Lattner }
130130fdc8d8SChris Lattner 
1302b9c1b51eSKate Stone lldb::SBFrame SBThread::GetSelectedFrame() {
13035160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1304f028a1fbSGreg Clayton 
1305f028a1fbSGreg Clayton   SBFrame sb_frame;
1306b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1307bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1308bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
13094fc6cb9cSJim Ingham 
1310b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
13117fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1312b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
13131ac04c30SGreg Clayton       frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame();
1314b9556accSGreg Clayton       sb_frame.SetFrameSP(frame_sp);
1315b9c1b51eSKate Stone     } else {
1316c9858e4dSGreg Clayton       if (log)
1317b9c1b51eSKate Stone         log->Printf(
1318b9c1b51eSKate Stone             "SBThread(%p)::GetSelectedFrame() => error: process is running",
1319324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
1320c9858e4dSGreg Clayton     }
13217fdf9ef1SGreg Clayton   }
1322f028a1fbSGreg Clayton 
1323b9c1b51eSKate Stone   if (log) {
1324481cef25SGreg Clayton     SBStream frame_desc_strm;
1325481cef25SGreg Clayton     sb_frame.GetDescription(frame_desc_strm);
1326f028a1fbSGreg Clayton     log->Printf("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
1327324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()),
1328b9c1b51eSKate Stone                 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1329f028a1fbSGreg Clayton   }
1330f028a1fbSGreg Clayton 
1331f028a1fbSGreg Clayton   return sb_frame;
1332f028a1fbSGreg Clayton }
1333f028a1fbSGreg Clayton 
1334b9c1b51eSKate Stone lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
13355160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1336f028a1fbSGreg Clayton 
1337f028a1fbSGreg Clayton   SBFrame sb_frame;
1338b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1339bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1340bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
13414fc6cb9cSJim Ingham 
1342b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
13437fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1344b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
13451ac04c30SGreg Clayton       Thread *thread = exe_ctx.GetThreadPtr();
13461ac04c30SGreg Clayton       frame_sp = thread->GetStackFrameAtIndex(idx);
1347b9c1b51eSKate Stone       if (frame_sp) {
13481ac04c30SGreg Clayton         thread->SetSelectedFrame(frame_sp.get());
1349b9556accSGreg Clayton         sb_frame.SetFrameSP(frame_sp);
1350f028a1fbSGreg Clayton       }
1351b9c1b51eSKate Stone     } else {
1352c9858e4dSGreg Clayton       if (log)
1353b9c1b51eSKate Stone         log->Printf(
1354b9c1b51eSKate Stone             "SBThread(%p)::SetSelectedFrame() => error: process is running",
1355324a1036SSaleem Abdulrasool             static_cast<void *>(exe_ctx.GetThreadPtr()));
1356c9858e4dSGreg Clayton     }
13577fdf9ef1SGreg Clayton   }
1358f028a1fbSGreg Clayton 
1359b9c1b51eSKate Stone   if (log) {
1360481cef25SGreg Clayton     SBStream frame_desc_strm;
1361481cef25SGreg Clayton     sb_frame.GetDescription(frame_desc_strm);
1362f028a1fbSGreg Clayton     log->Printf("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
1363324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()), idx,
1364b9c1b51eSKate Stone                 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1365f028a1fbSGreg Clayton   }
1366f028a1fbSGreg Clayton   return sb_frame;
1367f028a1fbSGreg Clayton }
1368f028a1fbSGreg Clayton 
1369b9c1b51eSKate Stone bool SBThread::EventIsThreadEvent(const SBEvent &event) {
13704f465cffSJim Ingham   return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
13714f465cffSJim Ingham }
13724f465cffSJim Ingham 
1373b9c1b51eSKate Stone SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) {
13744f465cffSJim Ingham   return Thread::ThreadEventData::GetStackFrameFromEvent(event.get());
13754f465cffSJim Ingham }
13764f465cffSJim Ingham 
1377b9c1b51eSKate Stone SBThread SBThread::GetThreadFromEvent(const SBEvent &event) {
13784f465cffSJim Ingham   return Thread::ThreadEventData::GetThreadFromEvent(event.get());
13794f465cffSJim Ingham }
1380f028a1fbSGreg Clayton 
1381b9c1b51eSKate Stone bool SBThread::operator==(const SBThread &rhs) const {
1382b9c1b51eSKate Stone   return m_opaque_sp->GetThreadSP().get() ==
1383b9c1b51eSKate Stone          rhs.m_opaque_sp->GetThreadSP().get();
138430fdc8d8SChris Lattner }
138530fdc8d8SChris Lattner 
1386b9c1b51eSKate Stone bool SBThread::operator!=(const SBThread &rhs) const {
1387b9c1b51eSKate Stone   return m_opaque_sp->GetThreadSP().get() !=
1388b9c1b51eSKate Stone          rhs.m_opaque_sp->GetThreadSP().get();
138930fdc8d8SChris Lattner }
1390dde9cff3SCaroline Tice 
1391b9c1b51eSKate Stone bool SBThread::GetStatus(SBStream &status) const {
13924f465cffSJim Ingham   Stream &strm = status.ref();
13934f465cffSJim Ingham 
1394b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1395b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1396b2e7d28eSJim Ingham 
1397b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
13986a9767c7SJim Ingham     exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true);
1399b9c1b51eSKate Stone   } else
14004f465cffSJim Ingham     strm.PutCString("No status");
14014f465cffSJim Ingham 
14024f465cffSJim Ingham   return true;
14034f465cffSJim Ingham }
14044f465cffSJim Ingham 
1405b9c1b51eSKate Stone bool SBThread::GetDescription(SBStream &description) const {
14066a9767c7SJim Ingham     return GetDescription(description, false);
14076a9767c7SJim Ingham }
14086a9767c7SJim Ingham 
14096a9767c7SJim Ingham bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
1410da7bc7d0SGreg Clayton   Stream &strm = description.ref();
1411da7bc7d0SGreg Clayton 
1412b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1413b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1414b2e7d28eSJim Ingham 
1415b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1416b9c1b51eSKate Stone     exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm,
14176a9767c7SJim Ingham                                                     LLDB_INVALID_THREAD_ID,
14186a9767c7SJim Ingham                                                     stop_format);
1419b9c1b51eSKate Stone     // strm.Printf("SBThread: tid = 0x%4.4" PRIx64,
1420b9c1b51eSKate Stone     // exe_ctx.GetThreadPtr()->GetID());
1421b9c1b51eSKate Stone   } else
1422da7bc7d0SGreg Clayton     strm.PutCString("No value");
1423ceb6b139SCaroline Tice 
1424ceb6b139SCaroline Tice   return true;
1425ceb6b139SCaroline Tice }
14265dd4916fSJason Molenda 
1427b9c1b51eSKate Stone SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
14285dd4916fSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1429bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1430bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
14315dd4916fSJason Molenda   SBThread sb_origin_thread;
14325dd4916fSJason Molenda 
1433b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
14345dd4916fSJason Molenda     Process::StopLocker stop_locker;
1435b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
14367a2f7904SJason Molenda       ThreadSP real_thread(exe_ctx.GetThreadSP());
1437b9c1b51eSKate Stone       if (real_thread) {
14385dd4916fSJason Molenda         ConstString type_const(type);
14397a2f7904SJason Molenda         Process *process = exe_ctx.GetProcessPtr();
1440b9c1b51eSKate Stone         if (process) {
14417a2f7904SJason Molenda           SystemRuntime *runtime = process->GetSystemRuntime();
1442b9c1b51eSKate Stone           if (runtime) {
1443b9c1b51eSKate Stone             ThreadSP new_thread_sp(
1444b9c1b51eSKate Stone                 runtime->GetExtendedBacktraceThread(real_thread, type_const));
1445b9c1b51eSKate Stone             if (new_thread_sp) {
1446b9c1b51eSKate Stone               // Save this in the Process' ExtendedThreadList so a strong
144705097246SAdrian Prantl               // pointer retains the object.
14487a2f7904SJason Molenda               process->GetExtendedThreadList().AddThread(new_thread_sp);
14497a2f7904SJason Molenda               sb_origin_thread.SetThread(new_thread_sp);
1450b9c1b51eSKate Stone               if (log) {
1451a6e9130dSJason Molenda                 const char *queue_name = new_thread_sp->GetQueueName();
1452a6e9130dSJason Molenda                 if (queue_name == NULL)
1453a6e9130dSJason Molenda                   queue_name = "";
1454b9c1b51eSKate Stone                 log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => new "
1455b9c1b51eSKate Stone                             "extended Thread "
1456b9c1b51eSKate Stone                             "created (%p) with queue_id 0x%" PRIx64
1457b9c1b51eSKate Stone                             " queue name '%s'",
1458324a1036SSaleem Abdulrasool                             static_cast<void *>(exe_ctx.GetThreadPtr()),
1459324a1036SSaleem Abdulrasool                             static_cast<void *>(new_thread_sp.get()),
1460b9c1b51eSKate Stone                             new_thread_sp->GetQueueID(), queue_name);
1461a6e9130dSJason Molenda               }
1462a6e9130dSJason Molenda             }
14637a2f7904SJason Molenda           }
14645dd4916fSJason Molenda         }
14655dd4916fSJason Molenda       }
1466b9c1b51eSKate Stone     } else {
14675dd4916fSJason Molenda       if (log)
1468b9c1b51eSKate Stone         log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => error: "
1469b9c1b51eSKate Stone                     "process is running",
1470324a1036SSaleem Abdulrasool                     static_cast<void *>(exe_ctx.GetThreadPtr()));
14715dd4916fSJason Molenda     }
14725dd4916fSJason Molenda   }
14735dd4916fSJason Molenda 
1474a6682a41SJonas Devlieghere   if (log && !sb_origin_thread.IsValid())
1475b9c1b51eSKate Stone     log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a "
1476b9c1b51eSKate Stone                 "Valid thread",
1477324a1036SSaleem Abdulrasool                 static_cast<void *>(exe_ctx.GetThreadPtr()));
14785dd4916fSJason Molenda   return sb_origin_thread;
14795dd4916fSJason Molenda }
14808ee9cb58SJason Molenda 
1481b9c1b51eSKate Stone uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
14828ee9cb58SJason Molenda   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
14838ee9cb58SJason Molenda   if (thread_sp)
14848ee9cb58SJason Molenda     return thread_sp->GetExtendedBacktraceOriginatingIndexID();
14858ee9cb58SJason Molenda   return LLDB_INVALID_INDEX32;
14868ee9cb58SJason Molenda }
1487b4892cd2SJason Molenda 
1488e60bc53bSKuba Mracek SBValue SBThread::GetCurrentException() {
1489e60bc53bSKuba Mracek   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1490e60bc53bSKuba Mracek   if (!thread_sp) return SBValue();
1491e60bc53bSKuba Mracek 
1492e60bc53bSKuba Mracek   return SBValue(thread_sp->GetCurrentException());
1493e60bc53bSKuba Mracek }
1494e60bc53bSKuba Mracek 
1495e60bc53bSKuba Mracek SBThread SBThread::GetCurrentExceptionBacktrace() {
1496e60bc53bSKuba Mracek   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1497e60bc53bSKuba Mracek   if (!thread_sp) return SBThread();
1498e60bc53bSKuba Mracek 
1499e60bc53bSKuba Mracek   return SBThread(thread_sp->GetCurrentExceptionBacktrace());
1500c9e1190aSKuba Mracek }
1501e60bc53bSKuba Mracek 
1502b9c1b51eSKate Stone bool SBThread::SafeToCallFunctions() {
1503b4892cd2SJason Molenda   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1504b4892cd2SJason Molenda   if (thread_sp)
1505b4892cd2SJason Molenda     return thread_sp->SafeToCallFunctions();
1506b4892cd2SJason Molenda   return true;
1507b4892cd2SJason Molenda }
15082bdbfd50SJim Ingham 
1509b9c1b51eSKate Stone lldb_private::Thread *SBThread::operator->() {
15102bdbfd50SJim Ingham   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
15112bdbfd50SJim Ingham   if (thread_sp)
15122bdbfd50SJim Ingham     return thread_sp.get();
15132bdbfd50SJim Ingham   else
15142bdbfd50SJim Ingham     return NULL;
15152bdbfd50SJim Ingham }
15162bdbfd50SJim Ingham 
1517b9c1b51eSKate Stone lldb_private::Thread *SBThread::get() {
15182bdbfd50SJim Ingham   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
15192bdbfd50SJim Ingham   if (thread_sp)
15202bdbfd50SJim Ingham     return thread_sp.get();
15212bdbfd50SJim Ingham   else
15222bdbfd50SJim Ingham     return NULL;
15232bdbfd50SJim Ingham }
1524