180814287SRaphael Isemann //===-- SBThread.cpp ------------------------------------------------------===//
230fdc8d8SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner 
94c5de699SEli Friedman #include "lldb/API/SBThread.h"
10baf5664fSJonas Devlieghere #include "SBReproducerPrivate.h"
11bd4bf82aSJonas Devlieghere #include "Utils.h"
12bd4bf82aSJonas Devlieghere #include "lldb/API/SBAddress.h"
13bd4bf82aSJonas Devlieghere #include "lldb/API/SBDebugger.h"
14bd4bf82aSJonas Devlieghere #include "lldb/API/SBEvent.h"
1530fdc8d8SChris Lattner #include "lldb/API/SBFileSpec.h"
16bd4bf82aSJonas Devlieghere #include "lldb/API/SBFrame.h"
17bd4bf82aSJonas Devlieghere #include "lldb/API/SBProcess.h"
18dde9cff3SCaroline Tice #include "lldb/API/SBStream.h"
1927a14f19SJim Ingham #include "lldb/API/SBStructuredData.h"
20b9c1b51eSKate Stone #include "lldb/API/SBSymbolContext.h"
21bd4bf82aSJonas Devlieghere #include "lldb/API/SBThreadCollection.h"
22bd4bf82aSJonas Devlieghere #include "lldb/API/SBThreadPlan.h"
23bd4bf82aSJonas Devlieghere #include "lldb/API/SBValue.h"
244e78f606SGreg Clayton #include "lldb/Breakpoint/BreakpointLocation.h"
256611103cSGreg Clayton #include "lldb/Core/Debugger.h"
2630fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h"
2727a14f19SJim Ingham #include "lldb/Core/StructuredDataImpl.h"
28a78bd7ffSZachary Turner #include "lldb/Core/ValueObject.h"
296611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
3093749ab3SZachary Turner #include "lldb/Symbol/CompileUnit.h"
31b9c1b51eSKate Stone #include "lldb/Symbol/SymbolContext.h"
3230fdc8d8SChris Lattner #include "lldb/Target/Process.h"
33b9ffa98cSJason Molenda #include "lldb/Target/Queue.h"
34f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h"
35b9c1b51eSKate Stone #include "lldb/Target/SystemRuntime.h"
3630fdc8d8SChris Lattner #include "lldb/Target/Target.h"
37b9c1b51eSKate Stone #include "lldb/Target/Thread.h"
3830fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h"
39b9c1b51eSKate Stone #include "lldb/Target/ThreadPlanStepInRange.h"
4030fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h"
4130fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h"
4230fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h"
43d821c997SPavel Labath #include "lldb/Utility/State.h"
44bf9a7730SZachary Turner #include "lldb/Utility/Stream.h"
45f2a8bccfSPavel Labath #include "lldb/Utility/StructuredData.h"
465bfee5f1SAbhishek Aggarwal #include "lldb/lldb-enumerations.h"
4730fdc8d8SChris Lattner 
48796ac80bSJonas Devlieghere #include <memory>
49796ac80bSJonas Devlieghere 
5030fdc8d8SChris Lattner using namespace lldb;
5130fdc8d8SChris Lattner using namespace lldb_private;
5230fdc8d8SChris Lattner 
53b9c1b51eSKate Stone const char *SBThread::GetBroadcasterClassName() {
54baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBThread,
55baf5664fSJonas Devlieghere                                     GetBroadcasterClassName);
56baf5664fSJonas Devlieghere 
574f465cffSJim Ingham   return Thread::GetStaticBroadcasterClass().AsCString();
584f465cffSJim Ingham }
594f465cffSJim Ingham 
60cfd1acedSGreg Clayton // Constructors
61baf5664fSJonas Devlieghere SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {
62baf5664fSJonas Devlieghere   LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBThread);
63baf5664fSJonas Devlieghere }
6430fdc8d8SChris Lattner 
65b9c1b51eSKate Stone SBThread::SBThread(const ThreadSP &lldb_object_sp)
66baf5664fSJonas Devlieghere     : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {
67baf5664fSJonas Devlieghere   LLDB_RECORD_CONSTRUCTOR(SBThread, (const lldb::ThreadSP &), lldb_object_sp);
68baf5664fSJonas Devlieghere }
6930fdc8d8SChris Lattner 
70bd4bf82aSJonas Devlieghere SBThread::SBThread(const SBThread &rhs) : m_opaque_sp() {
71baf5664fSJonas Devlieghere   LLDB_RECORD_CONSTRUCTOR(SBThread, (const lldb::SBThread &), rhs);
72baf5664fSJonas Devlieghere 
73bd4bf82aSJonas Devlieghere   m_opaque_sp = clone(rhs.m_opaque_sp);
74bd4bf82aSJonas Devlieghere }
7530fdc8d8SChris Lattner 
76cfd1acedSGreg Clayton // Assignment operator
77cfd1acedSGreg Clayton 
78b9c1b51eSKate Stone const lldb::SBThread &SBThread::operator=(const SBThread &rhs) {
79baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(const lldb::SBThread &,
80baf5664fSJonas Devlieghere                      SBThread, operator=,(const lldb::SBThread &), rhs);
81baf5664fSJonas Devlieghere 
82cfd1acedSGreg Clayton   if (this != &rhs)
83bd4bf82aSJonas Devlieghere     m_opaque_sp = clone(rhs.m_opaque_sp);
84306809f2SJonas Devlieghere   return LLDB_RECORD_RESULT(*this);
85cfd1acedSGreg Clayton }
86cfd1acedSGreg Clayton 
8730fdc8d8SChris Lattner // Destructor
88866b7a65SJonas Devlieghere SBThread::~SBThread() = default;
8930fdc8d8SChris Lattner 
90b9c1b51eSKate Stone lldb::SBQueue SBThread::GetQueue() const {
91baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBQueue, SBThread, GetQueue);
92baf5664fSJonas Devlieghere 
93b9ffa98cSJason Molenda   SBQueue sb_queue;
94b9ffa98cSJason Molenda   QueueSP queue_sp;
95bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
96bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
97b9ffa98cSJason Molenda 
98b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
99b9ffa98cSJason Molenda     Process::StopLocker stop_locker;
100b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
101b9ffa98cSJason Molenda       queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
102b9c1b51eSKate Stone       if (queue_sp) {
103b9ffa98cSJason Molenda         sb_queue.SetQueue(queue_sp);
104b9ffa98cSJason Molenda       }
105b9ffa98cSJason Molenda     }
106b9ffa98cSJason Molenda   }
107b9ffa98cSJason Molenda 
108baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_queue);
109b9ffa98cSJason Molenda }
110b9ffa98cSJason Molenda 
111b9c1b51eSKate Stone bool SBThread::IsValid() const {
112baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThread, IsValid);
1137f5237bcSPavel Labath   return this->operator bool();
1147f5237bcSPavel Labath }
1157f5237bcSPavel Labath SBThread::operator bool() const {
1167f5237bcSPavel Labath   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThread, operator bool);
117baf5664fSJonas Devlieghere 
118bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
119bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1207fa7dc36SJim Ingham 
1217fa7dc36SJim Ingham   Target *target = exe_ctx.GetTargetPtr();
1227fa7dc36SJim Ingham   Process *process = exe_ctx.GetProcessPtr();
123b9c1b51eSKate Stone   if (target && process) {
1247fa7dc36SJim Ingham     Process::StopLocker stop_locker;
1257fa7dc36SJim Ingham     if (stop_locker.TryLock(&process->GetRunLock()))
126248a1305SKonrad Kleine       return m_opaque_sp->GetThreadSP().get() != nullptr;
12730fdc8d8SChris Lattner   }
1287fa7dc36SJim Ingham   // Without a valid target & process, this thread can't be valid.
1297fa7dc36SJim Ingham   return false;
1307fa7dc36SJim Ingham }
13130fdc8d8SChris Lattner 
132baf5664fSJonas Devlieghere void SBThread::Clear() {
133baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(void, SBThread, Clear);
134baf5664fSJonas Devlieghere 
135baf5664fSJonas Devlieghere   m_opaque_sp->Clear();
136baf5664fSJonas Devlieghere }
13748e42549SGreg Clayton 
138b9c1b51eSKate Stone StopReason SBThread::GetStopReason() {
139baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::StopReason, SBThread, GetStopReason);
140baf5664fSJonas Devlieghere 
141ceb6b139SCaroline Tice   StopReason reason = eStopReasonInvalid;
142bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
143bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1444fc6cb9cSJim Ingham 
145b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1467fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
147b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
14897d5cf05SGreg Clayton       return exe_ctx.GetThreadPtr()->GetStopReason();
149c9858e4dSGreg Clayton     }
1507fdf9ef1SGreg Clayton   }
151ceb6b139SCaroline Tice 
152ceb6b139SCaroline Tice   return reason;
15330fdc8d8SChris Lattner }
15430fdc8d8SChris Lattner 
155b9c1b51eSKate Stone size_t SBThread::GetStopReasonDataCount() {
156baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(size_t, SBThread, GetStopReasonDataCount);
157baf5664fSJonas Devlieghere 
158bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
159bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1604fc6cb9cSJim Ingham 
161b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1627fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
163b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1641ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
165b9c1b51eSKate Stone       if (stop_info_sp) {
1664e78f606SGreg Clayton         StopReason reason = stop_info_sp->GetStopReason();
167b9c1b51eSKate Stone         switch (reason) {
1684e78f606SGreg Clayton         case eStopReasonInvalid:
1694e78f606SGreg Clayton         case eStopReasonNone:
1704e78f606SGreg Clayton         case eStopReasonTrace:
17190ba8115SGreg Clayton         case eStopReasonExec:
1724e78f606SGreg Clayton         case eStopReasonPlanComplete:
173f85defaeSAndrew Kaylor         case eStopReasonThreadExiting:
174afdf842bSKuba Brecka         case eStopReasonInstrumentation:
1754e78f606SGreg Clayton           // There is no data for these stop reasons.
1764e78f606SGreg Clayton           return 0;
1774e78f606SGreg Clayton 
178b9c1b51eSKate Stone         case eStopReasonBreakpoint: {
1794e78f606SGreg Clayton           break_id_t site_id = stop_info_sp->GetValue();
180b9c1b51eSKate Stone           lldb::BreakpointSiteSP bp_site_sp(
181b9c1b51eSKate Stone               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
182b9c1b51eSKate Stone                   site_id));
1834e78f606SGreg Clayton           if (bp_site_sp)
1844e78f606SGreg Clayton             return bp_site_sp->GetNumberOfOwners() * 2;
1854e78f606SGreg Clayton           else
1864e78f606SGreg Clayton             return 0; // Breakpoint must have cleared itself...
187b9c1b51eSKate Stone         } break;
1884e78f606SGreg Clayton 
1894e78f606SGreg Clayton         case eStopReasonWatchpoint:
190290fa41bSJohnny Chen           return 1;
1914e78f606SGreg Clayton 
1924e78f606SGreg Clayton         case eStopReasonSignal:
1934e78f606SGreg Clayton           return 1;
1944e78f606SGreg Clayton 
1954e78f606SGreg Clayton         case eStopReasonException:
1964e78f606SGreg Clayton           return 1;
1974e78f606SGreg Clayton         }
1984e78f606SGreg Clayton       }
199c9858e4dSGreg Clayton     }
2007fdf9ef1SGreg Clayton   }
2014e78f606SGreg Clayton   return 0;
2024e78f606SGreg Clayton }
2034e78f606SGreg Clayton 
204b9c1b51eSKate Stone uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
205baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(uint64_t, SBThread, GetStopReasonDataAtIndex, (uint32_t),
206baf5664fSJonas Devlieghere                      idx);
207baf5664fSJonas Devlieghere 
208bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
209bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
2104fc6cb9cSJim Ingham 
211b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
2127fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
213b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
2141ac04c30SGreg Clayton       Thread *thread = exe_ctx.GetThreadPtr();
2151ac04c30SGreg Clayton       StopInfoSP stop_info_sp = thread->GetStopInfo();
216b9c1b51eSKate Stone       if (stop_info_sp) {
2174e78f606SGreg Clayton         StopReason reason = stop_info_sp->GetStopReason();
218b9c1b51eSKate Stone         switch (reason) {
2194e78f606SGreg Clayton         case eStopReasonInvalid:
2204e78f606SGreg Clayton         case eStopReasonNone:
2214e78f606SGreg Clayton         case eStopReasonTrace:
22290ba8115SGreg Clayton         case eStopReasonExec:
2234e78f606SGreg Clayton         case eStopReasonPlanComplete:
224f85defaeSAndrew Kaylor         case eStopReasonThreadExiting:
225afdf842bSKuba Brecka         case eStopReasonInstrumentation:
2264e78f606SGreg Clayton           // There is no data for these stop reasons.
2274e78f606SGreg Clayton           return 0;
2284e78f606SGreg Clayton 
229b9c1b51eSKate Stone         case eStopReasonBreakpoint: {
2304e78f606SGreg Clayton           break_id_t site_id = stop_info_sp->GetValue();
231b9c1b51eSKate Stone           lldb::BreakpointSiteSP bp_site_sp(
232b9c1b51eSKate Stone               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
233b9c1b51eSKate Stone                   site_id));
234b9c1b51eSKate Stone           if (bp_site_sp) {
2354e78f606SGreg Clayton             uint32_t bp_index = idx / 2;
236b9c1b51eSKate Stone             BreakpointLocationSP bp_loc_sp(
237b9c1b51eSKate Stone                 bp_site_sp->GetOwnerAtIndex(bp_index));
238b9c1b51eSKate Stone             if (bp_loc_sp) {
239b9c1b51eSKate Stone               if (idx & 1) {
2404e78f606SGreg Clayton                 // Odd idx, return the breakpoint location ID
2414e78f606SGreg Clayton                 return bp_loc_sp->GetID();
242b9c1b51eSKate Stone               } else {
2434e78f606SGreg Clayton                 // Even idx, return the breakpoint ID
2444e78f606SGreg Clayton                 return bp_loc_sp->GetBreakpoint().GetID();
2454e78f606SGreg Clayton               }
2464e78f606SGreg Clayton             }
2474e78f606SGreg Clayton           }
2484e78f606SGreg Clayton           return LLDB_INVALID_BREAK_ID;
249b9c1b51eSKate Stone         } break;
2504e78f606SGreg Clayton 
2514e78f606SGreg Clayton         case eStopReasonWatchpoint:
252290fa41bSJohnny Chen           return stop_info_sp->GetValue();
2534e78f606SGreg Clayton 
2544e78f606SGreg Clayton         case eStopReasonSignal:
2554e78f606SGreg Clayton           return stop_info_sp->GetValue();
2564e78f606SGreg Clayton 
2574e78f606SGreg Clayton         case eStopReasonException:
2584e78f606SGreg Clayton           return stop_info_sp->GetValue();
2594e78f606SGreg Clayton         }
2604e78f606SGreg Clayton       }
261c9858e4dSGreg Clayton     }
2627fdf9ef1SGreg Clayton   }
2634e78f606SGreg Clayton   return 0;
2644e78f606SGreg Clayton }
2654e78f606SGreg Clayton 
266b9c1b51eSKate Stone bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) {
267baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, GetStopReasonExtendedInfoAsJSON,
268baf5664fSJonas Devlieghere                      (lldb::SBStream &), stream);
269baf5664fSJonas Devlieghere 
270afdf842bSKuba Brecka   Stream &strm = stream.ref();
271afdf842bSKuba Brecka 
272b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
273b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
274b2e7d28eSJim Ingham 
275afdf842bSKuba Brecka   if (!exe_ctx.HasThreadScope())
276afdf842bSKuba Brecka     return false;
277afdf842bSKuba Brecka 
278afdf842bSKuba Brecka   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
279afdf842bSKuba Brecka   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
280afdf842bSKuba Brecka   if (!info)
281afdf842bSKuba Brecka     return false;
282afdf842bSKuba Brecka 
283afdf842bSKuba Brecka   info->Dump(strm);
284afdf842bSKuba Brecka 
285afdf842bSKuba Brecka   return true;
286afdf842bSKuba Brecka }
287afdf842bSKuba Brecka 
2886a831436SKuba Brecka SBThreadCollection
289b9c1b51eSKate Stone SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
290baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBThreadCollection, SBThread,
291baf5664fSJonas Devlieghere                      GetStopReasonExtendedBacktraces,
292baf5664fSJonas Devlieghere                      (lldb::InstrumentationRuntimeType), type);
293baf5664fSJonas Devlieghere 
2945e3fe22cSJonas Devlieghere   SBThreadCollection threads;
2956a831436SKuba Brecka 
296b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
297b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
298b2e7d28eSJim Ingham 
2996a831436SKuba Brecka   if (!exe_ctx.HasThreadScope())
3005e3fe22cSJonas Devlieghere     return LLDB_RECORD_RESULT(SBThreadCollection());
3016a831436SKuba Brecka 
3026a831436SKuba Brecka   ProcessSP process_sp = exe_ctx.GetProcessSP();
3036a831436SKuba Brecka 
3046a831436SKuba Brecka   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
3056a831436SKuba Brecka   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
3066a831436SKuba Brecka   if (!info)
307baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(threads);
3086a831436SKuba Brecka 
3095e3fe22cSJonas Devlieghere   threads = process_sp->GetInstrumentationRuntime(type)
3105e3fe22cSJonas Devlieghere                 ->GetBacktracesFromExtendedStopInfo(info);
3115e3fe22cSJonas Devlieghere   return LLDB_RECORD_RESULT(threads);
3126a831436SKuba Brecka }
3136a831436SKuba Brecka 
314b9c1b51eSKate Stone size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
3153da7dcf3SJonas Devlieghere   LLDB_RECORD_METHOD(size_t, SBThread, GetStopDescription, (char *, size_t), "",
3163da7dcf3SJonas Devlieghere                      dst_len);
317baf5664fSJonas Devlieghere 
318bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
319bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3204fc6cb9cSJim Ingham 
32130fdc8d8SChris Lattner   if (dst)
32230fdc8d8SChris Lattner     *dst = 0;
323*20ce8affSFred Riss 
324*20ce8affSFred Riss   if (!exe_ctx.HasThreadScope())
32530fdc8d8SChris Lattner     return 0;
326*20ce8affSFred Riss 
327*20ce8affSFred Riss   Process::StopLocker stop_locker;
328*20ce8affSFred Riss   if (!stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
329*20ce8affSFred Riss     return 0;
330*20ce8affSFred Riss 
331*20ce8affSFred Riss   std::string thread_stop_desc = exe_ctx.GetThreadPtr()->GetStopDescription();
332*20ce8affSFred Riss   if (thread_stop_desc.empty())
333*20ce8affSFred Riss     return 0;
334*20ce8affSFred Riss 
335*20ce8affSFred Riss   if (dst)
336*20ce8affSFred Riss     return ::snprintf(dst, dst_len, "%s", thread_stop_desc.c_str()) + 1;
337*20ce8affSFred Riss 
338*20ce8affSFred Riss   // NULL dst passed in, return the length needed to contain the
339*20ce8affSFred Riss   // description.
340*20ce8affSFred Riss   return thread_stop_desc.size() + 1; // Include the NULL byte for size
34130fdc8d8SChris Lattner }
34230fdc8d8SChris Lattner 
343b9c1b51eSKate Stone SBValue SBThread::GetStopReturnValue() {
344baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBValue, SBThread, GetStopReturnValue);
345baf5664fSJonas Devlieghere 
34673ca05a2SJim Ingham   ValueObjectSP return_valobj_sp;
347bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
348bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3494fc6cb9cSJim Ingham 
350b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
3517fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
352b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
3531ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
354b9c1b51eSKate Stone       if (stop_info_sp) {
35573ca05a2SJim Ingham         return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp);
35673ca05a2SJim Ingham       }
357c9858e4dSGreg Clayton     }
3587fdf9ef1SGreg Clayton   }
35973ca05a2SJim Ingham 
360baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(SBValue(return_valobj_sp));
36173ca05a2SJim Ingham }
36273ca05a2SJim Ingham 
363b9c1b51eSKate Stone void SBThread::SetThread(const ThreadSP &lldb_object_sp) {
3647fdf9ef1SGreg Clayton   m_opaque_sp->SetThreadSP(lldb_object_sp);
36530fdc8d8SChris Lattner }
36630fdc8d8SChris Lattner 
367b9c1b51eSKate Stone lldb::tid_t SBThread::GetThreadID() const {
368baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::tid_t, SBThread, GetThreadID);
369baf5664fSJonas Devlieghere 
3707fdf9ef1SGreg Clayton   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
37117a6ad05SGreg Clayton   if (thread_sp)
3721ac04c30SGreg Clayton     return thread_sp->GetID();
3731ac04c30SGreg Clayton   return LLDB_INVALID_THREAD_ID;
37430fdc8d8SChris Lattner }
37530fdc8d8SChris Lattner 
376b9c1b51eSKate Stone uint32_t SBThread::GetIndexID() const {
377baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBThread, GetIndexID);
378baf5664fSJonas Devlieghere 
3797fdf9ef1SGreg Clayton   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
38017a6ad05SGreg Clayton   if (thread_sp)
38117a6ad05SGreg Clayton     return thread_sp->GetIndexID();
38230fdc8d8SChris Lattner   return LLDB_INVALID_INDEX32;
38330fdc8d8SChris Lattner }
3841ac04c30SGreg Clayton 
385b9c1b51eSKate Stone const char *SBThread::GetName() const {
386baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBThread, GetName);
387baf5664fSJonas Devlieghere 
388248a1305SKonrad Kleine   const char *name = nullptr;
389bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
390bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3914fc6cb9cSJim Ingham 
392b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
3937fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
394b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
3951ac04c30SGreg Clayton       name = exe_ctx.GetThreadPtr()->GetName();
396c9858e4dSGreg Clayton     }
3977fdf9ef1SGreg Clayton   }
398ceb6b139SCaroline Tice 
3994838131bSGreg Clayton   return name;
40030fdc8d8SChris Lattner }
40130fdc8d8SChris Lattner 
402b9c1b51eSKate Stone const char *SBThread::GetQueueName() const {
403baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBThread, GetQueueName);
404baf5664fSJonas Devlieghere 
405248a1305SKonrad Kleine   const char *name = nullptr;
406bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
407bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4084fc6cb9cSJim Ingham 
409b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4107fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
411b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4121ac04c30SGreg Clayton       name = exe_ctx.GetThreadPtr()->GetQueueName();
413c9858e4dSGreg Clayton     }
4147fdf9ef1SGreg Clayton   }
415ceb6b139SCaroline Tice 
4164838131bSGreg Clayton   return name;
41730fdc8d8SChris Lattner }
41830fdc8d8SChris Lattner 
419b9c1b51eSKate Stone lldb::queue_id_t SBThread::GetQueueID() const {
420baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::queue_id_t, SBThread, GetQueueID);
421baf5664fSJonas Devlieghere 
4224fdb5863SJason Molenda   queue_id_t id = LLDB_INVALID_QUEUE_ID;
423bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
424bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4254fdb5863SJason Molenda 
426b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4274fdb5863SJason Molenda     Process::StopLocker stop_locker;
428b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4294fdb5863SJason Molenda       id = exe_ctx.GetThreadPtr()->GetQueueID();
4304fdb5863SJason Molenda     }
4314fdb5863SJason Molenda   }
4324fdb5863SJason Molenda 
4334fdb5863SJason Molenda   return id;
4344fdb5863SJason Molenda }
4354fdb5863SJason Molenda 
436b9c1b51eSKate Stone bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
437baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, GetInfoItemByPathAsString,
438baf5664fSJonas Devlieghere                      (const char *, lldb::SBStream &), path, strm);
439baf5664fSJonas Devlieghere 
440705b1809SJason Molenda   bool success = false;
441bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
442bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
443705b1809SJason Molenda 
444b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
445705b1809SJason Molenda     Process::StopLocker stop_locker;
446b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
447705b1809SJason Molenda       Thread *thread = exe_ctx.GetThreadPtr();
448705b1809SJason Molenda       StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
449b9c1b51eSKate Stone       if (info_root_sp) {
450b9c1b51eSKate Stone         StructuredData::ObjectSP node =
451b9c1b51eSKate Stone             info_root_sp->GetObjectForDotSeparatedPath(path);
452b9c1b51eSKate Stone         if (node) {
4535bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeString) {
4542833321fSZachary Turner             strm.Printf("%s", node->GetAsString()->GetValue().str().c_str());
455705b1809SJason Molenda             success = true;
456705b1809SJason Molenda           }
4575bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeInteger) {
458705b1809SJason Molenda             strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue());
459705b1809SJason Molenda             success = true;
460705b1809SJason Molenda           }
4615bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeFloat) {
462705b1809SJason Molenda             strm.Printf("0x%f", node->GetAsFloat()->GetValue());
463705b1809SJason Molenda             success = true;
464705b1809SJason Molenda           }
4655bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeBoolean) {
466a6682a41SJonas Devlieghere             if (node->GetAsBoolean()->GetValue())
467705b1809SJason Molenda               strm.Printf("true");
468705b1809SJason Molenda             else
469705b1809SJason Molenda               strm.Printf("false");
470705b1809SJason Molenda             success = true;
471705b1809SJason Molenda           }
4725bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeNull) {
473705b1809SJason Molenda             strm.Printf("null");
474705b1809SJason Molenda             success = true;
475705b1809SJason Molenda           }
476705b1809SJason Molenda         }
477705b1809SJason Molenda       }
478705b1809SJason Molenda     }
479705b1809SJason Molenda   }
480705b1809SJason Molenda 
481705b1809SJason Molenda   return success;
482705b1809SJason Molenda }
483705b1809SJason Molenda 
484b9c1b51eSKate Stone SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
485b9c1b51eSKate Stone                                 ThreadPlan *new_plan) {
48664e7ead1SJim Ingham   SBError sb_error;
48764e7ead1SJim Ingham 
48864e7ead1SJim Ingham   Process *process = exe_ctx.GetProcessPtr();
489b9c1b51eSKate Stone   if (!process) {
49064e7ead1SJim Ingham     sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
49164e7ead1SJim Ingham     return sb_error;
49264e7ead1SJim Ingham   }
49364e7ead1SJim Ingham 
49464e7ead1SJim Ingham   Thread *thread = exe_ctx.GetThreadPtr();
495b9c1b51eSKate Stone   if (!thread) {
49664e7ead1SJim Ingham     sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
49764e7ead1SJim Ingham     return sb_error;
49864e7ead1SJim Ingham   }
49964e7ead1SJim Ingham 
500b9c1b51eSKate Stone   // User level plans should be Master Plans so they can be interrupted, other
50105097246SAdrian Prantl   // plans executed, and then a "continue" will resume the plan.
502248a1305SKonrad Kleine   if (new_plan != nullptr) {
50364e7ead1SJim Ingham     new_plan->SetIsMasterPlan(true);
50464e7ead1SJim Ingham     new_plan->SetOkayToDiscard(false);
50564e7ead1SJim Ingham   }
50664e7ead1SJim Ingham 
50764e7ead1SJim Ingham   // Why do we need to set the current thread by ID here???
50864e7ead1SJim Ingham   process->GetThreadList().SetSelectedThreadByID(thread->GetID());
50964e7ead1SJim Ingham 
510dc6224e0SGreg Clayton   if (process->GetTarget().GetDebugger().GetAsyncExecution())
511dc6224e0SGreg Clayton     sb_error.ref() = process->Resume();
512dc6224e0SGreg Clayton   else
513248a1305SKonrad Kleine     sb_error.ref() = process->ResumeSynchronous(nullptr);
51464e7ead1SJim Ingham 
51564e7ead1SJim Ingham   return sb_error;
51664e7ead1SJim Ingham }
51730fdc8d8SChris Lattner 
518b9c1b51eSKate Stone void SBThread::StepOver(lldb::RunMode stop_other_threads) {
519baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOver, (lldb::RunMode),
520baf5664fSJonas Devlieghere                      stop_other_threads);
521baf5664fSJonas Devlieghere 
522859f54b3SAlexander Polyakov   SBError error; // Ignored
523859f54b3SAlexander Polyakov   StepOver(stop_other_threads, error);
524859f54b3SAlexander Polyakov }
525859f54b3SAlexander Polyakov 
526859f54b3SAlexander Polyakov void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
527baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOver, (lldb::RunMode, lldb::SBError &),
528baf5664fSJonas Devlieghere                      stop_other_threads, error);
529baf5664fSJonas Devlieghere 
530bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
531bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
53217a6ad05SGreg Clayton 
533859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
534859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
535859f54b3SAlexander Polyakov     return;
536859f54b3SAlexander Polyakov   }
537859f54b3SAlexander Polyakov 
5381ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
5397ba6e991SJim Ingham   bool abort_other_plans = false;
540b57e4a1bSJason Molenda   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
54130fdc8d8SChris Lattner 
542e103ae92SJonas Devlieghere   Status new_plan_status;
5434d56e9c1SJim Ingham   ThreadPlanSP new_plan_sp;
544b9c1b51eSKate Stone   if (frame_sp) {
545b9c1b51eSKate Stone     if (frame_sp->HasDebugInformation()) {
5464b4b2478SJim Ingham       const LazyBool avoid_no_debug = eLazyBoolCalculate;
54730fdc8d8SChris Lattner       SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
548b9c1b51eSKate Stone       new_plan_sp = thread->QueueThreadPlanForStepOverRange(
549b9c1b51eSKate Stone           abort_other_plans, sc.line_entry, sc, stop_other_threads,
550e103ae92SJonas Devlieghere           new_plan_status, avoid_no_debug);
551b9c1b51eSKate Stone     } else {
552b9c1b51eSKate Stone       new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
553e103ae92SJonas Devlieghere           true, abort_other_plans, stop_other_threads, new_plan_status);
55430fdc8d8SChris Lattner     }
55530fdc8d8SChris Lattner   }
556859f54b3SAlexander Polyakov   error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
55730fdc8d8SChris Lattner }
55830fdc8d8SChris Lattner 
559b9c1b51eSKate Stone void SBThread::StepInto(lldb::RunMode stop_other_threads) {
560baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInto, (lldb::RunMode),
561baf5664fSJonas Devlieghere                      stop_other_threads);
562baf5664fSJonas Devlieghere 
563248a1305SKonrad Kleine   StepInto(nullptr, stop_other_threads);
564c627682eSJim Ingham }
565c627682eSJim Ingham 
566b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name,
567b9c1b51eSKate Stone                         lldb::RunMode stop_other_threads) {
568baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInto, (const char *, lldb::RunMode),
569baf5664fSJonas Devlieghere                      target_name, stop_other_threads);
570baf5664fSJonas Devlieghere 
571859f54b3SAlexander Polyakov   SBError error; // Ignored
572cbf6f9b2SJim Ingham   StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
573cbf6f9b2SJim Ingham }
574cbf6f9b2SJim Ingham 
575b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name, uint32_t end_line,
576b9c1b51eSKate Stone                         SBError &error, lldb::RunMode stop_other_threads) {
577baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInto,
578baf5664fSJonas Devlieghere                      (const char *, uint32_t, lldb::SBError &, lldb::RunMode),
579baf5664fSJonas Devlieghere                      target_name, end_line, error, stop_other_threads);
580baf5664fSJonas Devlieghere 
581ceb6b139SCaroline Tice 
582bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
583bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
58417a6ad05SGreg Clayton 
585859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
586859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
587859f54b3SAlexander Polyakov     return;
588859f54b3SAlexander Polyakov   }
589859f54b3SAlexander Polyakov 
5907ba6e991SJim Ingham   bool abort_other_plans = false;
59130fdc8d8SChris Lattner 
5921ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
593b57e4a1bSJason Molenda   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
5944d56e9c1SJim Ingham   ThreadPlanSP new_plan_sp;
595e103ae92SJonas Devlieghere   Status new_plan_status;
59630fdc8d8SChris Lattner 
597b9c1b51eSKate Stone   if (frame_sp && frame_sp->HasDebugInformation()) {
598cbf6f9b2SJim Ingham     SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
599cbf6f9b2SJim Ingham     AddressRange range;
600cbf6f9b2SJim Ingham     if (end_line == LLDB_INVALID_LINE_NUMBER)
601cbf6f9b2SJim Ingham       range = sc.line_entry.range;
602b9c1b51eSKate Stone     else {
603cbf6f9b2SJim Ingham       if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
604cbf6f9b2SJim Ingham         return;
605cbf6f9b2SJim Ingham     }
606cbf6f9b2SJim Ingham 
607b9c1b51eSKate Stone     const LazyBool step_out_avoids_code_without_debug_info =
608b9c1b51eSKate Stone         eLazyBoolCalculate;
609b9c1b51eSKate Stone     const LazyBool step_in_avoids_code_without_debug_info =
610b9c1b51eSKate Stone         eLazyBoolCalculate;
611b9c1b51eSKate Stone     new_plan_sp = thread->QueueThreadPlanForStepInRange(
612b9c1b51eSKate Stone         abort_other_plans, range, sc, target_name, stop_other_threads,
613e103ae92SJonas Devlieghere         new_plan_status, step_in_avoids_code_without_debug_info,
6144b4b2478SJim Ingham         step_out_avoids_code_without_debug_info);
615b9c1b51eSKate Stone   } else {
616b9c1b51eSKate Stone     new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
617e103ae92SJonas Devlieghere         false, abort_other_plans, stop_other_threads, new_plan_status);
61830fdc8d8SChris Lattner   }
619e103ae92SJonas Devlieghere 
620e103ae92SJonas Devlieghere   if (new_plan_status.Success())
621cbf6f9b2SJim Ingham     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
622e103ae92SJonas Devlieghere   else
623e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
62430fdc8d8SChris Lattner }
62530fdc8d8SChris Lattner 
626b9c1b51eSKate Stone void SBThread::StepOut() {
627baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(void, SBThread, StepOut);
628baf5664fSJonas Devlieghere 
629859f54b3SAlexander Polyakov   SBError error; // Ignored
630859f54b3SAlexander Polyakov   StepOut(error);
631859f54b3SAlexander Polyakov }
632859f54b3SAlexander Polyakov 
633859f54b3SAlexander Polyakov void SBThread::StepOut(SBError &error) {
634baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOut, (lldb::SBError &), error);
635baf5664fSJonas Devlieghere 
636bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
637bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
6384fc6cb9cSJim Ingham 
639859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
640859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
641859f54b3SAlexander Polyakov     return;
642859f54b3SAlexander Polyakov   }
643859f54b3SAlexander Polyakov 
6447ba6e991SJim Ingham   bool abort_other_plans = false;
64594b09246SJim Ingham   bool stop_other_threads = false;
64630fdc8d8SChris Lattner 
6471ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
6481ac04c30SGreg Clayton 
6494b4b2478SJim Ingham   const LazyBool avoid_no_debug = eLazyBoolCalculate;
650e103ae92SJonas Devlieghere   Status new_plan_status;
651b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
652248a1305SKonrad Kleine       abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
653e103ae92SJonas Devlieghere       eVoteNoOpinion, 0, new_plan_status, avoid_no_debug));
654481cef25SGreg Clayton 
655e103ae92SJonas Devlieghere   if (new_plan_status.Success())
656859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
657e103ae92SJonas Devlieghere   else
658e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
659481cef25SGreg Clayton }
660481cef25SGreg Clayton 
661859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
662baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOutOfFrame, (lldb::SBFrame &),
663baf5664fSJonas Devlieghere                      sb_frame);
664baf5664fSJonas Devlieghere 
665859f54b3SAlexander Polyakov   SBError error; // Ignored
666859f54b3SAlexander Polyakov   StepOutOfFrame(sb_frame, error);
667859f54b3SAlexander Polyakov }
668859f54b3SAlexander Polyakov 
669859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
670baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOutOfFrame,
671baf5664fSJonas Devlieghere                      (lldb::SBFrame &, lldb::SBError &), sb_frame, error);
672baf5664fSJonas Devlieghere 
673481cef25SGreg Clayton 
674bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
675bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
6764fc6cb9cSJim Ingham 
677b9c1b51eSKate Stone   if (!sb_frame.IsValid()) {
678859f54b3SAlexander Polyakov     error.SetErrorString("passed invalid SBFrame object");
679989a7558SJim Ingham     return;
680989a7558SJim Ingham   }
681989a7558SJim Ingham 
682b57e4a1bSJason Molenda   StackFrameSP frame_sp(sb_frame.GetFrameSP());
683481cef25SGreg Clayton 
684859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
685859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
686859f54b3SAlexander Polyakov     return;
687859f54b3SAlexander Polyakov   }
688859f54b3SAlexander Polyakov 
6897ba6e991SJim Ingham   bool abort_other_plans = false;
69094b09246SJim Ingham   bool stop_other_threads = false;
6911ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
692b9c1b51eSKate Stone   if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
693859f54b3SAlexander Polyakov     error.SetErrorString("passed a frame from another thread");
694859f54b3SAlexander Polyakov     return;
695989a7558SJim Ingham   }
696481cef25SGreg Clayton 
697e103ae92SJonas Devlieghere   Status new_plan_status;
698b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
699248a1305SKonrad Kleine       abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
700e103ae92SJonas Devlieghere       eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status));
70130fdc8d8SChris Lattner 
702e103ae92SJonas Devlieghere   if (new_plan_status.Success())
703859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
704e103ae92SJonas Devlieghere   else
705e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
70630fdc8d8SChris Lattner }
70730fdc8d8SChris Lattner 
708b9c1b51eSKate Stone void SBThread::StepInstruction(bool step_over) {
709baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInstruction, (bool), step_over);
710baf5664fSJonas Devlieghere 
711859f54b3SAlexander Polyakov   SBError error; // Ignored
712859f54b3SAlexander Polyakov   StepInstruction(step_over, error);
713859f54b3SAlexander Polyakov }
714859f54b3SAlexander Polyakov 
715859f54b3SAlexander Polyakov void SBThread::StepInstruction(bool step_over, SBError &error) {
716baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInstruction, (bool, lldb::SBError &),
717baf5664fSJonas Devlieghere                      step_over, error);
718baf5664fSJonas Devlieghere 
719bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
720bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
721ceb6b139SCaroline Tice 
722859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
723859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
724859f54b3SAlexander Polyakov     return;
725859f54b3SAlexander Polyakov   }
726859f54b3SAlexander Polyakov 
7271ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
728e103ae92SJonas Devlieghere   Status new_plan_status;
729e103ae92SJonas Devlieghere   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction(
730e103ae92SJonas Devlieghere       step_over, true, true, new_plan_status));
73164e7ead1SJim Ingham 
732e103ae92SJonas Devlieghere   if (new_plan_status.Success())
733859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
734e103ae92SJonas Devlieghere   else
735e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
73630fdc8d8SChris Lattner }
73730fdc8d8SChris Lattner 
738b9c1b51eSKate Stone void SBThread::RunToAddress(lldb::addr_t addr) {
739baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, RunToAddress, (lldb::addr_t), addr);
740baf5664fSJonas Devlieghere 
741859f54b3SAlexander Polyakov   SBError error; // Ignored
742859f54b3SAlexander Polyakov   RunToAddress(addr, error);
743859f54b3SAlexander Polyakov }
744859f54b3SAlexander Polyakov 
745859f54b3SAlexander Polyakov void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
746baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, RunToAddress,
747baf5664fSJonas Devlieghere                      (lldb::addr_t, lldb::SBError &), addr, error);
748baf5664fSJonas Devlieghere 
749bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
750bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
751ceb6b139SCaroline Tice 
752859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
753859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
754859f54b3SAlexander Polyakov     return;
755859f54b3SAlexander Polyakov   }
756859f54b3SAlexander Polyakov 
7577ba6e991SJim Ingham   bool abort_other_plans = false;
75830fdc8d8SChris Lattner   bool stop_other_threads = true;
75930fdc8d8SChris Lattner 
760e72dfb32SGreg Clayton   Address target_addr(addr);
76130fdc8d8SChris Lattner 
7621ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
7631ac04c30SGreg Clayton 
764e103ae92SJonas Devlieghere   Status new_plan_status;
765b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
766e103ae92SJonas Devlieghere       abort_other_plans, target_addr, stop_other_threads, new_plan_status));
76764e7ead1SJim Ingham 
768e103ae92SJonas Devlieghere   if (new_plan_status.Success())
769859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
770e103ae92SJonas Devlieghere   else
771e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
77230fdc8d8SChris Lattner }
77330fdc8d8SChris Lattner 
774b9c1b51eSKate Stone SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
775b9c1b51eSKate Stone                                 lldb::SBFileSpec &sb_file_spec, uint32_t line) {
776baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepOverUntil,
777baf5664fSJonas Devlieghere                      (lldb::SBFrame &, lldb::SBFileSpec &, uint32_t), sb_frame,
778baf5664fSJonas Devlieghere                      sb_file_spec, line);
779baf5664fSJonas Devlieghere 
780481cef25SGreg Clayton   SBError sb_error;
781481cef25SGreg Clayton   char path[PATH_MAX];
782481cef25SGreg Clayton 
783bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
784bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
7854fc6cb9cSJim Ingham 
786b57e4a1bSJason Molenda   StackFrameSP frame_sp(sb_frame.GetFrameSP());
78717a6ad05SGreg Clayton 
788b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
7891ac04c30SGreg Clayton     Target *target = exe_ctx.GetTargetPtr();
7901ac04c30SGreg Clayton     Thread *thread = exe_ctx.GetThreadPtr();
791481cef25SGreg Clayton 
792b9c1b51eSKate Stone     if (line == 0) {
793481cef25SGreg Clayton       sb_error.SetErrorString("invalid line argument");
794baf5664fSJonas Devlieghere       return LLDB_RECORD_RESULT(sb_error);
795481cef25SGreg Clayton     }
796481cef25SGreg Clayton 
797b9c1b51eSKate Stone     if (!frame_sp) {
7981ac04c30SGreg Clayton       frame_sp = thread->GetSelectedFrame();
799481cef25SGreg Clayton       if (!frame_sp)
8001ac04c30SGreg Clayton         frame_sp = thread->GetStackFrameAtIndex(0);
801481cef25SGreg Clayton     }
802481cef25SGreg Clayton 
803481cef25SGreg Clayton     SymbolContext frame_sc;
804b9c1b51eSKate Stone     if (!frame_sp) {
805481cef25SGreg Clayton       sb_error.SetErrorString("no valid frames in thread to step");
806baf5664fSJonas Devlieghere       return LLDB_RECORD_RESULT(sb_error);
807481cef25SGreg Clayton     }
808481cef25SGreg Clayton 
809481cef25SGreg Clayton     // If we have a frame, get its line
810b9c1b51eSKate Stone     frame_sc = frame_sp->GetSymbolContext(
811b9c1b51eSKate Stone         eSymbolContextCompUnit | eSymbolContextFunction |
812b9c1b51eSKate Stone         eSymbolContextLineEntry | eSymbolContextSymbol);
813481cef25SGreg Clayton 
814248a1305SKonrad Kleine     if (frame_sc.comp_unit == nullptr) {
815b9c1b51eSKate Stone       sb_error.SetErrorStringWithFormat(
816b9c1b51eSKate Stone           "frame %u doesn't have debug information", frame_sp->GetFrameIndex());
817baf5664fSJonas Devlieghere       return LLDB_RECORD_RESULT(sb_error);
818481cef25SGreg Clayton     }
819481cef25SGreg Clayton 
820481cef25SGreg Clayton     FileSpec step_file_spec;
821b9c1b51eSKate Stone     if (sb_file_spec.IsValid()) {
822481cef25SGreg Clayton       // The file spec passed in was valid, so use it
823481cef25SGreg Clayton       step_file_spec = sb_file_spec.ref();
824b9c1b51eSKate Stone     } else {
825481cef25SGreg Clayton       if (frame_sc.line_entry.IsValid())
826481cef25SGreg Clayton         step_file_spec = frame_sc.line_entry.file;
827b9c1b51eSKate Stone       else {
828481cef25SGreg Clayton         sb_error.SetErrorString("invalid file argument or no file for frame");
829baf5664fSJonas Devlieghere         return LLDB_RECORD_RESULT(sb_error);
830481cef25SGreg Clayton       }
831481cef25SGreg Clayton     }
832481cef25SGreg Clayton 
8339b70ddb3SJim Ingham     // Grab the current function, then we will make sure the "until" address is
8349b70ddb3SJim Ingham     // within the function.  We discard addresses that are out of the current
835b9c1b51eSKate Stone     // function, and then if there are no addresses remaining, give an
83605097246SAdrian Prantl     // appropriate error message.
8379b70ddb3SJim Ingham 
8389b70ddb3SJim Ingham     bool all_in_function = true;
8399b70ddb3SJim Ingham     AddressRange fun_range = frame_sc.function->GetAddressRange();
8409b70ddb3SJim Ingham 
841481cef25SGreg Clayton     std::vector<addr_t> step_over_until_addrs;
8427ba6e991SJim Ingham     const bool abort_other_plans = false;
843c02e3344SJim Ingham     const bool stop_other_threads = false;
844481cef25SGreg Clayton     const bool check_inlines = true;
845481cef25SGreg Clayton     const bool exact = false;
846481cef25SGreg Clayton 
847481cef25SGreg Clayton     SymbolContextList sc_list;
848c671639aSKonrad Kleine     frame_sc.comp_unit->ResolveSymbolContext(step_file_spec, line,
849c671639aSKonrad Kleine                                              check_inlines, exact,
850c671639aSKonrad Kleine                                              eSymbolContextLineEntry, sc_list);
851c671639aSKonrad Kleine     const uint32_t num_matches = sc_list.GetSize();
852b9c1b51eSKate Stone     if (num_matches > 0) {
853481cef25SGreg Clayton       SymbolContext sc;
854b9c1b51eSKate Stone       for (uint32_t i = 0; i < num_matches; ++i) {
855b9c1b51eSKate Stone         if (sc_list.GetContextAtIndex(i, sc)) {
856b9c1b51eSKate Stone           addr_t step_addr =
857b9c1b51eSKate Stone               sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
858b9c1b51eSKate Stone           if (step_addr != LLDB_INVALID_ADDRESS) {
8599b70ddb3SJim Ingham             if (fun_range.ContainsLoadAddress(step_addr, target))
860481cef25SGreg Clayton               step_over_until_addrs.push_back(step_addr);
8619b70ddb3SJim Ingham             else
8629b70ddb3SJim Ingham               all_in_function = false;
863481cef25SGreg Clayton           }
864481cef25SGreg Clayton         }
865481cef25SGreg Clayton       }
866481cef25SGreg Clayton     }
867481cef25SGreg Clayton 
868b9c1b51eSKate Stone     if (step_over_until_addrs.empty()) {
869b9c1b51eSKate Stone       if (all_in_function) {
870481cef25SGreg Clayton         step_file_spec.GetPath(path, sizeof(path));
871b9c1b51eSKate Stone         sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path,
872b9c1b51eSKate Stone                                           line);
873b9c1b51eSKate Stone       } else
87486edbf41SGreg Clayton         sb_error.SetErrorString("step until target not in current function");
875b9c1b51eSKate Stone     } else {
876e103ae92SJonas Devlieghere       Status new_plan_status;
877b9c1b51eSKate Stone       ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil(
878b9c1b51eSKate Stone           abort_other_plans, &step_over_until_addrs[0],
879b9c1b51eSKate Stone           step_over_until_addrs.size(), stop_other_threads,
880e103ae92SJonas Devlieghere           frame_sp->GetFrameIndex(), new_plan_status));
881481cef25SGreg Clayton 
882e103ae92SJonas Devlieghere       if (new_plan_status.Success())
8834d56e9c1SJim Ingham         sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
884e103ae92SJonas Devlieghere       else
885e103ae92SJonas Devlieghere         sb_error.SetErrorString(new_plan_status.AsCString());
886481cef25SGreg Clayton     }
887b9c1b51eSKate Stone   } else {
888481cef25SGreg Clayton     sb_error.SetErrorString("this SBThread object is invalid");
889481cef25SGreg Clayton   }
890baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
891481cef25SGreg Clayton }
892481cef25SGreg Clayton 
893b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) {
894baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
895baf5664fSJonas Devlieghere                      (const char *), script_class_name);
896baf5664fSJonas Devlieghere 
897baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
898baf5664fSJonas Devlieghere       StepUsingScriptedThreadPlan(script_class_name, true));
899c915a7d2SJim Ingham }
900c915a7d2SJim Ingham 
901b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
902b9c1b51eSKate Stone                                             bool resume_immediately) {
903baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
904baf5664fSJonas Devlieghere                      (const char *, bool), script_class_name,
905baf5664fSJonas Devlieghere                      resume_immediately);
906baf5664fSJonas Devlieghere 
90727a14f19SJim Ingham   lldb::SBStructuredData no_data;
9083da7dcf3SJonas Devlieghere   return LLDB_RECORD_RESULT(StepUsingScriptedThreadPlan(
9093da7dcf3SJonas Devlieghere       script_class_name, no_data, resume_immediately));
91027a14f19SJim Ingham }
91127a14f19SJim Ingham 
91227a14f19SJim Ingham SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
91327a14f19SJim Ingham                                               SBStructuredData &args_data,
91427a14f19SJim Ingham                                               bool resume_immediately) {
91527a14f19SJim Ingham   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
91627a14f19SJim Ingham                      (const char *, lldb::SBStructuredData &, bool),
9173da7dcf3SJonas Devlieghere                      script_class_name, args_data, resume_immediately);
91827a14f19SJim Ingham 
919e103ae92SJonas Devlieghere   SBError error;
9202bdbfd50SJim Ingham 
921bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
922bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
9232bdbfd50SJim Ingham 
924b9c1b51eSKate Stone   if (!exe_ctx.HasThreadScope()) {
925e103ae92SJonas Devlieghere     error.SetErrorString("this SBThread object is invalid");
926baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(error);
9272bdbfd50SJim Ingham   }
9282bdbfd50SJim Ingham 
9292bdbfd50SJim Ingham   Thread *thread = exe_ctx.GetThreadPtr();
930e103ae92SJonas Devlieghere   Status new_plan_status;
93127a14f19SJim Ingham   StructuredData::ObjectSP obj_sp = args_data.m_impl_up->GetObjectSP();
93227a14f19SJim Ingham 
933e103ae92SJonas Devlieghere   ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted(
93427a14f19SJim Ingham       false, script_class_name, obj_sp, false, new_plan_status);
9352bdbfd50SJim Ingham 
936e103ae92SJonas Devlieghere   if (new_plan_status.Fail()) {
937e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
938baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(error);
939c915a7d2SJim Ingham   }
940c915a7d2SJim Ingham 
941e103ae92SJonas Devlieghere   if (!resume_immediately)
942baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(error);
943c915a7d2SJim Ingham 
944e103ae92SJonas Devlieghere   if (new_plan_status.Success())
945e103ae92SJonas Devlieghere     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
946e103ae92SJonas Devlieghere   else
947e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
9482bdbfd50SJim Ingham 
949baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(error);
9502bdbfd50SJim Ingham }
9512bdbfd50SJim Ingham 
952b9c1b51eSKate Stone SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
953baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, JumpToLine,
954baf5664fSJonas Devlieghere                      (lldb::SBFileSpec &, uint32_t), file_spec, line);
955baf5664fSJonas Devlieghere 
956f86248d9SRichard Mitton   SBError sb_error;
957f86248d9SRichard Mitton 
958bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
959bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
960f86248d9SRichard Mitton 
961b9c1b51eSKate Stone   if (!exe_ctx.HasThreadScope()) {
962f86248d9SRichard Mitton     sb_error.SetErrorString("this SBThread object is invalid");
963baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(sb_error);
964f86248d9SRichard Mitton   }
965f86248d9SRichard Mitton 
966f86248d9SRichard Mitton   Thread *thread = exe_ctx.GetThreadPtr();
967f86248d9SRichard Mitton 
96828e4942bSPavel Labath   Status err = thread->JumpToLine(file_spec.ref(), line, true);
969f86248d9SRichard Mitton   sb_error.SetError(err);
970baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
971f86248d9SRichard Mitton }
972f86248d9SRichard Mitton 
973b9c1b51eSKate Stone SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
974baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, ReturnFromFrame,
975baf5664fSJonas Devlieghere                      (lldb::SBFrame &, lldb::SBValue &), frame, return_value);
976baf5664fSJonas Devlieghere 
9774413758cSJim Ingham   SBError sb_error;
9784413758cSJim Ingham 
979bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
980bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
9814413758cSJim Ingham 
982b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
9834413758cSJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
984b9c1b51eSKate Stone     sb_error.SetError(
985b9c1b51eSKate Stone         thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
9864413758cSJim Ingham   }
9874413758cSJim Ingham 
988baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
9894413758cSJim Ingham }
9904413758cSJim Ingham 
991b9c1b51eSKate Stone SBError SBThread::UnwindInnermostExpression() {
992baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBError, SBThread,
993baf5664fSJonas Devlieghere                              UnwindInnermostExpression);
994baf5664fSJonas Devlieghere 
9954ac8e93aSJim Ingham   SBError sb_error;
9964ac8e93aSJim Ingham 
9974ac8e93aSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
9984ac8e93aSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
9994ac8e93aSJim Ingham 
1000b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
10014ac8e93aSJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
10024ac8e93aSJim Ingham     sb_error.SetError(thread->UnwindInnermostExpression());
10034ac8e93aSJim Ingham     if (sb_error.Success())
10044ac8e93aSJim Ingham       thread->SetSelectedFrameByIndex(0, false);
10054ac8e93aSJim Ingham   }
10064ac8e93aSJim Ingham 
1007baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
10084ac8e93aSJim Ingham }
1009481cef25SGreg Clayton 
1010b9c1b51eSKate Stone bool SBThread::Suspend() {
1011baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, Suspend);
1012baf5664fSJonas Devlieghere 
1013859f54b3SAlexander Polyakov   SBError error; // Ignored
1014859f54b3SAlexander Polyakov   return Suspend(error);
1015859f54b3SAlexander Polyakov }
1016859f54b3SAlexander Polyakov 
1017859f54b3SAlexander Polyakov bool SBThread::Suspend(SBError &error) {
1018baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, Suspend, (lldb::SBError &), error);
1019baf5664fSJonas Devlieghere 
1020b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1021b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1022b2e7d28eSJim Ingham 
1023c9858e4dSGreg Clayton   bool result = false;
1024b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1025c9858e4dSGreg Clayton     Process::StopLocker stop_locker;
1026b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
10271ac04c30SGreg Clayton       exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
1028c9858e4dSGreg Clayton       result = true;
1029b9c1b51eSKate Stone     } else {
1030859f54b3SAlexander Polyakov       error.SetErrorString("process is running");
1031c9858e4dSGreg Clayton     }
1032859f54b3SAlexander Polyakov   } else
1033859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
1034c9858e4dSGreg Clayton   return result;
1035722a0cdcSGreg Clayton }
1036722a0cdcSGreg Clayton 
1037b9c1b51eSKate Stone bool SBThread::Resume() {
1038baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, Resume);
1039baf5664fSJonas Devlieghere 
1040859f54b3SAlexander Polyakov   SBError error; // Ignored
1041859f54b3SAlexander Polyakov   return Resume(error);
1042859f54b3SAlexander Polyakov }
1043859f54b3SAlexander Polyakov 
1044859f54b3SAlexander Polyakov bool SBThread::Resume(SBError &error) {
1045baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, Resume, (lldb::SBError &), error);
1046baf5664fSJonas Devlieghere 
1047b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1048b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1049b2e7d28eSJim Ingham 
1050c9858e4dSGreg Clayton   bool result = false;
1051b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1052c9858e4dSGreg Clayton     Process::StopLocker stop_locker;
1053b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
10546c9ed91cSJim Ingham       const bool override_suspend = true;
10556c9ed91cSJim Ingham       exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
1056c9858e4dSGreg Clayton       result = true;
1057b9c1b51eSKate Stone     } else {
1058859f54b3SAlexander Polyakov       error.SetErrorString("process is running");
1059c9858e4dSGreg Clayton     }
1060859f54b3SAlexander Polyakov   } else
1061859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
1062c9858e4dSGreg Clayton   return result;
1063722a0cdcSGreg Clayton }
1064722a0cdcSGreg Clayton 
1065b9c1b51eSKate Stone bool SBThread::IsSuspended() {
1066baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, IsSuspended);
1067baf5664fSJonas Devlieghere 
1068b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1069b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1070b2e7d28eSJim Ingham 
10711ac04c30SGreg Clayton   if (exe_ctx.HasThreadScope())
10721ac04c30SGreg Clayton     return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
1073722a0cdcSGreg Clayton   return false;
1074722a0cdcSGreg Clayton }
1075722a0cdcSGreg Clayton 
1076b9c1b51eSKate Stone bool SBThread::IsStopped() {
1077baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, IsStopped);
1078baf5664fSJonas Devlieghere 
1079b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1080b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1081b2e7d28eSJim Ingham 
1082a75418dbSAndrew Kaylor   if (exe_ctx.HasThreadScope())
1083a75418dbSAndrew Kaylor     return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1084a75418dbSAndrew Kaylor   return false;
1085a75418dbSAndrew Kaylor }
1086a75418dbSAndrew Kaylor 
1087b9c1b51eSKate Stone SBProcess SBThread::GetProcess() {
1088baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBProcess, SBThread, GetProcess);
1089baf5664fSJonas Devlieghere 
1090b9556accSGreg Clayton   SBProcess sb_process;
1091b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1092b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1093b2e7d28eSJim Ingham 
1094b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1095b9c1b51eSKate Stone     // Have to go up to the target so we can get a shared pointer to our
1096b9c1b51eSKate Stone     // process...
10971ac04c30SGreg Clayton     sb_process.SetSP(exe_ctx.GetProcessSP());
109830fdc8d8SChris Lattner   }
1099ceb6b139SCaroline Tice 
1100baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_process);
110130fdc8d8SChris Lattner }
110230fdc8d8SChris Lattner 
1103b9c1b51eSKate Stone uint32_t SBThread::GetNumFrames() {
1104baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBThread, GetNumFrames);
1105baf5664fSJonas Devlieghere 
1106ceb6b139SCaroline Tice   uint32_t num_frames = 0;
1107bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1108bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11094fc6cb9cSJim Ingham 
1110b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11117fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1112b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11131ac04c30SGreg Clayton       num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1114c9858e4dSGreg Clayton     }
11157fdf9ef1SGreg Clayton   }
1116ceb6b139SCaroline Tice 
1117ceb6b139SCaroline Tice   return num_frames;
111830fdc8d8SChris Lattner }
111930fdc8d8SChris Lattner 
1120b9c1b51eSKate Stone SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
1121baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBFrame, SBThread, GetFrameAtIndex, (uint32_t), idx);
1122baf5664fSJonas Devlieghere 
112330fdc8d8SChris Lattner   SBFrame sb_frame;
1124b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1125bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1126bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11274fc6cb9cSJim Ingham 
1128b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11297fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1130b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11311ac04c30SGreg Clayton       frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
1132b9556accSGreg Clayton       sb_frame.SetFrameSP(frame_sp);
1133c9858e4dSGreg Clayton     }
11347fdf9ef1SGreg Clayton   }
1135ceb6b139SCaroline Tice 
1136baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_frame);
113730fdc8d8SChris Lattner }
113830fdc8d8SChris Lattner 
1139b9c1b51eSKate Stone lldb::SBFrame SBThread::GetSelectedFrame() {
1140baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBFrame, SBThread, GetSelectedFrame);
1141baf5664fSJonas Devlieghere 
1142f028a1fbSGreg Clayton   SBFrame sb_frame;
1143b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1144bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1145bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11464fc6cb9cSJim Ingham 
1147b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11487fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1149b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11501ac04c30SGreg Clayton       frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame();
1151b9556accSGreg Clayton       sb_frame.SetFrameSP(frame_sp);
1152c9858e4dSGreg Clayton     }
11537fdf9ef1SGreg Clayton   }
1154f028a1fbSGreg Clayton 
1155baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_frame);
1156f028a1fbSGreg Clayton }
1157f028a1fbSGreg Clayton 
1158b9c1b51eSKate Stone lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
1159baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBFrame, SBThread, SetSelectedFrame, (uint32_t),
1160baf5664fSJonas Devlieghere                      idx);
1161baf5664fSJonas Devlieghere 
1162f028a1fbSGreg Clayton   SBFrame sb_frame;
1163b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1164bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1165bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11664fc6cb9cSJim Ingham 
1167b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11687fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1169b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11701ac04c30SGreg Clayton       Thread *thread = exe_ctx.GetThreadPtr();
11711ac04c30SGreg Clayton       frame_sp = thread->GetStackFrameAtIndex(idx);
1172b9c1b51eSKate Stone       if (frame_sp) {
11731ac04c30SGreg Clayton         thread->SetSelectedFrame(frame_sp.get());
1174b9556accSGreg Clayton         sb_frame.SetFrameSP(frame_sp);
1175f028a1fbSGreg Clayton       }
1176c9858e4dSGreg Clayton     }
11777fdf9ef1SGreg Clayton   }
1178f028a1fbSGreg Clayton 
1179baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_frame);
1180f028a1fbSGreg Clayton }
1181f028a1fbSGreg Clayton 
1182b9c1b51eSKate Stone bool SBThread::EventIsThreadEvent(const SBEvent &event) {
1183baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(bool, SBThread, EventIsThreadEvent,
1184baf5664fSJonas Devlieghere                             (const lldb::SBEvent &), event);
1185baf5664fSJonas Devlieghere 
1186248a1305SKonrad Kleine   return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != nullptr;
11874f465cffSJim Ingham }
11884f465cffSJim Ingham 
1189b9c1b51eSKate Stone SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) {
1190baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(lldb::SBFrame, SBThread, GetStackFrameFromEvent,
1191baf5664fSJonas Devlieghere                             (const lldb::SBEvent &), event);
1192baf5664fSJonas Devlieghere 
1193baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
1194baf5664fSJonas Devlieghere       Thread::ThreadEventData::GetStackFrameFromEvent(event.get()));
11954f465cffSJim Ingham }
11964f465cffSJim Ingham 
1197b9c1b51eSKate Stone SBThread SBThread::GetThreadFromEvent(const SBEvent &event) {
1198baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(lldb::SBThread, SBThread, GetThreadFromEvent,
1199baf5664fSJonas Devlieghere                             (const lldb::SBEvent &), event);
1200baf5664fSJonas Devlieghere 
1201baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
1202baf5664fSJonas Devlieghere       Thread::ThreadEventData::GetThreadFromEvent(event.get()));
12034f465cffSJim Ingham }
1204f028a1fbSGreg Clayton 
1205b9c1b51eSKate Stone bool SBThread::operator==(const SBThread &rhs) const {
1206baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, operator==,(const lldb::SBThread &),
1207baf5664fSJonas Devlieghere                            rhs);
1208baf5664fSJonas Devlieghere 
1209b9c1b51eSKate Stone   return m_opaque_sp->GetThreadSP().get() ==
1210b9c1b51eSKate Stone          rhs.m_opaque_sp->GetThreadSP().get();
121130fdc8d8SChris Lattner }
121230fdc8d8SChris Lattner 
1213b9c1b51eSKate Stone bool SBThread::operator!=(const SBThread &rhs) const {
1214baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, operator!=,(const lldb::SBThread &),
1215baf5664fSJonas Devlieghere                            rhs);
1216baf5664fSJonas Devlieghere 
1217b9c1b51eSKate Stone   return m_opaque_sp->GetThreadSP().get() !=
1218b9c1b51eSKate Stone          rhs.m_opaque_sp->GetThreadSP().get();
121930fdc8d8SChris Lattner }
1220dde9cff3SCaroline Tice 
1221b9c1b51eSKate Stone bool SBThread::GetStatus(SBStream &status) const {
1222baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetStatus, (lldb::SBStream &),
1223baf5664fSJonas Devlieghere                            status);
1224baf5664fSJonas Devlieghere 
12254f465cffSJim Ingham   Stream &strm = status.ref();
12264f465cffSJim Ingham 
1227b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1228b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1229b2e7d28eSJim Ingham 
1230b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
12316a9767c7SJim Ingham     exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true);
1232b9c1b51eSKate Stone   } else
12334f465cffSJim Ingham     strm.PutCString("No status");
12344f465cffSJim Ingham 
12354f465cffSJim Ingham   return true;
12364f465cffSJim Ingham }
12374f465cffSJim Ingham 
1238b9c1b51eSKate Stone bool SBThread::GetDescription(SBStream &description) const {
1239baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetDescription, (lldb::SBStream &),
1240baf5664fSJonas Devlieghere                            description);
1241baf5664fSJonas Devlieghere 
12426a9767c7SJim Ingham   return GetDescription(description, false);
12436a9767c7SJim Ingham }
12446a9767c7SJim Ingham 
12456a9767c7SJim Ingham bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
1246baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetDescription,
1247baf5664fSJonas Devlieghere                            (lldb::SBStream &, bool), description, stop_format);
1248baf5664fSJonas Devlieghere 
1249da7bc7d0SGreg Clayton   Stream &strm = description.ref();
1250da7bc7d0SGreg Clayton 
1251b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1252b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1253b2e7d28eSJim Ingham 
1254b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1255b9c1b51eSKate Stone     exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm,
12566a9767c7SJim Ingham                                                     LLDB_INVALID_THREAD_ID,
12576a9767c7SJim Ingham                                                     stop_format);
1258b9c1b51eSKate Stone     // strm.Printf("SBThread: tid = 0x%4.4" PRIx64,
1259b9c1b51eSKate Stone     // exe_ctx.GetThreadPtr()->GetID());
1260b9c1b51eSKate Stone   } else
1261da7bc7d0SGreg Clayton     strm.PutCString("No value");
1262ceb6b139SCaroline Tice 
1263ceb6b139SCaroline Tice   return true;
1264ceb6b139SCaroline Tice }
12655dd4916fSJason Molenda 
1266b9c1b51eSKate Stone SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
1267baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBThread, SBThread, GetExtendedBacktraceThread,
1268baf5664fSJonas Devlieghere                      (const char *), type);
1269baf5664fSJonas Devlieghere 
1270bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1271bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12725dd4916fSJason Molenda   SBThread sb_origin_thread;
12735dd4916fSJason Molenda 
12745dd4916fSJason Molenda   Process::StopLocker stop_locker;
1275b9c1b51eSKate Stone   if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1276b78094abSJim Ingham     if (exe_ctx.HasThreadScope()) {
12777a2f7904SJason Molenda       ThreadSP real_thread(exe_ctx.GetThreadSP());
1278b9c1b51eSKate Stone       if (real_thread) {
12795dd4916fSJason Molenda         ConstString type_const(type);
12807a2f7904SJason Molenda         Process *process = exe_ctx.GetProcessPtr();
1281b9c1b51eSKate Stone         if (process) {
12827a2f7904SJason Molenda           SystemRuntime *runtime = process->GetSystemRuntime();
1283b9c1b51eSKate Stone           if (runtime) {
1284b9c1b51eSKate Stone             ThreadSP new_thread_sp(
1285b9c1b51eSKate Stone                 runtime->GetExtendedBacktraceThread(real_thread, type_const));
1286b9c1b51eSKate Stone             if (new_thread_sp) {
1287b9c1b51eSKate Stone               // Save this in the Process' ExtendedThreadList so a strong
128805097246SAdrian Prantl               // pointer retains the object.
12897a2f7904SJason Molenda               process->GetExtendedThreadList().AddThread(new_thread_sp);
12907a2f7904SJason Molenda               sb_origin_thread.SetThread(new_thread_sp);
1291a6e9130dSJason Molenda             }
1292a6e9130dSJason Molenda           }
12937a2f7904SJason Molenda         }
12945dd4916fSJason Molenda       }
12955dd4916fSJason Molenda     }
12965dd4916fSJason Molenda   }
12975dd4916fSJason Molenda 
1298baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_origin_thread);
12995dd4916fSJason Molenda }
13008ee9cb58SJason Molenda 
1301b9c1b51eSKate Stone uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
1302baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBThread,
1303baf5664fSJonas Devlieghere                              GetExtendedBacktraceOriginatingIndexID);
1304baf5664fSJonas Devlieghere 
13058ee9cb58SJason Molenda   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
13068ee9cb58SJason Molenda   if (thread_sp)
13078ee9cb58SJason Molenda     return thread_sp->GetExtendedBacktraceOriginatingIndexID();
13088ee9cb58SJason Molenda   return LLDB_INVALID_INDEX32;
13098ee9cb58SJason Molenda }
1310b4892cd2SJason Molenda 
1311e60bc53bSKuba Mracek SBValue SBThread::GetCurrentException() {
1312baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBValue, SBThread, GetCurrentException);
1313e60bc53bSKuba Mracek 
1314baf5664fSJonas Devlieghere   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1315baf5664fSJonas Devlieghere   if (!thread_sp)
1316baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(SBValue());
1317baf5664fSJonas Devlieghere 
1318baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(SBValue(thread_sp->GetCurrentException()));
1319e60bc53bSKuba Mracek }
1320e60bc53bSKuba Mracek 
1321e60bc53bSKuba Mracek SBThread SBThread::GetCurrentExceptionBacktrace() {
1322baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBThread, SBThread,
1323baf5664fSJonas Devlieghere                              GetCurrentExceptionBacktrace);
1324e60bc53bSKuba Mracek 
1325baf5664fSJonas Devlieghere   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1326baf5664fSJonas Devlieghere   if (!thread_sp)
1327baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(SBThread());
1328baf5664fSJonas Devlieghere 
1329baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
1330baf5664fSJonas Devlieghere       SBThread(thread_sp->GetCurrentExceptionBacktrace()));
1331c9e1190aSKuba Mracek }
1332e60bc53bSKuba Mracek 
1333b9c1b51eSKate Stone bool SBThread::SafeToCallFunctions() {
1334baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, SafeToCallFunctions);
1335baf5664fSJonas Devlieghere 
1336b4892cd2SJason Molenda   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1337b4892cd2SJason Molenda   if (thread_sp)
1338b4892cd2SJason Molenda     return thread_sp->SafeToCallFunctions();
1339b4892cd2SJason Molenda   return true;
1340b4892cd2SJason Molenda }
13412bdbfd50SJim Ingham 
1342b9c1b51eSKate Stone lldb_private::Thread *SBThread::operator->() {
134326ca5a57SPavel Labath   return get();
13442bdbfd50SJim Ingham }
13452bdbfd50SJim Ingham 
1346b9c1b51eSKate Stone lldb_private::Thread *SBThread::get() {
134726ca5a57SPavel Labath   return m_opaque_sp->GetThreadSP().get();
13482bdbfd50SJim Ingham }
1349ae211eceSMichal Gorny 
1350ae211eceSMichal Gorny namespace lldb_private {
1351ae211eceSMichal Gorny namespace repro {
1352ae211eceSMichal Gorny 
1353ae211eceSMichal Gorny template <>
1354ae211eceSMichal Gorny void RegisterMethods<SBThread>(Registry &R) {
1355ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(const char *, SBThread, GetBroadcasterClassName,
1356ae211eceSMichal Gorny                               ());
1357ae211eceSMichal Gorny   LLDB_REGISTER_CONSTRUCTOR(SBThread, ());
1358ae211eceSMichal Gorny   LLDB_REGISTER_CONSTRUCTOR(SBThread, (const lldb::ThreadSP &));
1359ae211eceSMichal Gorny   LLDB_REGISTER_CONSTRUCTOR(SBThread, (const lldb::SBThread &));
1360ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(const lldb::SBThread &,
1361ae211eceSMichal Gorny                        SBThread, operator=,(const lldb::SBThread &));
1362ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(lldb::SBQueue, SBThread, GetQueue, ());
1363ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, IsValid, ());
1364ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, operator bool, ());
1365ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, Clear, ());
1366ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::StopReason, SBThread, GetStopReason, ());
1367ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(size_t, SBThread, GetStopReasonDataCount, ());
1368ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(uint64_t, SBThread, GetStopReasonDataAtIndex,
1369ae211eceSMichal Gorny                        (uint32_t));
1370ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, GetStopReasonExtendedInfoAsJSON,
1371ae211eceSMichal Gorny                        (lldb::SBStream &));
1372ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBThreadCollection, SBThread,
1373ae211eceSMichal Gorny                        GetStopReasonExtendedBacktraces,
1374ae211eceSMichal Gorny                        (lldb::InstrumentationRuntimeType));
1375ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBValue, SBThread, GetStopReturnValue, ());
1376ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(lldb::tid_t, SBThread, GetThreadID, ());
1377ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(uint32_t, SBThread, GetIndexID, ());
1378ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(const char *, SBThread, GetName, ());
1379ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(const char *, SBThread, GetQueueName, ());
1380ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(lldb::queue_id_t, SBThread, GetQueueID, ());
1381ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, GetInfoItemByPathAsString,
1382ae211eceSMichal Gorny                        (const char *, lldb::SBStream &));
1383ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOver, (lldb::RunMode));
1384ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOver,
1385ae211eceSMichal Gorny                        (lldb::RunMode, lldb::SBError &));
1386ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInto, (lldb::RunMode));
1387ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInto,
1388ae211eceSMichal Gorny                        (const char *, lldb::RunMode));
1389ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(
1390ae211eceSMichal Gorny       void, SBThread, StepInto,
1391ae211eceSMichal Gorny       (const char *, uint32_t, lldb::SBError &, lldb::RunMode));
1392ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOut, ());
1393ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOut, (lldb::SBError &));
1394ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOutOfFrame, (lldb::SBFrame &));
1395ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOutOfFrame,
1396ae211eceSMichal Gorny                        (lldb::SBFrame &, lldb::SBError &));
1397ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInstruction, (bool));
1398ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInstruction,
1399ae211eceSMichal Gorny                        (bool, lldb::SBError &));
1400ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, RunToAddress, (lldb::addr_t));
1401ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, RunToAddress,
1402ae211eceSMichal Gorny                        (lldb::addr_t, lldb::SBError &));
1403ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepOverUntil,
1404ae211eceSMichal Gorny                        (lldb::SBFrame &, lldb::SBFileSpec &, uint32_t));
1405ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
1406ae211eceSMichal Gorny                        (const char *));
1407ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
1408ae211eceSMichal Gorny                        (const char *, bool));
140927a14f19SJim Ingham   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
141027a14f19SJim Ingham                        (const char *, SBStructuredData &, bool));
1411ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, JumpToLine,
1412ae211eceSMichal Gorny                        (lldb::SBFileSpec &, uint32_t));
1413ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, ReturnFromFrame,
1414ae211eceSMichal Gorny                        (lldb::SBFrame &, lldb::SBValue &));
1415ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, UnwindInnermostExpression,
1416ae211eceSMichal Gorny                        ());
1417ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Suspend, ());
1418ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Suspend, (lldb::SBError &));
1419ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Resume, ());
1420ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Resume, (lldb::SBError &));
1421ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, IsSuspended, ());
1422ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, IsStopped, ());
1423ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBProcess, SBThread, GetProcess, ());
1424ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(uint32_t, SBThread, GetNumFrames, ());
1425ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, GetFrameAtIndex, (uint32_t));
1426ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, GetSelectedFrame, ());
1427ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, SetSelectedFrame, (uint32_t));
1428ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(bool, SBThread, EventIsThreadEvent,
1429ae211eceSMichal Gorny                               (const lldb::SBEvent &));
1430ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(lldb::SBFrame, SBThread, GetStackFrameFromEvent,
1431ae211eceSMichal Gorny                               (const lldb::SBEvent &));
1432ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(lldb::SBThread, SBThread, GetThreadFromEvent,
1433ae211eceSMichal Gorny                               (const lldb::SBEvent &));
1434ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool,
1435ae211eceSMichal Gorny                              SBThread, operator==,(const lldb::SBThread &));
1436ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool,
1437ae211eceSMichal Gorny                              SBThread, operator!=,(const lldb::SBThread &));
1438ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetStatus, (lldb::SBStream &));
1439ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetDescription,
1440ae211eceSMichal Gorny                              (lldb::SBStream &));
1441ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetDescription,
1442ae211eceSMichal Gorny                              (lldb::SBStream &, bool));
1443ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBThread, SBThread, GetExtendedBacktraceThread,
1444ae211eceSMichal Gorny                        (const char *));
1445ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(uint32_t, SBThread,
1446ae211eceSMichal Gorny                        GetExtendedBacktraceOriginatingIndexID, ());
1447ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBValue, SBThread, GetCurrentException, ());
1448ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBThread, SBThread, GetCurrentExceptionBacktrace,
1449ae211eceSMichal Gorny                        ());
1450ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, SafeToCallFunctions, ());
14512f025bb8SJonas Devlieghere   LLDB_REGISTER_CHAR_PTR_REDIRECT(size_t, SBThread, GetStopDescription);
1452ae211eceSMichal Gorny }
1453ae211eceSMichal Gorny 
1454ae211eceSMichal Gorny }
1455ae211eceSMichal Gorny }
1456