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:
175*0b697561SWalter Erquinigo         case eStopReasonProcessorTrace:
1764e78f606SGreg Clayton           // There is no data for these stop reasons.
1774e78f606SGreg Clayton           return 0;
1784e78f606SGreg Clayton 
179b9c1b51eSKate Stone         case eStopReasonBreakpoint: {
1804e78f606SGreg Clayton           break_id_t site_id = stop_info_sp->GetValue();
181b9c1b51eSKate Stone           lldb::BreakpointSiteSP bp_site_sp(
182b9c1b51eSKate Stone               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
183b9c1b51eSKate Stone                   site_id));
1844e78f606SGreg Clayton           if (bp_site_sp)
1854e78f606SGreg Clayton             return bp_site_sp->GetNumberOfOwners() * 2;
1864e78f606SGreg Clayton           else
1874e78f606SGreg Clayton             return 0; // Breakpoint must have cleared itself...
188b9c1b51eSKate Stone         } break;
1894e78f606SGreg Clayton 
1904e78f606SGreg Clayton         case eStopReasonWatchpoint:
191290fa41bSJohnny Chen           return 1;
1924e78f606SGreg Clayton 
1934e78f606SGreg Clayton         case eStopReasonSignal:
1944e78f606SGreg Clayton           return 1;
1954e78f606SGreg Clayton 
1964e78f606SGreg Clayton         case eStopReasonException:
1974e78f606SGreg Clayton           return 1;
1984e78f606SGreg Clayton         }
1994e78f606SGreg Clayton       }
200c9858e4dSGreg Clayton     }
2017fdf9ef1SGreg Clayton   }
2024e78f606SGreg Clayton   return 0;
2034e78f606SGreg Clayton }
2044e78f606SGreg Clayton 
205b9c1b51eSKate Stone uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
206baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(uint64_t, SBThread, GetStopReasonDataAtIndex, (uint32_t),
207baf5664fSJonas Devlieghere                      idx);
208baf5664fSJonas Devlieghere 
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:
227*0b697561SWalter Erquinigo         case eStopReasonProcessorTrace:
2284e78f606SGreg Clayton           // There is no data for these stop reasons.
2294e78f606SGreg Clayton           return 0;
2304e78f606SGreg Clayton 
231b9c1b51eSKate Stone         case eStopReasonBreakpoint: {
2324e78f606SGreg Clayton           break_id_t site_id = stop_info_sp->GetValue();
233b9c1b51eSKate Stone           lldb::BreakpointSiteSP bp_site_sp(
234b9c1b51eSKate Stone               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
235b9c1b51eSKate Stone                   site_id));
236b9c1b51eSKate Stone           if (bp_site_sp) {
2374e78f606SGreg Clayton             uint32_t bp_index = idx / 2;
238b9c1b51eSKate Stone             BreakpointLocationSP bp_loc_sp(
239b9c1b51eSKate Stone                 bp_site_sp->GetOwnerAtIndex(bp_index));
240b9c1b51eSKate Stone             if (bp_loc_sp) {
241b9c1b51eSKate Stone               if (idx & 1) {
2424e78f606SGreg Clayton                 // Odd idx, return the breakpoint location ID
2434e78f606SGreg Clayton                 return bp_loc_sp->GetID();
244b9c1b51eSKate Stone               } else {
2454e78f606SGreg Clayton                 // Even idx, return the breakpoint ID
2464e78f606SGreg Clayton                 return bp_loc_sp->GetBreakpoint().GetID();
2474e78f606SGreg Clayton               }
2484e78f606SGreg Clayton             }
2494e78f606SGreg Clayton           }
2504e78f606SGreg Clayton           return LLDB_INVALID_BREAK_ID;
251b9c1b51eSKate Stone         } break;
2524e78f606SGreg Clayton 
2534e78f606SGreg Clayton         case eStopReasonWatchpoint:
254290fa41bSJohnny Chen           return stop_info_sp->GetValue();
2554e78f606SGreg Clayton 
2564e78f606SGreg Clayton         case eStopReasonSignal:
2574e78f606SGreg Clayton           return stop_info_sp->GetValue();
2584e78f606SGreg Clayton 
2594e78f606SGreg Clayton         case eStopReasonException:
2604e78f606SGreg Clayton           return stop_info_sp->GetValue();
2614e78f606SGreg Clayton         }
2624e78f606SGreg Clayton       }
263c9858e4dSGreg Clayton     }
2647fdf9ef1SGreg Clayton   }
2654e78f606SGreg Clayton   return 0;
2664e78f606SGreg Clayton }
2674e78f606SGreg Clayton 
268b9c1b51eSKate Stone bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) {
269baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, GetStopReasonExtendedInfoAsJSON,
270baf5664fSJonas Devlieghere                      (lldb::SBStream &), stream);
271baf5664fSJonas Devlieghere 
272afdf842bSKuba Brecka   Stream &strm = stream.ref();
273afdf842bSKuba Brecka 
274b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
275b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
276b2e7d28eSJim Ingham 
277afdf842bSKuba Brecka   if (!exe_ctx.HasThreadScope())
278afdf842bSKuba Brecka     return false;
279afdf842bSKuba Brecka 
280afdf842bSKuba Brecka   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
281afdf842bSKuba Brecka   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
282afdf842bSKuba Brecka   if (!info)
283afdf842bSKuba Brecka     return false;
284afdf842bSKuba Brecka 
285afdf842bSKuba Brecka   info->Dump(strm);
286afdf842bSKuba Brecka 
287afdf842bSKuba Brecka   return true;
288afdf842bSKuba Brecka }
289afdf842bSKuba Brecka 
2906a831436SKuba Brecka SBThreadCollection
291b9c1b51eSKate Stone SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
292baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBThreadCollection, SBThread,
293baf5664fSJonas Devlieghere                      GetStopReasonExtendedBacktraces,
294baf5664fSJonas Devlieghere                      (lldb::InstrumentationRuntimeType), type);
295baf5664fSJonas Devlieghere 
2965e3fe22cSJonas Devlieghere   SBThreadCollection threads;
2976a831436SKuba Brecka 
298b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
299b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
300b2e7d28eSJim Ingham 
3016a831436SKuba Brecka   if (!exe_ctx.HasThreadScope())
3025e3fe22cSJonas Devlieghere     return LLDB_RECORD_RESULT(SBThreadCollection());
3036a831436SKuba Brecka 
3046a831436SKuba Brecka   ProcessSP process_sp = exe_ctx.GetProcessSP();
3056a831436SKuba Brecka 
3066a831436SKuba Brecka   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
3076a831436SKuba Brecka   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
3086a831436SKuba Brecka   if (!info)
309baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(threads);
3106a831436SKuba Brecka 
3115e3fe22cSJonas Devlieghere   threads = process_sp->GetInstrumentationRuntime(type)
3125e3fe22cSJonas Devlieghere                 ->GetBacktracesFromExtendedStopInfo(info);
3135e3fe22cSJonas Devlieghere   return LLDB_RECORD_RESULT(threads);
3146a831436SKuba Brecka }
3156a831436SKuba Brecka 
316b9c1b51eSKate Stone size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
317e687aa82SJonas Devlieghere   LLDB_RECORD_CHAR_PTR_METHOD(size_t, SBThread, GetStopDescription,
318e687aa82SJonas Devlieghere                               (char *, size_t), dst, "", dst_len);
319baf5664fSJonas Devlieghere 
320bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
321bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3224fc6cb9cSJim Ingham 
32330fdc8d8SChris Lattner   if (dst)
32430fdc8d8SChris Lattner     *dst = 0;
32520ce8affSFred Riss 
32620ce8affSFred Riss   if (!exe_ctx.HasThreadScope())
32730fdc8d8SChris Lattner     return 0;
32820ce8affSFred Riss 
32920ce8affSFred Riss   Process::StopLocker stop_locker;
33020ce8affSFred Riss   if (!stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
33120ce8affSFred Riss     return 0;
33220ce8affSFred Riss 
33320ce8affSFred Riss   std::string thread_stop_desc = exe_ctx.GetThreadPtr()->GetStopDescription();
33420ce8affSFred Riss   if (thread_stop_desc.empty())
33520ce8affSFred Riss     return 0;
33620ce8affSFred Riss 
33720ce8affSFred Riss   if (dst)
33820ce8affSFred Riss     return ::snprintf(dst, dst_len, "%s", thread_stop_desc.c_str()) + 1;
33920ce8affSFred Riss 
34020ce8affSFred Riss   // NULL dst passed in, return the length needed to contain the
34120ce8affSFred Riss   // description.
34220ce8affSFred Riss   return thread_stop_desc.size() + 1; // Include the NULL byte for size
34330fdc8d8SChris Lattner }
34430fdc8d8SChris Lattner 
345b9c1b51eSKate Stone SBValue SBThread::GetStopReturnValue() {
346baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBValue, SBThread, GetStopReturnValue);
347baf5664fSJonas Devlieghere 
34873ca05a2SJim Ingham   ValueObjectSP return_valobj_sp;
349bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
350bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3514fc6cb9cSJim Ingham 
352b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
3537fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
354b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
3551ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
356b9c1b51eSKate Stone       if (stop_info_sp) {
35773ca05a2SJim Ingham         return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp);
35873ca05a2SJim Ingham       }
359c9858e4dSGreg Clayton     }
3607fdf9ef1SGreg Clayton   }
36173ca05a2SJim Ingham 
362baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(SBValue(return_valobj_sp));
36373ca05a2SJim Ingham }
36473ca05a2SJim Ingham 
365b9c1b51eSKate Stone void SBThread::SetThread(const ThreadSP &lldb_object_sp) {
3667fdf9ef1SGreg Clayton   m_opaque_sp->SetThreadSP(lldb_object_sp);
36730fdc8d8SChris Lattner }
36830fdc8d8SChris Lattner 
369b9c1b51eSKate Stone lldb::tid_t SBThread::GetThreadID() const {
370baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::tid_t, SBThread, GetThreadID);
371baf5664fSJonas Devlieghere 
3727fdf9ef1SGreg Clayton   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
37317a6ad05SGreg Clayton   if (thread_sp)
3741ac04c30SGreg Clayton     return thread_sp->GetID();
3751ac04c30SGreg Clayton   return LLDB_INVALID_THREAD_ID;
37630fdc8d8SChris Lattner }
37730fdc8d8SChris Lattner 
378b9c1b51eSKate Stone uint32_t SBThread::GetIndexID() const {
379baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBThread, GetIndexID);
380baf5664fSJonas Devlieghere 
3817fdf9ef1SGreg Clayton   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
38217a6ad05SGreg Clayton   if (thread_sp)
38317a6ad05SGreg Clayton     return thread_sp->GetIndexID();
38430fdc8d8SChris Lattner   return LLDB_INVALID_INDEX32;
38530fdc8d8SChris Lattner }
3861ac04c30SGreg Clayton 
387b9c1b51eSKate Stone const char *SBThread::GetName() const {
388baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBThread, GetName);
389baf5664fSJonas Devlieghere 
390248a1305SKonrad Kleine   const char *name = nullptr;
391bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
392bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3934fc6cb9cSJim Ingham 
394b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
3957fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
396b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
3971ac04c30SGreg Clayton       name = exe_ctx.GetThreadPtr()->GetName();
398c9858e4dSGreg Clayton     }
3997fdf9ef1SGreg Clayton   }
400ceb6b139SCaroline Tice 
4014838131bSGreg Clayton   return name;
40230fdc8d8SChris Lattner }
40330fdc8d8SChris Lattner 
404b9c1b51eSKate Stone const char *SBThread::GetQueueName() const {
405baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBThread, GetQueueName);
406baf5664fSJonas Devlieghere 
407248a1305SKonrad Kleine   const char *name = nullptr;
408bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
409bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4104fc6cb9cSJim Ingham 
411b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4127fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
413b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4141ac04c30SGreg Clayton       name = exe_ctx.GetThreadPtr()->GetQueueName();
415c9858e4dSGreg Clayton     }
4167fdf9ef1SGreg Clayton   }
417ceb6b139SCaroline Tice 
4184838131bSGreg Clayton   return name;
41930fdc8d8SChris Lattner }
42030fdc8d8SChris Lattner 
421b9c1b51eSKate Stone lldb::queue_id_t SBThread::GetQueueID() const {
422baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::queue_id_t, SBThread, GetQueueID);
423baf5664fSJonas Devlieghere 
4244fdb5863SJason Molenda   queue_id_t id = LLDB_INVALID_QUEUE_ID;
425bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
426bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4274fdb5863SJason Molenda 
428b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4294fdb5863SJason Molenda     Process::StopLocker stop_locker;
430b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4314fdb5863SJason Molenda       id = exe_ctx.GetThreadPtr()->GetQueueID();
4324fdb5863SJason Molenda     }
4334fdb5863SJason Molenda   }
4344fdb5863SJason Molenda 
4354fdb5863SJason Molenda   return id;
4364fdb5863SJason Molenda }
4374fdb5863SJason Molenda 
438b9c1b51eSKate Stone bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
439baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, GetInfoItemByPathAsString,
440baf5664fSJonas Devlieghere                      (const char *, lldb::SBStream &), path, strm);
441baf5664fSJonas Devlieghere 
442705b1809SJason Molenda   bool success = false;
443bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
444bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
445705b1809SJason Molenda 
446b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
447705b1809SJason Molenda     Process::StopLocker stop_locker;
448b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
449705b1809SJason Molenda       Thread *thread = exe_ctx.GetThreadPtr();
450705b1809SJason Molenda       StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
451b9c1b51eSKate Stone       if (info_root_sp) {
452b9c1b51eSKate Stone         StructuredData::ObjectSP node =
453b9c1b51eSKate Stone             info_root_sp->GetObjectForDotSeparatedPath(path);
454b9c1b51eSKate Stone         if (node) {
4555bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeString) {
4562833321fSZachary Turner             strm.Printf("%s", node->GetAsString()->GetValue().str().c_str());
457705b1809SJason Molenda             success = true;
458705b1809SJason Molenda           }
4595bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeInteger) {
460705b1809SJason Molenda             strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue());
461705b1809SJason Molenda             success = true;
462705b1809SJason Molenda           }
4635bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeFloat) {
464705b1809SJason Molenda             strm.Printf("0x%f", node->GetAsFloat()->GetValue());
465705b1809SJason Molenda             success = true;
466705b1809SJason Molenda           }
4675bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeBoolean) {
468a6682a41SJonas Devlieghere             if (node->GetAsBoolean()->GetValue())
469705b1809SJason Molenda               strm.Printf("true");
470705b1809SJason Molenda             else
471705b1809SJason Molenda               strm.Printf("false");
472705b1809SJason Molenda             success = true;
473705b1809SJason Molenda           }
4745bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeNull) {
475705b1809SJason Molenda             strm.Printf("null");
476705b1809SJason Molenda             success = true;
477705b1809SJason Molenda           }
478705b1809SJason Molenda         }
479705b1809SJason Molenda       }
480705b1809SJason Molenda     }
481705b1809SJason Molenda   }
482705b1809SJason Molenda 
483705b1809SJason Molenda   return success;
484705b1809SJason Molenda }
485705b1809SJason Molenda 
486b9c1b51eSKate Stone SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
487b9c1b51eSKate Stone                                 ThreadPlan *new_plan) {
48864e7ead1SJim Ingham   SBError sb_error;
48964e7ead1SJim Ingham 
49064e7ead1SJim Ingham   Process *process = exe_ctx.GetProcessPtr();
491b9c1b51eSKate Stone   if (!process) {
49264e7ead1SJim Ingham     sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
49364e7ead1SJim Ingham     return sb_error;
49464e7ead1SJim Ingham   }
49564e7ead1SJim Ingham 
49664e7ead1SJim Ingham   Thread *thread = exe_ctx.GetThreadPtr();
497b9c1b51eSKate Stone   if (!thread) {
49864e7ead1SJim Ingham     sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
49964e7ead1SJim Ingham     return sb_error;
50064e7ead1SJim Ingham   }
50164e7ead1SJim Ingham 
502b9c1b51eSKate Stone   // User level plans should be Master Plans so they can be interrupted, other
50305097246SAdrian Prantl   // plans executed, and then a "continue" will resume the plan.
504248a1305SKonrad Kleine   if (new_plan != nullptr) {
50564e7ead1SJim Ingham     new_plan->SetIsMasterPlan(true);
50664e7ead1SJim Ingham     new_plan->SetOkayToDiscard(false);
50764e7ead1SJim Ingham   }
50864e7ead1SJim Ingham 
50964e7ead1SJim Ingham   // Why do we need to set the current thread by ID here???
51064e7ead1SJim Ingham   process->GetThreadList().SetSelectedThreadByID(thread->GetID());
51164e7ead1SJim Ingham 
512dc6224e0SGreg Clayton   if (process->GetTarget().GetDebugger().GetAsyncExecution())
513dc6224e0SGreg Clayton     sb_error.ref() = process->Resume();
514dc6224e0SGreg Clayton   else
515248a1305SKonrad Kleine     sb_error.ref() = process->ResumeSynchronous(nullptr);
51664e7ead1SJim Ingham 
51764e7ead1SJim Ingham   return sb_error;
51864e7ead1SJim Ingham }
51930fdc8d8SChris Lattner 
520b9c1b51eSKate Stone void SBThread::StepOver(lldb::RunMode stop_other_threads) {
521baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOver, (lldb::RunMode),
522baf5664fSJonas Devlieghere                      stop_other_threads);
523baf5664fSJonas Devlieghere 
524859f54b3SAlexander Polyakov   SBError error; // Ignored
525859f54b3SAlexander Polyakov   StepOver(stop_other_threads, error);
526859f54b3SAlexander Polyakov }
527859f54b3SAlexander Polyakov 
528859f54b3SAlexander Polyakov void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
529baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOver, (lldb::RunMode, lldb::SBError &),
530baf5664fSJonas Devlieghere                      stop_other_threads, error);
531baf5664fSJonas Devlieghere 
532bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
533bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
53417a6ad05SGreg Clayton 
535859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
536859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
537859f54b3SAlexander Polyakov     return;
538859f54b3SAlexander Polyakov   }
539859f54b3SAlexander Polyakov 
5401ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
5417ba6e991SJim Ingham   bool abort_other_plans = false;
542b57e4a1bSJason Molenda   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
54330fdc8d8SChris Lattner 
544e103ae92SJonas Devlieghere   Status new_plan_status;
5454d56e9c1SJim Ingham   ThreadPlanSP new_plan_sp;
546b9c1b51eSKate Stone   if (frame_sp) {
547b9c1b51eSKate Stone     if (frame_sp->HasDebugInformation()) {
5484b4b2478SJim Ingham       const LazyBool avoid_no_debug = eLazyBoolCalculate;
54930fdc8d8SChris Lattner       SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
550b9c1b51eSKate Stone       new_plan_sp = thread->QueueThreadPlanForStepOverRange(
551b9c1b51eSKate Stone           abort_other_plans, sc.line_entry, sc, stop_other_threads,
552e103ae92SJonas Devlieghere           new_plan_status, avoid_no_debug);
553b9c1b51eSKate Stone     } else {
554b9c1b51eSKate Stone       new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
555e103ae92SJonas Devlieghere           true, abort_other_plans, stop_other_threads, new_plan_status);
55630fdc8d8SChris Lattner     }
55730fdc8d8SChris Lattner   }
558859f54b3SAlexander Polyakov   error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
55930fdc8d8SChris Lattner }
56030fdc8d8SChris Lattner 
561b9c1b51eSKate Stone void SBThread::StepInto(lldb::RunMode stop_other_threads) {
562baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInto, (lldb::RunMode),
563baf5664fSJonas Devlieghere                      stop_other_threads);
564baf5664fSJonas Devlieghere 
565248a1305SKonrad Kleine   StepInto(nullptr, stop_other_threads);
566c627682eSJim Ingham }
567c627682eSJim Ingham 
568b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name,
569b9c1b51eSKate Stone                         lldb::RunMode stop_other_threads) {
570baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInto, (const char *, lldb::RunMode),
571baf5664fSJonas Devlieghere                      target_name, stop_other_threads);
572baf5664fSJonas Devlieghere 
573859f54b3SAlexander Polyakov   SBError error; // Ignored
574cbf6f9b2SJim Ingham   StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
575cbf6f9b2SJim Ingham }
576cbf6f9b2SJim Ingham 
577b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name, uint32_t end_line,
578b9c1b51eSKate Stone                         SBError &error, lldb::RunMode stop_other_threads) {
579baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInto,
580baf5664fSJonas Devlieghere                      (const char *, uint32_t, lldb::SBError &, lldb::RunMode),
581baf5664fSJonas Devlieghere                      target_name, end_line, error, stop_other_threads);
582baf5664fSJonas Devlieghere 
583ceb6b139SCaroline Tice 
584bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
585bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
58617a6ad05SGreg Clayton 
587859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
588859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
589859f54b3SAlexander Polyakov     return;
590859f54b3SAlexander Polyakov   }
591859f54b3SAlexander Polyakov 
5927ba6e991SJim Ingham   bool abort_other_plans = false;
59330fdc8d8SChris Lattner 
5941ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
595b57e4a1bSJason Molenda   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
5964d56e9c1SJim Ingham   ThreadPlanSP new_plan_sp;
597e103ae92SJonas Devlieghere   Status new_plan_status;
59830fdc8d8SChris Lattner 
599b9c1b51eSKate Stone   if (frame_sp && frame_sp->HasDebugInformation()) {
600cbf6f9b2SJim Ingham     SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
601cbf6f9b2SJim Ingham     AddressRange range;
602cbf6f9b2SJim Ingham     if (end_line == LLDB_INVALID_LINE_NUMBER)
603cbf6f9b2SJim Ingham       range = sc.line_entry.range;
604b9c1b51eSKate Stone     else {
605cbf6f9b2SJim Ingham       if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
606cbf6f9b2SJim Ingham         return;
607cbf6f9b2SJim Ingham     }
608cbf6f9b2SJim Ingham 
609b9c1b51eSKate Stone     const LazyBool step_out_avoids_code_without_debug_info =
610b9c1b51eSKate Stone         eLazyBoolCalculate;
611b9c1b51eSKate Stone     const LazyBool step_in_avoids_code_without_debug_info =
612b9c1b51eSKate Stone         eLazyBoolCalculate;
613b9c1b51eSKate Stone     new_plan_sp = thread->QueueThreadPlanForStepInRange(
614b9c1b51eSKate Stone         abort_other_plans, range, sc, target_name, stop_other_threads,
615e103ae92SJonas Devlieghere         new_plan_status, step_in_avoids_code_without_debug_info,
6164b4b2478SJim Ingham         step_out_avoids_code_without_debug_info);
617b9c1b51eSKate Stone   } else {
618b9c1b51eSKate Stone     new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
619e103ae92SJonas Devlieghere         false, abort_other_plans, stop_other_threads, new_plan_status);
62030fdc8d8SChris Lattner   }
621e103ae92SJonas Devlieghere 
622e103ae92SJonas Devlieghere   if (new_plan_status.Success())
623cbf6f9b2SJim Ingham     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
624e103ae92SJonas Devlieghere   else
625e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
62630fdc8d8SChris Lattner }
62730fdc8d8SChris Lattner 
628b9c1b51eSKate Stone void SBThread::StepOut() {
629baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(void, SBThread, StepOut);
630baf5664fSJonas Devlieghere 
631859f54b3SAlexander Polyakov   SBError error; // Ignored
632859f54b3SAlexander Polyakov   StepOut(error);
633859f54b3SAlexander Polyakov }
634859f54b3SAlexander Polyakov 
635859f54b3SAlexander Polyakov void SBThread::StepOut(SBError &error) {
636baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOut, (lldb::SBError &), error);
637baf5664fSJonas Devlieghere 
638bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
639bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
6404fc6cb9cSJim Ingham 
641859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
642859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
643859f54b3SAlexander Polyakov     return;
644859f54b3SAlexander Polyakov   }
645859f54b3SAlexander Polyakov 
6467ba6e991SJim Ingham   bool abort_other_plans = false;
64794b09246SJim Ingham   bool stop_other_threads = false;
64830fdc8d8SChris Lattner 
6491ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
6501ac04c30SGreg Clayton 
6514b4b2478SJim Ingham   const LazyBool avoid_no_debug = eLazyBoolCalculate;
652e103ae92SJonas Devlieghere   Status new_plan_status;
653b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
654248a1305SKonrad Kleine       abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
655e103ae92SJonas Devlieghere       eVoteNoOpinion, 0, new_plan_status, avoid_no_debug));
656481cef25SGreg Clayton 
657e103ae92SJonas Devlieghere   if (new_plan_status.Success())
658859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
659e103ae92SJonas Devlieghere   else
660e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
661481cef25SGreg Clayton }
662481cef25SGreg Clayton 
663859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
664baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOutOfFrame, (lldb::SBFrame &),
665baf5664fSJonas Devlieghere                      sb_frame);
666baf5664fSJonas Devlieghere 
667859f54b3SAlexander Polyakov   SBError error; // Ignored
668859f54b3SAlexander Polyakov   StepOutOfFrame(sb_frame, error);
669859f54b3SAlexander Polyakov }
670859f54b3SAlexander Polyakov 
671859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
672baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOutOfFrame,
673baf5664fSJonas Devlieghere                      (lldb::SBFrame &, lldb::SBError &), sb_frame, error);
674baf5664fSJonas Devlieghere 
675481cef25SGreg Clayton 
676bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
677bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
6784fc6cb9cSJim Ingham 
679b9c1b51eSKate Stone   if (!sb_frame.IsValid()) {
680859f54b3SAlexander Polyakov     error.SetErrorString("passed invalid SBFrame object");
681989a7558SJim Ingham     return;
682989a7558SJim Ingham   }
683989a7558SJim Ingham 
684b57e4a1bSJason Molenda   StackFrameSP frame_sp(sb_frame.GetFrameSP());
685481cef25SGreg Clayton 
686859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
687859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
688859f54b3SAlexander Polyakov     return;
689859f54b3SAlexander Polyakov   }
690859f54b3SAlexander Polyakov 
6917ba6e991SJim Ingham   bool abort_other_plans = false;
69294b09246SJim Ingham   bool stop_other_threads = false;
6931ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
694b9c1b51eSKate Stone   if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
695859f54b3SAlexander Polyakov     error.SetErrorString("passed a frame from another thread");
696859f54b3SAlexander Polyakov     return;
697989a7558SJim Ingham   }
698481cef25SGreg Clayton 
699e103ae92SJonas Devlieghere   Status new_plan_status;
700b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
701248a1305SKonrad Kleine       abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
702e103ae92SJonas Devlieghere       eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status));
70330fdc8d8SChris Lattner 
704e103ae92SJonas Devlieghere   if (new_plan_status.Success())
705859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
706e103ae92SJonas Devlieghere   else
707e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
70830fdc8d8SChris Lattner }
70930fdc8d8SChris Lattner 
710b9c1b51eSKate Stone void SBThread::StepInstruction(bool step_over) {
711baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInstruction, (bool), step_over);
712baf5664fSJonas Devlieghere 
713859f54b3SAlexander Polyakov   SBError error; // Ignored
714859f54b3SAlexander Polyakov   StepInstruction(step_over, error);
715859f54b3SAlexander Polyakov }
716859f54b3SAlexander Polyakov 
717859f54b3SAlexander Polyakov void SBThread::StepInstruction(bool step_over, SBError &error) {
718baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInstruction, (bool, lldb::SBError &),
719baf5664fSJonas Devlieghere                      step_over, error);
720baf5664fSJonas Devlieghere 
721bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
722bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
723ceb6b139SCaroline Tice 
724859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
725859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
726859f54b3SAlexander Polyakov     return;
727859f54b3SAlexander Polyakov   }
728859f54b3SAlexander Polyakov 
7291ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
730e103ae92SJonas Devlieghere   Status new_plan_status;
731e103ae92SJonas Devlieghere   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction(
732e103ae92SJonas Devlieghere       step_over, true, true, new_plan_status));
73364e7ead1SJim Ingham 
734e103ae92SJonas Devlieghere   if (new_plan_status.Success())
735859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
736e103ae92SJonas Devlieghere   else
737e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
73830fdc8d8SChris Lattner }
73930fdc8d8SChris Lattner 
740b9c1b51eSKate Stone void SBThread::RunToAddress(lldb::addr_t addr) {
741baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, RunToAddress, (lldb::addr_t), addr);
742baf5664fSJonas Devlieghere 
743859f54b3SAlexander Polyakov   SBError error; // Ignored
744859f54b3SAlexander Polyakov   RunToAddress(addr, error);
745859f54b3SAlexander Polyakov }
746859f54b3SAlexander Polyakov 
747859f54b3SAlexander Polyakov void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
748baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, RunToAddress,
749baf5664fSJonas Devlieghere                      (lldb::addr_t, lldb::SBError &), addr, error);
750baf5664fSJonas Devlieghere 
751bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
752bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
753ceb6b139SCaroline Tice 
754859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
755859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
756859f54b3SAlexander Polyakov     return;
757859f54b3SAlexander Polyakov   }
758859f54b3SAlexander Polyakov 
7597ba6e991SJim Ingham   bool abort_other_plans = false;
76030fdc8d8SChris Lattner   bool stop_other_threads = true;
76130fdc8d8SChris Lattner 
762e72dfb32SGreg Clayton   Address target_addr(addr);
76330fdc8d8SChris Lattner 
7641ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
7651ac04c30SGreg Clayton 
766e103ae92SJonas Devlieghere   Status new_plan_status;
767b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
768e103ae92SJonas Devlieghere       abort_other_plans, target_addr, stop_other_threads, new_plan_status));
76964e7ead1SJim Ingham 
770e103ae92SJonas Devlieghere   if (new_plan_status.Success())
771859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
772e103ae92SJonas Devlieghere   else
773e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
77430fdc8d8SChris Lattner }
77530fdc8d8SChris Lattner 
776b9c1b51eSKate Stone SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
777b9c1b51eSKate Stone                                 lldb::SBFileSpec &sb_file_spec, uint32_t line) {
778baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepOverUntil,
779baf5664fSJonas Devlieghere                      (lldb::SBFrame &, lldb::SBFileSpec &, uint32_t), sb_frame,
780baf5664fSJonas Devlieghere                      sb_file_spec, line);
781baf5664fSJonas Devlieghere 
782481cef25SGreg Clayton   SBError sb_error;
783481cef25SGreg Clayton   char path[PATH_MAX];
784481cef25SGreg Clayton 
785bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
786bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
7874fc6cb9cSJim Ingham 
788b57e4a1bSJason Molenda   StackFrameSP frame_sp(sb_frame.GetFrameSP());
78917a6ad05SGreg Clayton 
790b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
7911ac04c30SGreg Clayton     Target *target = exe_ctx.GetTargetPtr();
7921ac04c30SGreg Clayton     Thread *thread = exe_ctx.GetThreadPtr();
793481cef25SGreg Clayton 
794b9c1b51eSKate Stone     if (line == 0) {
795481cef25SGreg Clayton       sb_error.SetErrorString("invalid line argument");
796baf5664fSJonas Devlieghere       return LLDB_RECORD_RESULT(sb_error);
797481cef25SGreg Clayton     }
798481cef25SGreg Clayton 
799b9c1b51eSKate Stone     if (!frame_sp) {
8001ac04c30SGreg Clayton       frame_sp = thread->GetSelectedFrame();
801481cef25SGreg Clayton       if (!frame_sp)
8021ac04c30SGreg Clayton         frame_sp = thread->GetStackFrameAtIndex(0);
803481cef25SGreg Clayton     }
804481cef25SGreg Clayton 
805481cef25SGreg Clayton     SymbolContext frame_sc;
806b9c1b51eSKate Stone     if (!frame_sp) {
807481cef25SGreg Clayton       sb_error.SetErrorString("no valid frames in thread to step");
808baf5664fSJonas Devlieghere       return LLDB_RECORD_RESULT(sb_error);
809481cef25SGreg Clayton     }
810481cef25SGreg Clayton 
811481cef25SGreg Clayton     // If we have a frame, get its line
812b9c1b51eSKate Stone     frame_sc = frame_sp->GetSymbolContext(
813b9c1b51eSKate Stone         eSymbolContextCompUnit | eSymbolContextFunction |
814b9c1b51eSKate Stone         eSymbolContextLineEntry | eSymbolContextSymbol);
815481cef25SGreg Clayton 
816248a1305SKonrad Kleine     if (frame_sc.comp_unit == nullptr) {
817b9c1b51eSKate Stone       sb_error.SetErrorStringWithFormat(
818b9c1b51eSKate Stone           "frame %u doesn't have debug information", frame_sp->GetFrameIndex());
819baf5664fSJonas Devlieghere       return LLDB_RECORD_RESULT(sb_error);
820481cef25SGreg Clayton     }
821481cef25SGreg Clayton 
822481cef25SGreg Clayton     FileSpec step_file_spec;
823b9c1b51eSKate Stone     if (sb_file_spec.IsValid()) {
824481cef25SGreg Clayton       // The file spec passed in was valid, so use it
825481cef25SGreg Clayton       step_file_spec = sb_file_spec.ref();
826b9c1b51eSKate Stone     } else {
827481cef25SGreg Clayton       if (frame_sc.line_entry.IsValid())
828481cef25SGreg Clayton         step_file_spec = frame_sc.line_entry.file;
829b9c1b51eSKate Stone       else {
830481cef25SGreg Clayton         sb_error.SetErrorString("invalid file argument or no file for frame");
831baf5664fSJonas Devlieghere         return LLDB_RECORD_RESULT(sb_error);
832481cef25SGreg Clayton       }
833481cef25SGreg Clayton     }
834481cef25SGreg Clayton 
8359b70ddb3SJim Ingham     // Grab the current function, then we will make sure the "until" address is
8369b70ddb3SJim Ingham     // within the function.  We discard addresses that are out of the current
837b9c1b51eSKate Stone     // function, and then if there are no addresses remaining, give an
83805097246SAdrian Prantl     // appropriate error message.
8399b70ddb3SJim Ingham 
8409b70ddb3SJim Ingham     bool all_in_function = true;
8419b70ddb3SJim Ingham     AddressRange fun_range = frame_sc.function->GetAddressRange();
8429b70ddb3SJim Ingham 
843481cef25SGreg Clayton     std::vector<addr_t> step_over_until_addrs;
8447ba6e991SJim Ingham     const bool abort_other_plans = false;
845c02e3344SJim Ingham     const bool stop_other_threads = false;
846481cef25SGreg Clayton     const bool check_inlines = true;
847481cef25SGreg Clayton     const bool exact = false;
848481cef25SGreg Clayton 
849481cef25SGreg Clayton     SymbolContextList sc_list;
850c671639aSKonrad Kleine     frame_sc.comp_unit->ResolveSymbolContext(step_file_spec, line,
851c671639aSKonrad Kleine                                              check_inlines, exact,
852c671639aSKonrad Kleine                                              eSymbolContextLineEntry, sc_list);
853c671639aSKonrad Kleine     const uint32_t num_matches = sc_list.GetSize();
854b9c1b51eSKate Stone     if (num_matches > 0) {
855481cef25SGreg Clayton       SymbolContext sc;
856b9c1b51eSKate Stone       for (uint32_t i = 0; i < num_matches; ++i) {
857b9c1b51eSKate Stone         if (sc_list.GetContextAtIndex(i, sc)) {
858b9c1b51eSKate Stone           addr_t step_addr =
859b9c1b51eSKate Stone               sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
860b9c1b51eSKate Stone           if (step_addr != LLDB_INVALID_ADDRESS) {
8619b70ddb3SJim Ingham             if (fun_range.ContainsLoadAddress(step_addr, target))
862481cef25SGreg Clayton               step_over_until_addrs.push_back(step_addr);
8639b70ddb3SJim Ingham             else
8649b70ddb3SJim Ingham               all_in_function = false;
865481cef25SGreg Clayton           }
866481cef25SGreg Clayton         }
867481cef25SGreg Clayton       }
868481cef25SGreg Clayton     }
869481cef25SGreg Clayton 
870b9c1b51eSKate Stone     if (step_over_until_addrs.empty()) {
871b9c1b51eSKate Stone       if (all_in_function) {
872481cef25SGreg Clayton         step_file_spec.GetPath(path, sizeof(path));
873b9c1b51eSKate Stone         sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path,
874b9c1b51eSKate Stone                                           line);
875b9c1b51eSKate Stone       } else
87686edbf41SGreg Clayton         sb_error.SetErrorString("step until target not in current function");
877b9c1b51eSKate Stone     } else {
878e103ae92SJonas Devlieghere       Status new_plan_status;
879b9c1b51eSKate Stone       ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil(
880b9c1b51eSKate Stone           abort_other_plans, &step_over_until_addrs[0],
881b9c1b51eSKate Stone           step_over_until_addrs.size(), stop_other_threads,
882e103ae92SJonas Devlieghere           frame_sp->GetFrameIndex(), new_plan_status));
883481cef25SGreg Clayton 
884e103ae92SJonas Devlieghere       if (new_plan_status.Success())
8854d56e9c1SJim Ingham         sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
886e103ae92SJonas Devlieghere       else
887e103ae92SJonas Devlieghere         sb_error.SetErrorString(new_plan_status.AsCString());
888481cef25SGreg Clayton     }
889b9c1b51eSKate Stone   } else {
890481cef25SGreg Clayton     sb_error.SetErrorString("this SBThread object is invalid");
891481cef25SGreg Clayton   }
892baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
893481cef25SGreg Clayton }
894481cef25SGreg Clayton 
895b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) {
896baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
897baf5664fSJonas Devlieghere                      (const char *), script_class_name);
898baf5664fSJonas Devlieghere 
899baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
900baf5664fSJonas Devlieghere       StepUsingScriptedThreadPlan(script_class_name, true));
901c915a7d2SJim Ingham }
902c915a7d2SJim Ingham 
903b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
904b9c1b51eSKate Stone                                             bool resume_immediately) {
905baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
906baf5664fSJonas Devlieghere                      (const char *, bool), script_class_name,
907baf5664fSJonas Devlieghere                      resume_immediately);
908baf5664fSJonas Devlieghere 
90927a14f19SJim Ingham   lldb::SBStructuredData no_data;
9103da7dcf3SJonas Devlieghere   return LLDB_RECORD_RESULT(StepUsingScriptedThreadPlan(
9113da7dcf3SJonas Devlieghere       script_class_name, no_data, resume_immediately));
91227a14f19SJim Ingham }
91327a14f19SJim Ingham 
91427a14f19SJim Ingham SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
91527a14f19SJim Ingham                                               SBStructuredData &args_data,
91627a14f19SJim Ingham                                               bool resume_immediately) {
91727a14f19SJim Ingham   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
91827a14f19SJim Ingham                      (const char *, lldb::SBStructuredData &, bool),
9193da7dcf3SJonas Devlieghere                      script_class_name, args_data, resume_immediately);
92027a14f19SJim Ingham 
921e103ae92SJonas Devlieghere   SBError error;
9222bdbfd50SJim Ingham 
923bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
924bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
9252bdbfd50SJim Ingham 
926b9c1b51eSKate Stone   if (!exe_ctx.HasThreadScope()) {
927e103ae92SJonas Devlieghere     error.SetErrorString("this SBThread object is invalid");
928baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(error);
9292bdbfd50SJim Ingham   }
9302bdbfd50SJim Ingham 
9312bdbfd50SJim Ingham   Thread *thread = exe_ctx.GetThreadPtr();
932e103ae92SJonas Devlieghere   Status new_plan_status;
93327a14f19SJim Ingham   StructuredData::ObjectSP obj_sp = args_data.m_impl_up->GetObjectSP();
93427a14f19SJim Ingham 
935e103ae92SJonas Devlieghere   ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted(
93627a14f19SJim Ingham       false, script_class_name, obj_sp, false, new_plan_status);
9372bdbfd50SJim Ingham 
938e103ae92SJonas Devlieghere   if (new_plan_status.Fail()) {
939e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
940baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(error);
941c915a7d2SJim Ingham   }
942c915a7d2SJim Ingham 
943e103ae92SJonas Devlieghere   if (!resume_immediately)
944baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(error);
945c915a7d2SJim Ingham 
946e103ae92SJonas Devlieghere   if (new_plan_status.Success())
947e103ae92SJonas Devlieghere     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
948e103ae92SJonas Devlieghere   else
949e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
9502bdbfd50SJim Ingham 
951baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(error);
9522bdbfd50SJim Ingham }
9532bdbfd50SJim Ingham 
954b9c1b51eSKate Stone SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
955baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, JumpToLine,
956baf5664fSJonas Devlieghere                      (lldb::SBFileSpec &, uint32_t), file_spec, line);
957baf5664fSJonas Devlieghere 
958f86248d9SRichard Mitton   SBError sb_error;
959f86248d9SRichard Mitton 
960bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
961bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
962f86248d9SRichard Mitton 
963b9c1b51eSKate Stone   if (!exe_ctx.HasThreadScope()) {
964f86248d9SRichard Mitton     sb_error.SetErrorString("this SBThread object is invalid");
965baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(sb_error);
966f86248d9SRichard Mitton   }
967f86248d9SRichard Mitton 
968f86248d9SRichard Mitton   Thread *thread = exe_ctx.GetThreadPtr();
969f86248d9SRichard Mitton 
97028e4942bSPavel Labath   Status err = thread->JumpToLine(file_spec.ref(), line, true);
971f86248d9SRichard Mitton   sb_error.SetError(err);
972baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
973f86248d9SRichard Mitton }
974f86248d9SRichard Mitton 
975b9c1b51eSKate Stone SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
976baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, ReturnFromFrame,
977baf5664fSJonas Devlieghere                      (lldb::SBFrame &, lldb::SBValue &), frame, return_value);
978baf5664fSJonas Devlieghere 
9794413758cSJim Ingham   SBError sb_error;
9804413758cSJim Ingham 
981bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
982bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
9834413758cSJim Ingham 
984b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
9854413758cSJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
986b9c1b51eSKate Stone     sb_error.SetError(
987b9c1b51eSKate Stone         thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
9884413758cSJim Ingham   }
9894413758cSJim Ingham 
990baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
9914413758cSJim Ingham }
9924413758cSJim Ingham 
993b9c1b51eSKate Stone SBError SBThread::UnwindInnermostExpression() {
994baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBError, SBThread,
995baf5664fSJonas Devlieghere                              UnwindInnermostExpression);
996baf5664fSJonas Devlieghere 
9974ac8e93aSJim Ingham   SBError sb_error;
9984ac8e93aSJim Ingham 
9994ac8e93aSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
10004ac8e93aSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
10014ac8e93aSJim Ingham 
1002b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
10034ac8e93aSJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
10044ac8e93aSJim Ingham     sb_error.SetError(thread->UnwindInnermostExpression());
10054ac8e93aSJim Ingham     if (sb_error.Success())
10064ac8e93aSJim Ingham       thread->SetSelectedFrameByIndex(0, false);
10074ac8e93aSJim Ingham   }
10084ac8e93aSJim Ingham 
1009baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
10104ac8e93aSJim Ingham }
1011481cef25SGreg Clayton 
1012b9c1b51eSKate Stone bool SBThread::Suspend() {
1013baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, Suspend);
1014baf5664fSJonas Devlieghere 
1015859f54b3SAlexander Polyakov   SBError error; // Ignored
1016859f54b3SAlexander Polyakov   return Suspend(error);
1017859f54b3SAlexander Polyakov }
1018859f54b3SAlexander Polyakov 
1019859f54b3SAlexander Polyakov bool SBThread::Suspend(SBError &error) {
1020baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, Suspend, (lldb::SBError &), error);
1021baf5664fSJonas Devlieghere 
1022b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1023b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1024b2e7d28eSJim Ingham 
1025c9858e4dSGreg Clayton   bool result = false;
1026b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1027c9858e4dSGreg Clayton     Process::StopLocker stop_locker;
1028b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
10291ac04c30SGreg Clayton       exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
1030c9858e4dSGreg Clayton       result = true;
1031b9c1b51eSKate Stone     } else {
1032859f54b3SAlexander Polyakov       error.SetErrorString("process is running");
1033c9858e4dSGreg Clayton     }
1034859f54b3SAlexander Polyakov   } else
1035859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
1036c9858e4dSGreg Clayton   return result;
1037722a0cdcSGreg Clayton }
1038722a0cdcSGreg Clayton 
1039b9c1b51eSKate Stone bool SBThread::Resume() {
1040baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, Resume);
1041baf5664fSJonas Devlieghere 
1042859f54b3SAlexander Polyakov   SBError error; // Ignored
1043859f54b3SAlexander Polyakov   return Resume(error);
1044859f54b3SAlexander Polyakov }
1045859f54b3SAlexander Polyakov 
1046859f54b3SAlexander Polyakov bool SBThread::Resume(SBError &error) {
1047baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, Resume, (lldb::SBError &), error);
1048baf5664fSJonas Devlieghere 
1049b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1050b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1051b2e7d28eSJim Ingham 
1052c9858e4dSGreg Clayton   bool result = false;
1053b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1054c9858e4dSGreg Clayton     Process::StopLocker stop_locker;
1055b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
10566c9ed91cSJim Ingham       const bool override_suspend = true;
10576c9ed91cSJim Ingham       exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
1058c9858e4dSGreg Clayton       result = true;
1059b9c1b51eSKate Stone     } else {
1060859f54b3SAlexander Polyakov       error.SetErrorString("process is running");
1061c9858e4dSGreg Clayton     }
1062859f54b3SAlexander Polyakov   } else
1063859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
1064c9858e4dSGreg Clayton   return result;
1065722a0cdcSGreg Clayton }
1066722a0cdcSGreg Clayton 
1067b9c1b51eSKate Stone bool SBThread::IsSuspended() {
1068baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, IsSuspended);
1069baf5664fSJonas Devlieghere 
1070b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1071b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1072b2e7d28eSJim Ingham 
10731ac04c30SGreg Clayton   if (exe_ctx.HasThreadScope())
10741ac04c30SGreg Clayton     return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
1075722a0cdcSGreg Clayton   return false;
1076722a0cdcSGreg Clayton }
1077722a0cdcSGreg Clayton 
1078b9c1b51eSKate Stone bool SBThread::IsStopped() {
1079baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, IsStopped);
1080baf5664fSJonas Devlieghere 
1081b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1082b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1083b2e7d28eSJim Ingham 
1084a75418dbSAndrew Kaylor   if (exe_ctx.HasThreadScope())
1085a75418dbSAndrew Kaylor     return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1086a75418dbSAndrew Kaylor   return false;
1087a75418dbSAndrew Kaylor }
1088a75418dbSAndrew Kaylor 
1089b9c1b51eSKate Stone SBProcess SBThread::GetProcess() {
1090baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBProcess, SBThread, GetProcess);
1091baf5664fSJonas Devlieghere 
1092b9556accSGreg Clayton   SBProcess sb_process;
1093b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1094b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1095b2e7d28eSJim Ingham 
1096b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1097b9c1b51eSKate Stone     // Have to go up to the target so we can get a shared pointer to our
1098b9c1b51eSKate Stone     // process...
10991ac04c30SGreg Clayton     sb_process.SetSP(exe_ctx.GetProcessSP());
110030fdc8d8SChris Lattner   }
1101ceb6b139SCaroline Tice 
1102baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_process);
110330fdc8d8SChris Lattner }
110430fdc8d8SChris Lattner 
1105b9c1b51eSKate Stone uint32_t SBThread::GetNumFrames() {
1106baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBThread, GetNumFrames);
1107baf5664fSJonas Devlieghere 
1108ceb6b139SCaroline Tice   uint32_t num_frames = 0;
1109bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1110bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11114fc6cb9cSJim Ingham 
1112b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11137fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1114b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11151ac04c30SGreg Clayton       num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1116c9858e4dSGreg Clayton     }
11177fdf9ef1SGreg Clayton   }
1118ceb6b139SCaroline Tice 
1119ceb6b139SCaroline Tice   return num_frames;
112030fdc8d8SChris Lattner }
112130fdc8d8SChris Lattner 
1122b9c1b51eSKate Stone SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
1123baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBFrame, SBThread, GetFrameAtIndex, (uint32_t), idx);
1124baf5664fSJonas Devlieghere 
112530fdc8d8SChris Lattner   SBFrame sb_frame;
1126b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1127bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1128bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11294fc6cb9cSJim Ingham 
1130b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11317fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1132b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11331ac04c30SGreg Clayton       frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
1134b9556accSGreg Clayton       sb_frame.SetFrameSP(frame_sp);
1135c9858e4dSGreg Clayton     }
11367fdf9ef1SGreg Clayton   }
1137ceb6b139SCaroline Tice 
1138baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_frame);
113930fdc8d8SChris Lattner }
114030fdc8d8SChris Lattner 
1141b9c1b51eSKate Stone lldb::SBFrame SBThread::GetSelectedFrame() {
1142baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBFrame, SBThread, GetSelectedFrame);
1143baf5664fSJonas Devlieghere 
1144f028a1fbSGreg Clayton   SBFrame sb_frame;
1145b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1146bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1147bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11484fc6cb9cSJim Ingham 
1149b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11507fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1151b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11521ac04c30SGreg Clayton       frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame();
1153b9556accSGreg Clayton       sb_frame.SetFrameSP(frame_sp);
1154c9858e4dSGreg Clayton     }
11557fdf9ef1SGreg Clayton   }
1156f028a1fbSGreg Clayton 
1157baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_frame);
1158f028a1fbSGreg Clayton }
1159f028a1fbSGreg Clayton 
1160b9c1b51eSKate Stone lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
1161baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBFrame, SBThread, SetSelectedFrame, (uint32_t),
1162baf5664fSJonas Devlieghere                      idx);
1163baf5664fSJonas Devlieghere 
1164f028a1fbSGreg Clayton   SBFrame sb_frame;
1165b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1166bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1167bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11684fc6cb9cSJim Ingham 
1169b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11707fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1171b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11721ac04c30SGreg Clayton       Thread *thread = exe_ctx.GetThreadPtr();
11731ac04c30SGreg Clayton       frame_sp = thread->GetStackFrameAtIndex(idx);
1174b9c1b51eSKate Stone       if (frame_sp) {
11751ac04c30SGreg Clayton         thread->SetSelectedFrame(frame_sp.get());
1176b9556accSGreg Clayton         sb_frame.SetFrameSP(frame_sp);
1177f028a1fbSGreg Clayton       }
1178c9858e4dSGreg Clayton     }
11797fdf9ef1SGreg Clayton   }
1180f028a1fbSGreg Clayton 
1181baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_frame);
1182f028a1fbSGreg Clayton }
1183f028a1fbSGreg Clayton 
1184b9c1b51eSKate Stone bool SBThread::EventIsThreadEvent(const SBEvent &event) {
1185baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(bool, SBThread, EventIsThreadEvent,
1186baf5664fSJonas Devlieghere                             (const lldb::SBEvent &), event);
1187baf5664fSJonas Devlieghere 
1188248a1305SKonrad Kleine   return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != nullptr;
11894f465cffSJim Ingham }
11904f465cffSJim Ingham 
1191b9c1b51eSKate Stone SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) {
1192baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(lldb::SBFrame, SBThread, GetStackFrameFromEvent,
1193baf5664fSJonas Devlieghere                             (const lldb::SBEvent &), event);
1194baf5664fSJonas Devlieghere 
1195baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
1196baf5664fSJonas Devlieghere       Thread::ThreadEventData::GetStackFrameFromEvent(event.get()));
11974f465cffSJim Ingham }
11984f465cffSJim Ingham 
1199b9c1b51eSKate Stone SBThread SBThread::GetThreadFromEvent(const SBEvent &event) {
1200baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(lldb::SBThread, SBThread, GetThreadFromEvent,
1201baf5664fSJonas Devlieghere                             (const lldb::SBEvent &), event);
1202baf5664fSJonas Devlieghere 
1203baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
1204baf5664fSJonas Devlieghere       Thread::ThreadEventData::GetThreadFromEvent(event.get()));
12054f465cffSJim Ingham }
1206f028a1fbSGreg Clayton 
1207b9c1b51eSKate Stone bool SBThread::operator==(const SBThread &rhs) const {
1208baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, operator==,(const lldb::SBThread &),
1209baf5664fSJonas Devlieghere                            rhs);
1210baf5664fSJonas Devlieghere 
1211b9c1b51eSKate Stone   return m_opaque_sp->GetThreadSP().get() ==
1212b9c1b51eSKate Stone          rhs.m_opaque_sp->GetThreadSP().get();
121330fdc8d8SChris Lattner }
121430fdc8d8SChris Lattner 
1215b9c1b51eSKate Stone bool SBThread::operator!=(const SBThread &rhs) const {
1216baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, operator!=,(const lldb::SBThread &),
1217baf5664fSJonas Devlieghere                            rhs);
1218baf5664fSJonas Devlieghere 
1219b9c1b51eSKate Stone   return m_opaque_sp->GetThreadSP().get() !=
1220b9c1b51eSKate Stone          rhs.m_opaque_sp->GetThreadSP().get();
122130fdc8d8SChris Lattner }
1222dde9cff3SCaroline Tice 
1223b9c1b51eSKate Stone bool SBThread::GetStatus(SBStream &status) const {
1224baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetStatus, (lldb::SBStream &),
1225baf5664fSJonas Devlieghere                            status);
1226baf5664fSJonas Devlieghere 
12274f465cffSJim Ingham   Stream &strm = status.ref();
12284f465cffSJim Ingham 
1229b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1230b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1231b2e7d28eSJim Ingham 
1232b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
12336a9767c7SJim Ingham     exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true);
1234b9c1b51eSKate Stone   } else
12354f465cffSJim Ingham     strm.PutCString("No status");
12364f465cffSJim Ingham 
12374f465cffSJim Ingham   return true;
12384f465cffSJim Ingham }
12394f465cffSJim Ingham 
1240b9c1b51eSKate Stone bool SBThread::GetDescription(SBStream &description) const {
1241baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetDescription, (lldb::SBStream &),
1242baf5664fSJonas Devlieghere                            description);
1243baf5664fSJonas Devlieghere 
12446a9767c7SJim Ingham   return GetDescription(description, false);
12456a9767c7SJim Ingham }
12466a9767c7SJim Ingham 
12476a9767c7SJim Ingham bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
1248baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetDescription,
1249baf5664fSJonas Devlieghere                            (lldb::SBStream &, bool), description, stop_format);
1250baf5664fSJonas Devlieghere 
1251da7bc7d0SGreg Clayton   Stream &strm = description.ref();
1252da7bc7d0SGreg Clayton 
1253b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1254b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1255b2e7d28eSJim Ingham 
1256b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1257b9c1b51eSKate Stone     exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm,
12586a9767c7SJim Ingham                                                     LLDB_INVALID_THREAD_ID,
12596a9767c7SJim Ingham                                                     stop_format);
1260b9c1b51eSKate Stone     // strm.Printf("SBThread: tid = 0x%4.4" PRIx64,
1261b9c1b51eSKate Stone     // exe_ctx.GetThreadPtr()->GetID());
1262b9c1b51eSKate Stone   } else
1263da7bc7d0SGreg Clayton     strm.PutCString("No value");
1264ceb6b139SCaroline Tice 
1265ceb6b139SCaroline Tice   return true;
1266ceb6b139SCaroline Tice }
12675dd4916fSJason Molenda 
1268b9c1b51eSKate Stone SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
1269baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBThread, SBThread, GetExtendedBacktraceThread,
1270baf5664fSJonas Devlieghere                      (const char *), type);
1271baf5664fSJonas Devlieghere 
1272bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1273bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12745dd4916fSJason Molenda   SBThread sb_origin_thread;
12755dd4916fSJason Molenda 
12765dd4916fSJason Molenda   Process::StopLocker stop_locker;
1277b9c1b51eSKate Stone   if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1278b78094abSJim Ingham     if (exe_ctx.HasThreadScope()) {
12797a2f7904SJason Molenda       ThreadSP real_thread(exe_ctx.GetThreadSP());
1280b9c1b51eSKate Stone       if (real_thread) {
12815dd4916fSJason Molenda         ConstString type_const(type);
12827a2f7904SJason Molenda         Process *process = exe_ctx.GetProcessPtr();
1283b9c1b51eSKate Stone         if (process) {
12847a2f7904SJason Molenda           SystemRuntime *runtime = process->GetSystemRuntime();
1285b9c1b51eSKate Stone           if (runtime) {
1286b9c1b51eSKate Stone             ThreadSP new_thread_sp(
1287b9c1b51eSKate Stone                 runtime->GetExtendedBacktraceThread(real_thread, type_const));
1288b9c1b51eSKate Stone             if (new_thread_sp) {
1289b9c1b51eSKate Stone               // Save this in the Process' ExtendedThreadList so a strong
129005097246SAdrian Prantl               // pointer retains the object.
12917a2f7904SJason Molenda               process->GetExtendedThreadList().AddThread(new_thread_sp);
12927a2f7904SJason Molenda               sb_origin_thread.SetThread(new_thread_sp);
1293a6e9130dSJason Molenda             }
1294a6e9130dSJason Molenda           }
12957a2f7904SJason Molenda         }
12965dd4916fSJason Molenda       }
12975dd4916fSJason Molenda     }
12985dd4916fSJason Molenda   }
12995dd4916fSJason Molenda 
1300baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_origin_thread);
13015dd4916fSJason Molenda }
13028ee9cb58SJason Molenda 
1303b9c1b51eSKate Stone uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
1304baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBThread,
1305baf5664fSJonas Devlieghere                              GetExtendedBacktraceOriginatingIndexID);
1306baf5664fSJonas Devlieghere 
13078ee9cb58SJason Molenda   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
13088ee9cb58SJason Molenda   if (thread_sp)
13098ee9cb58SJason Molenda     return thread_sp->GetExtendedBacktraceOriginatingIndexID();
13108ee9cb58SJason Molenda   return LLDB_INVALID_INDEX32;
13118ee9cb58SJason Molenda }
1312b4892cd2SJason Molenda 
1313e60bc53bSKuba Mracek SBValue SBThread::GetCurrentException() {
1314baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBValue, SBThread, GetCurrentException);
1315e60bc53bSKuba Mracek 
1316baf5664fSJonas Devlieghere   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1317baf5664fSJonas Devlieghere   if (!thread_sp)
1318baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(SBValue());
1319baf5664fSJonas Devlieghere 
1320baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(SBValue(thread_sp->GetCurrentException()));
1321e60bc53bSKuba Mracek }
1322e60bc53bSKuba Mracek 
1323e60bc53bSKuba Mracek SBThread SBThread::GetCurrentExceptionBacktrace() {
1324baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBThread, SBThread,
1325baf5664fSJonas Devlieghere                              GetCurrentExceptionBacktrace);
1326e60bc53bSKuba Mracek 
1327baf5664fSJonas Devlieghere   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1328baf5664fSJonas Devlieghere   if (!thread_sp)
1329baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(SBThread());
1330baf5664fSJonas Devlieghere 
1331baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
1332baf5664fSJonas Devlieghere       SBThread(thread_sp->GetCurrentExceptionBacktrace()));
1333c9e1190aSKuba Mracek }
1334e60bc53bSKuba Mracek 
1335b9c1b51eSKate Stone bool SBThread::SafeToCallFunctions() {
1336baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, SafeToCallFunctions);
1337baf5664fSJonas Devlieghere 
1338b4892cd2SJason Molenda   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1339b4892cd2SJason Molenda   if (thread_sp)
1340b4892cd2SJason Molenda     return thread_sp->SafeToCallFunctions();
1341b4892cd2SJason Molenda   return true;
1342b4892cd2SJason Molenda }
13432bdbfd50SJim Ingham 
1344b9c1b51eSKate Stone lldb_private::Thread *SBThread::operator->() {
134526ca5a57SPavel Labath   return get();
13462bdbfd50SJim Ingham }
13472bdbfd50SJim Ingham 
1348b9c1b51eSKate Stone lldb_private::Thread *SBThread::get() {
134926ca5a57SPavel Labath   return m_opaque_sp->GetThreadSP().get();
13502bdbfd50SJim Ingham }
1351ae211eceSMichal Gorny 
1352ae211eceSMichal Gorny namespace lldb_private {
1353ae211eceSMichal Gorny namespace repro {
1354ae211eceSMichal Gorny 
1355ae211eceSMichal Gorny template <>
1356ae211eceSMichal Gorny void RegisterMethods<SBThread>(Registry &R) {
1357ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(const char *, SBThread, GetBroadcasterClassName,
1358ae211eceSMichal Gorny                               ());
1359ae211eceSMichal Gorny   LLDB_REGISTER_CONSTRUCTOR(SBThread, ());
1360ae211eceSMichal Gorny   LLDB_REGISTER_CONSTRUCTOR(SBThread, (const lldb::ThreadSP &));
1361ae211eceSMichal Gorny   LLDB_REGISTER_CONSTRUCTOR(SBThread, (const lldb::SBThread &));
1362ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(const lldb::SBThread &,
1363ae211eceSMichal Gorny                        SBThread, operator=,(const lldb::SBThread &));
1364ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(lldb::SBQueue, SBThread, GetQueue, ());
1365ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, IsValid, ());
1366ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, operator bool, ());
1367ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, Clear, ());
1368ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::StopReason, SBThread, GetStopReason, ());
1369ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(size_t, SBThread, GetStopReasonDataCount, ());
1370ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(uint64_t, SBThread, GetStopReasonDataAtIndex,
1371ae211eceSMichal Gorny                        (uint32_t));
1372ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, GetStopReasonExtendedInfoAsJSON,
1373ae211eceSMichal Gorny                        (lldb::SBStream &));
1374ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBThreadCollection, SBThread,
1375ae211eceSMichal Gorny                        GetStopReasonExtendedBacktraces,
1376ae211eceSMichal Gorny                        (lldb::InstrumentationRuntimeType));
1377ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBValue, SBThread, GetStopReturnValue, ());
1378ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(lldb::tid_t, SBThread, GetThreadID, ());
1379ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(uint32_t, SBThread, GetIndexID, ());
1380ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(const char *, SBThread, GetName, ());
1381ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(const char *, SBThread, GetQueueName, ());
1382ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(lldb::queue_id_t, SBThread, GetQueueID, ());
1383ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, GetInfoItemByPathAsString,
1384ae211eceSMichal Gorny                        (const char *, lldb::SBStream &));
1385ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOver, (lldb::RunMode));
1386ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOver,
1387ae211eceSMichal Gorny                        (lldb::RunMode, lldb::SBError &));
1388ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInto, (lldb::RunMode));
1389ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInto,
1390ae211eceSMichal Gorny                        (const char *, lldb::RunMode));
1391ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(
1392ae211eceSMichal Gorny       void, SBThread, StepInto,
1393ae211eceSMichal Gorny       (const char *, uint32_t, lldb::SBError &, lldb::RunMode));
1394ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOut, ());
1395ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOut, (lldb::SBError &));
1396ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOutOfFrame, (lldb::SBFrame &));
1397ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOutOfFrame,
1398ae211eceSMichal Gorny                        (lldb::SBFrame &, lldb::SBError &));
1399ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInstruction, (bool));
1400ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInstruction,
1401ae211eceSMichal Gorny                        (bool, lldb::SBError &));
1402ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, RunToAddress, (lldb::addr_t));
1403ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, RunToAddress,
1404ae211eceSMichal Gorny                        (lldb::addr_t, lldb::SBError &));
1405ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepOverUntil,
1406ae211eceSMichal Gorny                        (lldb::SBFrame &, lldb::SBFileSpec &, uint32_t));
1407ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
1408ae211eceSMichal Gorny                        (const char *));
1409ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
1410ae211eceSMichal Gorny                        (const char *, bool));
141127a14f19SJim Ingham   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
141227a14f19SJim Ingham                        (const char *, SBStructuredData &, bool));
1413ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, JumpToLine,
1414ae211eceSMichal Gorny                        (lldb::SBFileSpec &, uint32_t));
1415ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, ReturnFromFrame,
1416ae211eceSMichal Gorny                        (lldb::SBFrame &, lldb::SBValue &));
1417ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, UnwindInnermostExpression,
1418ae211eceSMichal Gorny                        ());
1419ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Suspend, ());
1420ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Suspend, (lldb::SBError &));
1421ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Resume, ());
1422ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Resume, (lldb::SBError &));
1423ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, IsSuspended, ());
1424ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, IsStopped, ());
1425ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBProcess, SBThread, GetProcess, ());
1426ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(uint32_t, SBThread, GetNumFrames, ());
1427ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, GetFrameAtIndex, (uint32_t));
1428ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, GetSelectedFrame, ());
1429ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, SetSelectedFrame, (uint32_t));
1430ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(bool, SBThread, EventIsThreadEvent,
1431ae211eceSMichal Gorny                               (const lldb::SBEvent &));
1432ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(lldb::SBFrame, SBThread, GetStackFrameFromEvent,
1433ae211eceSMichal Gorny                               (const lldb::SBEvent &));
1434ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(lldb::SBThread, SBThread, GetThreadFromEvent,
1435ae211eceSMichal Gorny                               (const lldb::SBEvent &));
1436ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool,
1437ae211eceSMichal Gorny                              SBThread, operator==,(const lldb::SBThread &));
1438ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool,
1439ae211eceSMichal Gorny                              SBThread, operator!=,(const lldb::SBThread &));
1440ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetStatus, (lldb::SBStream &));
1441ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetDescription,
1442ae211eceSMichal Gorny                              (lldb::SBStream &));
1443ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetDescription,
1444ae211eceSMichal Gorny                              (lldb::SBStream &, bool));
1445ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBThread, SBThread, GetExtendedBacktraceThread,
1446ae211eceSMichal Gorny                        (const char *));
1447ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(uint32_t, SBThread,
1448ae211eceSMichal Gorny                        GetExtendedBacktraceOriginatingIndexID, ());
1449ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBValue, SBThread, GetCurrentException, ());
1450ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBThread, SBThread, GetCurrentExceptionBacktrace,
1451ae211eceSMichal Gorny                        ());
1452ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, SafeToCallFunctions, ());
1453e687aa82SJonas Devlieghere   LLDB_REGISTER_CHAR_PTR_METHOD(size_t, SBThread, GetStopDescription);
1454ae211eceSMichal Gorny }
1455ae211eceSMichal Gorny 
1456ae211eceSMichal Gorny }
1457ae211eceSMichal Gorny }
1458