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"
43b9c1b51eSKate Stone #include "lldb/Target/UnixSignals.h"
44d821c997SPavel Labath #include "lldb/Utility/State.h"
45bf9a7730SZachary Turner #include "lldb/Utility/Stream.h"
46f2a8bccfSPavel Labath #include "lldb/Utility/StructuredData.h"
475bfee5f1SAbhishek Aggarwal #include "lldb/lldb-enumerations.h"
4830fdc8d8SChris Lattner 
49796ac80bSJonas Devlieghere #include <memory>
50796ac80bSJonas Devlieghere 
5130fdc8d8SChris Lattner using namespace lldb;
5230fdc8d8SChris Lattner using namespace lldb_private;
5330fdc8d8SChris Lattner 
54b9c1b51eSKate Stone const char *SBThread::GetBroadcasterClassName() {
55baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBThread,
56baf5664fSJonas Devlieghere                                     GetBroadcasterClassName);
57baf5664fSJonas Devlieghere 
584f465cffSJim Ingham   return Thread::GetStaticBroadcasterClass().AsCString();
594f465cffSJim Ingham }
604f465cffSJim Ingham 
61cfd1acedSGreg Clayton // Constructors
62baf5664fSJonas Devlieghere SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {
63baf5664fSJonas Devlieghere   LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBThread);
64baf5664fSJonas Devlieghere }
6530fdc8d8SChris Lattner 
66b9c1b51eSKate Stone SBThread::SBThread(const ThreadSP &lldb_object_sp)
67baf5664fSJonas Devlieghere     : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {
68baf5664fSJonas Devlieghere   LLDB_RECORD_CONSTRUCTOR(SBThread, (const lldb::ThreadSP &), lldb_object_sp);
69baf5664fSJonas Devlieghere }
7030fdc8d8SChris Lattner 
71bd4bf82aSJonas Devlieghere SBThread::SBThread(const SBThread &rhs) : m_opaque_sp() {
72baf5664fSJonas Devlieghere   LLDB_RECORD_CONSTRUCTOR(SBThread, (const lldb::SBThread &), rhs);
73baf5664fSJonas Devlieghere 
74bd4bf82aSJonas Devlieghere   m_opaque_sp = clone(rhs.m_opaque_sp);
75bd4bf82aSJonas Devlieghere }
7630fdc8d8SChris Lattner 
77cfd1acedSGreg Clayton // Assignment operator
78cfd1acedSGreg Clayton 
79b9c1b51eSKate Stone const lldb::SBThread &SBThread::operator=(const SBThread &rhs) {
80baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(const lldb::SBThread &,
81baf5664fSJonas Devlieghere                      SBThread, operator=,(const lldb::SBThread &), rhs);
82baf5664fSJonas Devlieghere 
83cfd1acedSGreg Clayton   if (this != &rhs)
84bd4bf82aSJonas Devlieghere     m_opaque_sp = clone(rhs.m_opaque_sp);
85306809f2SJonas Devlieghere   return LLDB_RECORD_RESULT(*this);
86cfd1acedSGreg Clayton }
87cfd1acedSGreg Clayton 
8830fdc8d8SChris Lattner // Destructor
89b9c1b51eSKate Stone SBThread::~SBThread() {}
9030fdc8d8SChris Lattner 
91b9c1b51eSKate Stone lldb::SBQueue SBThread::GetQueue() const {
92baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBQueue, SBThread, GetQueue);
93baf5664fSJonas Devlieghere 
94b9ffa98cSJason Molenda   SBQueue sb_queue;
95b9ffa98cSJason Molenda   QueueSP queue_sp;
96bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
97bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
98b9ffa98cSJason Molenda 
99b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
100b9ffa98cSJason Molenda     Process::StopLocker stop_locker;
101b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
102b9ffa98cSJason Molenda       queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
103b9c1b51eSKate Stone       if (queue_sp) {
104b9ffa98cSJason Molenda         sb_queue.SetQueue(queue_sp);
105b9ffa98cSJason Molenda       }
106b9ffa98cSJason Molenda     }
107b9ffa98cSJason Molenda   }
108b9ffa98cSJason Molenda 
109baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_queue);
110b9ffa98cSJason Molenda }
111b9ffa98cSJason Molenda 
112b9c1b51eSKate Stone bool SBThread::IsValid() const {
113baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThread, IsValid);
1147f5237bcSPavel Labath   return this->operator bool();
1157f5237bcSPavel Labath }
1167f5237bcSPavel Labath SBThread::operator bool() const {
1177f5237bcSPavel Labath   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThread, operator bool);
118baf5664fSJonas Devlieghere 
119bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
120bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1217fa7dc36SJim Ingham 
1227fa7dc36SJim Ingham   Target *target = exe_ctx.GetTargetPtr();
1237fa7dc36SJim Ingham   Process *process = exe_ctx.GetProcessPtr();
124b9c1b51eSKate Stone   if (target && process) {
1257fa7dc36SJim Ingham     Process::StopLocker stop_locker;
1267fa7dc36SJim Ingham     if (stop_locker.TryLock(&process->GetRunLock()))
127248a1305SKonrad Kleine       return m_opaque_sp->GetThreadSP().get() != nullptr;
12830fdc8d8SChris Lattner   }
1297fa7dc36SJim Ingham   // Without a valid target & process, this thread can't be valid.
1307fa7dc36SJim Ingham   return false;
1317fa7dc36SJim Ingham }
13230fdc8d8SChris Lattner 
133baf5664fSJonas Devlieghere void SBThread::Clear() {
134baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(void, SBThread, Clear);
135baf5664fSJonas Devlieghere 
136baf5664fSJonas Devlieghere   m_opaque_sp->Clear();
137baf5664fSJonas Devlieghere }
13848e42549SGreg Clayton 
139b9c1b51eSKate Stone StopReason SBThread::GetStopReason() {
140baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::StopReason, SBThread, GetStopReason);
141baf5664fSJonas Devlieghere 
142ceb6b139SCaroline Tice   StopReason reason = eStopReasonInvalid;
143bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
144bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1454fc6cb9cSJim Ingham 
146b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1477fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
148b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
14997d5cf05SGreg Clayton       return exe_ctx.GetThreadPtr()->GetStopReason();
150c9858e4dSGreg Clayton     }
1517fdf9ef1SGreg Clayton   }
152ceb6b139SCaroline Tice 
153ceb6b139SCaroline Tice   return reason;
15430fdc8d8SChris Lattner }
15530fdc8d8SChris Lattner 
156b9c1b51eSKate Stone size_t SBThread::GetStopReasonDataCount() {
157baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(size_t, SBThread, GetStopReasonDataCount);
158baf5664fSJonas Devlieghere 
159bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
160bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1614fc6cb9cSJim Ingham 
162b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1637fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
164b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1651ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
166b9c1b51eSKate Stone       if (stop_info_sp) {
1674e78f606SGreg Clayton         StopReason reason = stop_info_sp->GetStopReason();
168b9c1b51eSKate Stone         switch (reason) {
1694e78f606SGreg Clayton         case eStopReasonInvalid:
1704e78f606SGreg Clayton         case eStopReasonNone:
1714e78f606SGreg Clayton         case eStopReasonTrace:
17290ba8115SGreg Clayton         case eStopReasonExec:
1734e78f606SGreg Clayton         case eStopReasonPlanComplete:
174f85defaeSAndrew Kaylor         case eStopReasonThreadExiting:
175afdf842bSKuba Brecka         case eStopReasonInstrumentation:
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:
2274e78f606SGreg Clayton           // There is no data for these stop reasons.
2284e78f606SGreg Clayton           return 0;
2294e78f606SGreg Clayton 
230b9c1b51eSKate Stone         case eStopReasonBreakpoint: {
2314e78f606SGreg Clayton           break_id_t site_id = stop_info_sp->GetValue();
232b9c1b51eSKate Stone           lldb::BreakpointSiteSP bp_site_sp(
233b9c1b51eSKate Stone               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
234b9c1b51eSKate Stone                   site_id));
235b9c1b51eSKate Stone           if (bp_site_sp) {
2364e78f606SGreg Clayton             uint32_t bp_index = idx / 2;
237b9c1b51eSKate Stone             BreakpointLocationSP bp_loc_sp(
238b9c1b51eSKate Stone                 bp_site_sp->GetOwnerAtIndex(bp_index));
239b9c1b51eSKate Stone             if (bp_loc_sp) {
240b9c1b51eSKate Stone               if (idx & 1) {
2414e78f606SGreg Clayton                 // Odd idx, return the breakpoint location ID
2424e78f606SGreg Clayton                 return bp_loc_sp->GetID();
243b9c1b51eSKate Stone               } else {
2444e78f606SGreg Clayton                 // Even idx, return the breakpoint ID
2454e78f606SGreg Clayton                 return bp_loc_sp->GetBreakpoint().GetID();
2464e78f606SGreg Clayton               }
2474e78f606SGreg Clayton             }
2484e78f606SGreg Clayton           }
2494e78f606SGreg Clayton           return LLDB_INVALID_BREAK_ID;
250b9c1b51eSKate Stone         } break;
2514e78f606SGreg Clayton 
2524e78f606SGreg Clayton         case eStopReasonWatchpoint:
253290fa41bSJohnny Chen           return stop_info_sp->GetValue();
2544e78f606SGreg Clayton 
2554e78f606SGreg Clayton         case eStopReasonSignal:
2564e78f606SGreg Clayton           return stop_info_sp->GetValue();
2574e78f606SGreg Clayton 
2584e78f606SGreg Clayton         case eStopReasonException:
2594e78f606SGreg Clayton           return stop_info_sp->GetValue();
2604e78f606SGreg Clayton         }
2614e78f606SGreg Clayton       }
262c9858e4dSGreg Clayton     }
2637fdf9ef1SGreg Clayton   }
2644e78f606SGreg Clayton   return 0;
2654e78f606SGreg Clayton }
2664e78f606SGreg Clayton 
267b9c1b51eSKate Stone bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) {
268baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, GetStopReasonExtendedInfoAsJSON,
269baf5664fSJonas Devlieghere                      (lldb::SBStream &), stream);
270baf5664fSJonas Devlieghere 
271afdf842bSKuba Brecka   Stream &strm = stream.ref();
272afdf842bSKuba Brecka 
273b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
274b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
275b2e7d28eSJim Ingham 
276afdf842bSKuba Brecka   if (!exe_ctx.HasThreadScope())
277afdf842bSKuba Brecka     return false;
278afdf842bSKuba Brecka 
279afdf842bSKuba Brecka   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
280afdf842bSKuba Brecka   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
281afdf842bSKuba Brecka   if (!info)
282afdf842bSKuba Brecka     return false;
283afdf842bSKuba Brecka 
284afdf842bSKuba Brecka   info->Dump(strm);
285afdf842bSKuba Brecka 
286afdf842bSKuba Brecka   return true;
287afdf842bSKuba Brecka }
288afdf842bSKuba Brecka 
2896a831436SKuba Brecka SBThreadCollection
290b9c1b51eSKate Stone SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
291baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBThreadCollection, SBThread,
292baf5664fSJonas Devlieghere                      GetStopReasonExtendedBacktraces,
293baf5664fSJonas Devlieghere                      (lldb::InstrumentationRuntimeType), type);
294baf5664fSJonas Devlieghere 
295*5e3fe22cSJonas Devlieghere   SBThreadCollection threads;
2966a831436SKuba Brecka 
297b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
298b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
299b2e7d28eSJim Ingham 
3006a831436SKuba Brecka   if (!exe_ctx.HasThreadScope())
301*5e3fe22cSJonas Devlieghere     return LLDB_RECORD_RESULT(SBThreadCollection());
3026a831436SKuba Brecka 
3036a831436SKuba Brecka   ProcessSP process_sp = exe_ctx.GetProcessSP();
3046a831436SKuba Brecka 
3056a831436SKuba Brecka   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
3066a831436SKuba Brecka   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
3076a831436SKuba Brecka   if (!info)
308baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(threads);
3096a831436SKuba Brecka 
310*5e3fe22cSJonas Devlieghere   threads = process_sp->GetInstrumentationRuntime(type)
311*5e3fe22cSJonas Devlieghere                 ->GetBacktracesFromExtendedStopInfo(info);
312*5e3fe22cSJonas Devlieghere   return LLDB_RECORD_RESULT(threads);
3136a831436SKuba Brecka }
3146a831436SKuba Brecka 
315b9c1b51eSKate Stone size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
3163da7dcf3SJonas Devlieghere   LLDB_RECORD_METHOD(size_t, SBThread, GetStopDescription, (char *, size_t), "",
3173da7dcf3SJonas Devlieghere                      dst_len);
318baf5664fSJonas Devlieghere 
319bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
320bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3214fc6cb9cSJim Ingham 
322b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
3237fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
324b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
3257fdf9ef1SGreg Clayton 
3261ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
327b9c1b51eSKate Stone       if (stop_info_sp) {
3287ebe9cc4SMed Ismail Bennani         std::string thread_stop_desc =
3297ebe9cc4SMed Ismail Bennani             exe_ctx.GetThreadPtr()->GetStopDescription();
3307ebe9cc4SMed Ismail Bennani         const char *stop_desc = thread_stop_desc.c_str();
3317ebe9cc4SMed Ismail Bennani 
3327ebe9cc4SMed Ismail Bennani         if (stop_desc[0] != '\0') {
33330fdc8d8SChris Lattner           if (dst)
33430fdc8d8SChris Lattner             return ::snprintf(dst, dst_len, "%s", stop_desc);
335b9c1b51eSKate Stone           else {
336b9c1b51eSKate Stone             // NULL dst passed in, return the length needed to contain the
337b9c1b51eSKate Stone             // description
33830fdc8d8SChris Lattner             return ::strlen(stop_desc) + 1; // Include the NULL byte for size
33930fdc8d8SChris Lattner           }
340b9c1b51eSKate Stone         } else {
34130fdc8d8SChris Lattner           size_t stop_desc_len = 0;
342b9c1b51eSKate Stone           switch (stop_info_sp->GetStopReason()) {
34330fdc8d8SChris Lattner           case eStopReasonTrace:
344b9c1b51eSKate Stone           case eStopReasonPlanComplete: {
34530fdc8d8SChris Lattner             static char trace_desc[] = "step";
34630fdc8d8SChris Lattner             stop_desc = trace_desc;
347b9c1b51eSKate Stone             stop_desc_len =
348b9c1b51eSKate Stone                 sizeof(trace_desc); // Include the NULL byte for size
349b9c1b51eSKate Stone           } break;
35030fdc8d8SChris Lattner 
351b9c1b51eSKate Stone           case eStopReasonBreakpoint: {
35230fdc8d8SChris Lattner             static char bp_desc[] = "breakpoint hit";
35330fdc8d8SChris Lattner             stop_desc = bp_desc;
35430fdc8d8SChris Lattner             stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
355b9c1b51eSKate Stone           } break;
35630fdc8d8SChris Lattner 
357b9c1b51eSKate Stone           case eStopReasonWatchpoint: {
35830fdc8d8SChris Lattner             static char wp_desc[] = "watchpoint hit";
35930fdc8d8SChris Lattner             stop_desc = wp_desc;
36030fdc8d8SChris Lattner             stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
361b9c1b51eSKate Stone           } break;
36230fdc8d8SChris Lattner 
363b9c1b51eSKate Stone           case eStopReasonSignal: {
364b9c1b51eSKate Stone             stop_desc =
365b9c1b51eSKate Stone                 exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString(
366b9c1b51eSKate Stone                     stop_info_sp->GetValue());
367248a1305SKonrad Kleine             if (stop_desc == nullptr || stop_desc[0] == '\0') {
36830fdc8d8SChris Lattner               static char signal_desc[] = "signal";
36930fdc8d8SChris Lattner               stop_desc = signal_desc;
370b9c1b51eSKate Stone               stop_desc_len =
371b9c1b51eSKate Stone                   sizeof(signal_desc); // Include the NULL byte for size
37230fdc8d8SChris Lattner             }
373b9c1b51eSKate Stone           } break;
37430fdc8d8SChris Lattner 
375b9c1b51eSKate Stone           case eStopReasonException: {
37630fdc8d8SChris Lattner             char exc_desc[] = "exception";
37730fdc8d8SChris Lattner             stop_desc = exc_desc;
37830fdc8d8SChris Lattner             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
379b9c1b51eSKate Stone           } break;
380c982c768SGreg Clayton 
381b9c1b51eSKate Stone           case eStopReasonExec: {
38290ba8115SGreg Clayton             char exc_desc[] = "exec";
38390ba8115SGreg Clayton             stop_desc = exc_desc;
38490ba8115SGreg Clayton             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
385b9c1b51eSKate Stone           } break;
38690ba8115SGreg Clayton 
387b9c1b51eSKate Stone           case eStopReasonThreadExiting: {
388f85defaeSAndrew Kaylor             char limbo_desc[] = "thread exiting";
389f85defaeSAndrew Kaylor             stop_desc = limbo_desc;
390f85defaeSAndrew Kaylor             stop_desc_len = sizeof(limbo_desc);
391b9c1b51eSKate Stone           } break;
392c982c768SGreg Clayton           default:
393c982c768SGreg Clayton             break;
39430fdc8d8SChris Lattner           }
39530fdc8d8SChris Lattner 
396b9c1b51eSKate Stone           if (stop_desc && stop_desc[0]) {
39730fdc8d8SChris Lattner             if (dst)
398b9c1b51eSKate Stone               return ::snprintf(dst, dst_len, "%s", stop_desc) +
399b9c1b51eSKate Stone                      1; // Include the NULL byte
40030fdc8d8SChris Lattner 
40130fdc8d8SChris Lattner             if (stop_desc_len == 0)
40230fdc8d8SChris Lattner               stop_desc_len = ::strlen(stop_desc) + 1; // Include the NULL byte
40330fdc8d8SChris Lattner 
40430fdc8d8SChris Lattner             return stop_desc_len;
40530fdc8d8SChris Lattner           }
40630fdc8d8SChris Lattner         }
40730fdc8d8SChris Lattner       }
408c9858e4dSGreg Clayton     }
4097fdf9ef1SGreg Clayton   }
41030fdc8d8SChris Lattner   if (dst)
41130fdc8d8SChris Lattner     *dst = 0;
41230fdc8d8SChris Lattner   return 0;
41330fdc8d8SChris Lattner }
41430fdc8d8SChris Lattner 
415b9c1b51eSKate Stone SBValue SBThread::GetStopReturnValue() {
416baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBValue, SBThread, GetStopReturnValue);
417baf5664fSJonas Devlieghere 
41873ca05a2SJim Ingham   ValueObjectSP return_valobj_sp;
419bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
420bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4214fc6cb9cSJim Ingham 
422b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4237fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
424b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4251ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
426b9c1b51eSKate Stone       if (stop_info_sp) {
42773ca05a2SJim Ingham         return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp);
42873ca05a2SJim Ingham       }
429c9858e4dSGreg Clayton     }
4307fdf9ef1SGreg Clayton   }
43173ca05a2SJim Ingham 
432baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(SBValue(return_valobj_sp));
43373ca05a2SJim Ingham }
43473ca05a2SJim Ingham 
435b9c1b51eSKate Stone void SBThread::SetThread(const ThreadSP &lldb_object_sp) {
4367fdf9ef1SGreg Clayton   m_opaque_sp->SetThreadSP(lldb_object_sp);
43730fdc8d8SChris Lattner }
43830fdc8d8SChris Lattner 
439b9c1b51eSKate Stone lldb::tid_t SBThread::GetThreadID() const {
440baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::tid_t, SBThread, GetThreadID);
441baf5664fSJonas Devlieghere 
4427fdf9ef1SGreg Clayton   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
44317a6ad05SGreg Clayton   if (thread_sp)
4441ac04c30SGreg Clayton     return thread_sp->GetID();
4451ac04c30SGreg Clayton   return LLDB_INVALID_THREAD_ID;
44630fdc8d8SChris Lattner }
44730fdc8d8SChris Lattner 
448b9c1b51eSKate Stone uint32_t SBThread::GetIndexID() const {
449baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBThread, GetIndexID);
450baf5664fSJonas Devlieghere 
4517fdf9ef1SGreg Clayton   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
45217a6ad05SGreg Clayton   if (thread_sp)
45317a6ad05SGreg Clayton     return thread_sp->GetIndexID();
45430fdc8d8SChris Lattner   return LLDB_INVALID_INDEX32;
45530fdc8d8SChris Lattner }
4561ac04c30SGreg Clayton 
457b9c1b51eSKate Stone const char *SBThread::GetName() const {
458baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBThread, GetName);
459baf5664fSJonas Devlieghere 
460248a1305SKonrad Kleine   const char *name = nullptr;
461bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
462bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4634fc6cb9cSJim Ingham 
464b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4657fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
466b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4671ac04c30SGreg Clayton       name = exe_ctx.GetThreadPtr()->GetName();
468c9858e4dSGreg Clayton     }
4697fdf9ef1SGreg Clayton   }
470ceb6b139SCaroline Tice 
4714838131bSGreg Clayton   return name;
47230fdc8d8SChris Lattner }
47330fdc8d8SChris Lattner 
474b9c1b51eSKate Stone const char *SBThread::GetQueueName() const {
475baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBThread, GetQueueName);
476baf5664fSJonas Devlieghere 
477248a1305SKonrad Kleine   const char *name = nullptr;
478bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
479bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4804fc6cb9cSJim Ingham 
481b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4827fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
483b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4841ac04c30SGreg Clayton       name = exe_ctx.GetThreadPtr()->GetQueueName();
485c9858e4dSGreg Clayton     }
4867fdf9ef1SGreg Clayton   }
487ceb6b139SCaroline Tice 
4884838131bSGreg Clayton   return name;
48930fdc8d8SChris Lattner }
49030fdc8d8SChris Lattner 
491b9c1b51eSKate Stone lldb::queue_id_t SBThread::GetQueueID() const {
492baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::queue_id_t, SBThread, GetQueueID);
493baf5664fSJonas Devlieghere 
4944fdb5863SJason Molenda   queue_id_t id = LLDB_INVALID_QUEUE_ID;
495bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
496bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4974fdb5863SJason Molenda 
498b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4994fdb5863SJason Molenda     Process::StopLocker stop_locker;
500b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
5014fdb5863SJason Molenda       id = exe_ctx.GetThreadPtr()->GetQueueID();
5024fdb5863SJason Molenda     }
5034fdb5863SJason Molenda   }
5044fdb5863SJason Molenda 
5054fdb5863SJason Molenda   return id;
5064fdb5863SJason Molenda }
5074fdb5863SJason Molenda 
508b9c1b51eSKate Stone bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
509baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, GetInfoItemByPathAsString,
510baf5664fSJonas Devlieghere                      (const char *, lldb::SBStream &), path, strm);
511baf5664fSJonas Devlieghere 
512705b1809SJason Molenda   bool success = false;
513bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
514bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
515705b1809SJason Molenda 
516b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
517705b1809SJason Molenda     Process::StopLocker stop_locker;
518b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
519705b1809SJason Molenda       Thread *thread = exe_ctx.GetThreadPtr();
520705b1809SJason Molenda       StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
521b9c1b51eSKate Stone       if (info_root_sp) {
522b9c1b51eSKate Stone         StructuredData::ObjectSP node =
523b9c1b51eSKate Stone             info_root_sp->GetObjectForDotSeparatedPath(path);
524b9c1b51eSKate Stone         if (node) {
5255bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeString) {
5262833321fSZachary Turner             strm.Printf("%s", node->GetAsString()->GetValue().str().c_str());
527705b1809SJason Molenda             success = true;
528705b1809SJason Molenda           }
5295bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeInteger) {
530705b1809SJason Molenda             strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue());
531705b1809SJason Molenda             success = true;
532705b1809SJason Molenda           }
5335bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeFloat) {
534705b1809SJason Molenda             strm.Printf("0x%f", node->GetAsFloat()->GetValue());
535705b1809SJason Molenda             success = true;
536705b1809SJason Molenda           }
5375bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeBoolean) {
538a6682a41SJonas Devlieghere             if (node->GetAsBoolean()->GetValue())
539705b1809SJason Molenda               strm.Printf("true");
540705b1809SJason Molenda             else
541705b1809SJason Molenda               strm.Printf("false");
542705b1809SJason Molenda             success = true;
543705b1809SJason Molenda           }
5445bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeNull) {
545705b1809SJason Molenda             strm.Printf("null");
546705b1809SJason Molenda             success = true;
547705b1809SJason Molenda           }
548705b1809SJason Molenda         }
549705b1809SJason Molenda       }
550705b1809SJason Molenda     }
551705b1809SJason Molenda   }
552705b1809SJason Molenda 
553705b1809SJason Molenda   return success;
554705b1809SJason Molenda }
555705b1809SJason Molenda 
556b9c1b51eSKate Stone SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
557b9c1b51eSKate Stone                                 ThreadPlan *new_plan) {
55864e7ead1SJim Ingham   SBError sb_error;
55964e7ead1SJim Ingham 
56064e7ead1SJim Ingham   Process *process = exe_ctx.GetProcessPtr();
561b9c1b51eSKate Stone   if (!process) {
56264e7ead1SJim Ingham     sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
56364e7ead1SJim Ingham     return sb_error;
56464e7ead1SJim Ingham   }
56564e7ead1SJim Ingham 
56664e7ead1SJim Ingham   Thread *thread = exe_ctx.GetThreadPtr();
567b9c1b51eSKate Stone   if (!thread) {
56864e7ead1SJim Ingham     sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
56964e7ead1SJim Ingham     return sb_error;
57064e7ead1SJim Ingham   }
57164e7ead1SJim Ingham 
572b9c1b51eSKate Stone   // User level plans should be Master Plans so they can be interrupted, other
57305097246SAdrian Prantl   // plans executed, and then a "continue" will resume the plan.
574248a1305SKonrad Kleine   if (new_plan != nullptr) {
57564e7ead1SJim Ingham     new_plan->SetIsMasterPlan(true);
57664e7ead1SJim Ingham     new_plan->SetOkayToDiscard(false);
57764e7ead1SJim Ingham   }
57864e7ead1SJim Ingham 
57964e7ead1SJim Ingham   // Why do we need to set the current thread by ID here???
58064e7ead1SJim Ingham   process->GetThreadList().SetSelectedThreadByID(thread->GetID());
58164e7ead1SJim Ingham 
582dc6224e0SGreg Clayton   if (process->GetTarget().GetDebugger().GetAsyncExecution())
583dc6224e0SGreg Clayton     sb_error.ref() = process->Resume();
584dc6224e0SGreg Clayton   else
585248a1305SKonrad Kleine     sb_error.ref() = process->ResumeSynchronous(nullptr);
58664e7ead1SJim Ingham 
58764e7ead1SJim Ingham   return sb_error;
58864e7ead1SJim Ingham }
58930fdc8d8SChris Lattner 
590b9c1b51eSKate Stone void SBThread::StepOver(lldb::RunMode stop_other_threads) {
591baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOver, (lldb::RunMode),
592baf5664fSJonas Devlieghere                      stop_other_threads);
593baf5664fSJonas Devlieghere 
594859f54b3SAlexander Polyakov   SBError error; // Ignored
595859f54b3SAlexander Polyakov   StepOver(stop_other_threads, error);
596859f54b3SAlexander Polyakov }
597859f54b3SAlexander Polyakov 
598859f54b3SAlexander Polyakov void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
599baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOver, (lldb::RunMode, lldb::SBError &),
600baf5664fSJonas Devlieghere                      stop_other_threads, error);
601baf5664fSJonas Devlieghere 
602bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
603bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
60417a6ad05SGreg Clayton 
605859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
606859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
607859f54b3SAlexander Polyakov     return;
608859f54b3SAlexander Polyakov   }
609859f54b3SAlexander Polyakov 
6101ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
6117ba6e991SJim Ingham   bool abort_other_plans = false;
612b57e4a1bSJason Molenda   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
61330fdc8d8SChris Lattner 
614e103ae92SJonas Devlieghere   Status new_plan_status;
6154d56e9c1SJim Ingham   ThreadPlanSP new_plan_sp;
616b9c1b51eSKate Stone   if (frame_sp) {
617b9c1b51eSKate Stone     if (frame_sp->HasDebugInformation()) {
6184b4b2478SJim Ingham       const LazyBool avoid_no_debug = eLazyBoolCalculate;
61930fdc8d8SChris Lattner       SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
620b9c1b51eSKate Stone       new_plan_sp = thread->QueueThreadPlanForStepOverRange(
621b9c1b51eSKate Stone           abort_other_plans, sc.line_entry, sc, stop_other_threads,
622e103ae92SJonas Devlieghere           new_plan_status, avoid_no_debug);
623b9c1b51eSKate Stone     } else {
624b9c1b51eSKate Stone       new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
625e103ae92SJonas Devlieghere           true, abort_other_plans, stop_other_threads, new_plan_status);
62630fdc8d8SChris Lattner     }
62730fdc8d8SChris Lattner   }
628859f54b3SAlexander Polyakov   error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
62930fdc8d8SChris Lattner }
63030fdc8d8SChris Lattner 
631b9c1b51eSKate Stone void SBThread::StepInto(lldb::RunMode stop_other_threads) {
632baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInto, (lldb::RunMode),
633baf5664fSJonas Devlieghere                      stop_other_threads);
634baf5664fSJonas Devlieghere 
635248a1305SKonrad Kleine   StepInto(nullptr, stop_other_threads);
636c627682eSJim Ingham }
637c627682eSJim Ingham 
638b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name,
639b9c1b51eSKate Stone                         lldb::RunMode stop_other_threads) {
640baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInto, (const char *, lldb::RunMode),
641baf5664fSJonas Devlieghere                      target_name, stop_other_threads);
642baf5664fSJonas Devlieghere 
643859f54b3SAlexander Polyakov   SBError error; // Ignored
644cbf6f9b2SJim Ingham   StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
645cbf6f9b2SJim Ingham }
646cbf6f9b2SJim Ingham 
647b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name, uint32_t end_line,
648b9c1b51eSKate Stone                         SBError &error, lldb::RunMode stop_other_threads) {
649baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInto,
650baf5664fSJonas Devlieghere                      (const char *, uint32_t, lldb::SBError &, lldb::RunMode),
651baf5664fSJonas Devlieghere                      target_name, end_line, error, stop_other_threads);
652baf5664fSJonas Devlieghere 
653ceb6b139SCaroline Tice 
654bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
655bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
65617a6ad05SGreg Clayton 
657859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
658859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
659859f54b3SAlexander Polyakov     return;
660859f54b3SAlexander Polyakov   }
661859f54b3SAlexander Polyakov 
6627ba6e991SJim Ingham   bool abort_other_plans = false;
66330fdc8d8SChris Lattner 
6641ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
665b57e4a1bSJason Molenda   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
6664d56e9c1SJim Ingham   ThreadPlanSP new_plan_sp;
667e103ae92SJonas Devlieghere   Status new_plan_status;
66830fdc8d8SChris Lattner 
669b9c1b51eSKate Stone   if (frame_sp && frame_sp->HasDebugInformation()) {
670cbf6f9b2SJim Ingham     SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
671cbf6f9b2SJim Ingham     AddressRange range;
672cbf6f9b2SJim Ingham     if (end_line == LLDB_INVALID_LINE_NUMBER)
673cbf6f9b2SJim Ingham       range = sc.line_entry.range;
674b9c1b51eSKate Stone     else {
675cbf6f9b2SJim Ingham       if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
676cbf6f9b2SJim Ingham         return;
677cbf6f9b2SJim Ingham     }
678cbf6f9b2SJim Ingham 
679b9c1b51eSKate Stone     const LazyBool step_out_avoids_code_without_debug_info =
680b9c1b51eSKate Stone         eLazyBoolCalculate;
681b9c1b51eSKate Stone     const LazyBool step_in_avoids_code_without_debug_info =
682b9c1b51eSKate Stone         eLazyBoolCalculate;
683b9c1b51eSKate Stone     new_plan_sp = thread->QueueThreadPlanForStepInRange(
684b9c1b51eSKate Stone         abort_other_plans, range, sc, target_name, stop_other_threads,
685e103ae92SJonas Devlieghere         new_plan_status, step_in_avoids_code_without_debug_info,
6864b4b2478SJim Ingham         step_out_avoids_code_without_debug_info);
687b9c1b51eSKate Stone   } else {
688b9c1b51eSKate Stone     new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
689e103ae92SJonas Devlieghere         false, abort_other_plans, stop_other_threads, new_plan_status);
69030fdc8d8SChris Lattner   }
691e103ae92SJonas Devlieghere 
692e103ae92SJonas Devlieghere   if (new_plan_status.Success())
693cbf6f9b2SJim Ingham     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
694e103ae92SJonas Devlieghere   else
695e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
69630fdc8d8SChris Lattner }
69730fdc8d8SChris Lattner 
698b9c1b51eSKate Stone void SBThread::StepOut() {
699baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(void, SBThread, StepOut);
700baf5664fSJonas Devlieghere 
701859f54b3SAlexander Polyakov   SBError error; // Ignored
702859f54b3SAlexander Polyakov   StepOut(error);
703859f54b3SAlexander Polyakov }
704859f54b3SAlexander Polyakov 
705859f54b3SAlexander Polyakov void SBThread::StepOut(SBError &error) {
706baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOut, (lldb::SBError &), error);
707baf5664fSJonas Devlieghere 
708bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
709bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
7104fc6cb9cSJim Ingham 
711859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
712859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
713859f54b3SAlexander Polyakov     return;
714859f54b3SAlexander Polyakov   }
715859f54b3SAlexander Polyakov 
7167ba6e991SJim Ingham   bool abort_other_plans = false;
71794b09246SJim Ingham   bool stop_other_threads = false;
71830fdc8d8SChris Lattner 
7191ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
7201ac04c30SGreg Clayton 
7214b4b2478SJim Ingham   const LazyBool avoid_no_debug = eLazyBoolCalculate;
722e103ae92SJonas Devlieghere   Status new_plan_status;
723b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
724248a1305SKonrad Kleine       abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
725e103ae92SJonas Devlieghere       eVoteNoOpinion, 0, new_plan_status, avoid_no_debug));
726481cef25SGreg Clayton 
727e103ae92SJonas Devlieghere   if (new_plan_status.Success())
728859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
729e103ae92SJonas Devlieghere   else
730e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
731481cef25SGreg Clayton }
732481cef25SGreg Clayton 
733859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
734baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOutOfFrame, (lldb::SBFrame &),
735baf5664fSJonas Devlieghere                      sb_frame);
736baf5664fSJonas Devlieghere 
737859f54b3SAlexander Polyakov   SBError error; // Ignored
738859f54b3SAlexander Polyakov   StepOutOfFrame(sb_frame, error);
739859f54b3SAlexander Polyakov }
740859f54b3SAlexander Polyakov 
741859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
742baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOutOfFrame,
743baf5664fSJonas Devlieghere                      (lldb::SBFrame &, lldb::SBError &), sb_frame, error);
744baf5664fSJonas Devlieghere 
745481cef25SGreg Clayton 
746bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
747bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
7484fc6cb9cSJim Ingham 
749b9c1b51eSKate Stone   if (!sb_frame.IsValid()) {
750859f54b3SAlexander Polyakov     error.SetErrorString("passed invalid SBFrame object");
751989a7558SJim Ingham     return;
752989a7558SJim Ingham   }
753989a7558SJim Ingham 
754b57e4a1bSJason Molenda   StackFrameSP frame_sp(sb_frame.GetFrameSP());
755481cef25SGreg Clayton 
756859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
757859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
758859f54b3SAlexander Polyakov     return;
759859f54b3SAlexander Polyakov   }
760859f54b3SAlexander Polyakov 
7617ba6e991SJim Ingham   bool abort_other_plans = false;
76294b09246SJim Ingham   bool stop_other_threads = false;
7631ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
764b9c1b51eSKate Stone   if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
765859f54b3SAlexander Polyakov     error.SetErrorString("passed a frame from another thread");
766859f54b3SAlexander Polyakov     return;
767989a7558SJim Ingham   }
768481cef25SGreg Clayton 
769e103ae92SJonas Devlieghere   Status new_plan_status;
770b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
771248a1305SKonrad Kleine       abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
772e103ae92SJonas Devlieghere       eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status));
77330fdc8d8SChris Lattner 
774e103ae92SJonas Devlieghere   if (new_plan_status.Success())
775859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
776e103ae92SJonas Devlieghere   else
777e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
77830fdc8d8SChris Lattner }
77930fdc8d8SChris Lattner 
780b9c1b51eSKate Stone void SBThread::StepInstruction(bool step_over) {
781baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInstruction, (bool), step_over);
782baf5664fSJonas Devlieghere 
783859f54b3SAlexander Polyakov   SBError error; // Ignored
784859f54b3SAlexander Polyakov   StepInstruction(step_over, error);
785859f54b3SAlexander Polyakov }
786859f54b3SAlexander Polyakov 
787859f54b3SAlexander Polyakov void SBThread::StepInstruction(bool step_over, SBError &error) {
788baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInstruction, (bool, lldb::SBError &),
789baf5664fSJonas Devlieghere                      step_over, error);
790baf5664fSJonas Devlieghere 
791bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
792bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
793ceb6b139SCaroline Tice 
794859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
795859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
796859f54b3SAlexander Polyakov     return;
797859f54b3SAlexander Polyakov   }
798859f54b3SAlexander Polyakov 
7991ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
800e103ae92SJonas Devlieghere   Status new_plan_status;
801e103ae92SJonas Devlieghere   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction(
802e103ae92SJonas Devlieghere       step_over, true, true, new_plan_status));
80364e7ead1SJim Ingham 
804e103ae92SJonas Devlieghere   if (new_plan_status.Success())
805859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
806e103ae92SJonas Devlieghere   else
807e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
80830fdc8d8SChris Lattner }
80930fdc8d8SChris Lattner 
810b9c1b51eSKate Stone void SBThread::RunToAddress(lldb::addr_t addr) {
811baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, RunToAddress, (lldb::addr_t), addr);
812baf5664fSJonas Devlieghere 
813859f54b3SAlexander Polyakov   SBError error; // Ignored
814859f54b3SAlexander Polyakov   RunToAddress(addr, error);
815859f54b3SAlexander Polyakov }
816859f54b3SAlexander Polyakov 
817859f54b3SAlexander Polyakov void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
818baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, RunToAddress,
819baf5664fSJonas Devlieghere                      (lldb::addr_t, lldb::SBError &), addr, error);
820baf5664fSJonas Devlieghere 
821bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
822bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
823ceb6b139SCaroline Tice 
824859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
825859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
826859f54b3SAlexander Polyakov     return;
827859f54b3SAlexander Polyakov   }
828859f54b3SAlexander Polyakov 
8297ba6e991SJim Ingham   bool abort_other_plans = false;
83030fdc8d8SChris Lattner   bool stop_other_threads = true;
83130fdc8d8SChris Lattner 
832e72dfb32SGreg Clayton   Address target_addr(addr);
83330fdc8d8SChris Lattner 
8341ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
8351ac04c30SGreg Clayton 
836e103ae92SJonas Devlieghere   Status new_plan_status;
837b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
838e103ae92SJonas Devlieghere       abort_other_plans, target_addr, stop_other_threads, new_plan_status));
83964e7ead1SJim Ingham 
840e103ae92SJonas Devlieghere   if (new_plan_status.Success())
841859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
842e103ae92SJonas Devlieghere   else
843e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
84430fdc8d8SChris Lattner }
84530fdc8d8SChris Lattner 
846b9c1b51eSKate Stone SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
847b9c1b51eSKate Stone                                 lldb::SBFileSpec &sb_file_spec, uint32_t line) {
848baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepOverUntil,
849baf5664fSJonas Devlieghere                      (lldb::SBFrame &, lldb::SBFileSpec &, uint32_t), sb_frame,
850baf5664fSJonas Devlieghere                      sb_file_spec, line);
851baf5664fSJonas Devlieghere 
852481cef25SGreg Clayton   SBError sb_error;
853481cef25SGreg Clayton   char path[PATH_MAX];
854481cef25SGreg Clayton 
855bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
856bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
8574fc6cb9cSJim Ingham 
858b57e4a1bSJason Molenda   StackFrameSP frame_sp(sb_frame.GetFrameSP());
85917a6ad05SGreg Clayton 
860b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
8611ac04c30SGreg Clayton     Target *target = exe_ctx.GetTargetPtr();
8621ac04c30SGreg Clayton     Thread *thread = exe_ctx.GetThreadPtr();
863481cef25SGreg Clayton 
864b9c1b51eSKate Stone     if (line == 0) {
865481cef25SGreg Clayton       sb_error.SetErrorString("invalid line argument");
866baf5664fSJonas Devlieghere       return LLDB_RECORD_RESULT(sb_error);
867481cef25SGreg Clayton     }
868481cef25SGreg Clayton 
869b9c1b51eSKate Stone     if (!frame_sp) {
8701ac04c30SGreg Clayton       frame_sp = thread->GetSelectedFrame();
871481cef25SGreg Clayton       if (!frame_sp)
8721ac04c30SGreg Clayton         frame_sp = thread->GetStackFrameAtIndex(0);
873481cef25SGreg Clayton     }
874481cef25SGreg Clayton 
875481cef25SGreg Clayton     SymbolContext frame_sc;
876b9c1b51eSKate Stone     if (!frame_sp) {
877481cef25SGreg Clayton       sb_error.SetErrorString("no valid frames in thread to step");
878baf5664fSJonas Devlieghere       return LLDB_RECORD_RESULT(sb_error);
879481cef25SGreg Clayton     }
880481cef25SGreg Clayton 
881481cef25SGreg Clayton     // If we have a frame, get its line
882b9c1b51eSKate Stone     frame_sc = frame_sp->GetSymbolContext(
883b9c1b51eSKate Stone         eSymbolContextCompUnit | eSymbolContextFunction |
884b9c1b51eSKate Stone         eSymbolContextLineEntry | eSymbolContextSymbol);
885481cef25SGreg Clayton 
886248a1305SKonrad Kleine     if (frame_sc.comp_unit == nullptr) {
887b9c1b51eSKate Stone       sb_error.SetErrorStringWithFormat(
888b9c1b51eSKate Stone           "frame %u doesn't have debug information", frame_sp->GetFrameIndex());
889baf5664fSJonas Devlieghere       return LLDB_RECORD_RESULT(sb_error);
890481cef25SGreg Clayton     }
891481cef25SGreg Clayton 
892481cef25SGreg Clayton     FileSpec step_file_spec;
893b9c1b51eSKate Stone     if (sb_file_spec.IsValid()) {
894481cef25SGreg Clayton       // The file spec passed in was valid, so use it
895481cef25SGreg Clayton       step_file_spec = sb_file_spec.ref();
896b9c1b51eSKate Stone     } else {
897481cef25SGreg Clayton       if (frame_sc.line_entry.IsValid())
898481cef25SGreg Clayton         step_file_spec = frame_sc.line_entry.file;
899b9c1b51eSKate Stone       else {
900481cef25SGreg Clayton         sb_error.SetErrorString("invalid file argument or no file for frame");
901baf5664fSJonas Devlieghere         return LLDB_RECORD_RESULT(sb_error);
902481cef25SGreg Clayton       }
903481cef25SGreg Clayton     }
904481cef25SGreg Clayton 
9059b70ddb3SJim Ingham     // Grab the current function, then we will make sure the "until" address is
9069b70ddb3SJim Ingham     // within the function.  We discard addresses that are out of the current
907b9c1b51eSKate Stone     // function, and then if there are no addresses remaining, give an
90805097246SAdrian Prantl     // appropriate error message.
9099b70ddb3SJim Ingham 
9109b70ddb3SJim Ingham     bool all_in_function = true;
9119b70ddb3SJim Ingham     AddressRange fun_range = frame_sc.function->GetAddressRange();
9129b70ddb3SJim Ingham 
913481cef25SGreg Clayton     std::vector<addr_t> step_over_until_addrs;
9147ba6e991SJim Ingham     const bool abort_other_plans = false;
915c02e3344SJim Ingham     const bool stop_other_threads = false;
916481cef25SGreg Clayton     const bool check_inlines = true;
917481cef25SGreg Clayton     const bool exact = false;
918481cef25SGreg Clayton 
919481cef25SGreg Clayton     SymbolContextList sc_list;
920c671639aSKonrad Kleine     frame_sc.comp_unit->ResolveSymbolContext(step_file_spec, line,
921c671639aSKonrad Kleine                                              check_inlines, exact,
922c671639aSKonrad Kleine                                              eSymbolContextLineEntry, sc_list);
923c671639aSKonrad Kleine     const uint32_t num_matches = sc_list.GetSize();
924b9c1b51eSKate Stone     if (num_matches > 0) {
925481cef25SGreg Clayton       SymbolContext sc;
926b9c1b51eSKate Stone       for (uint32_t i = 0; i < num_matches; ++i) {
927b9c1b51eSKate Stone         if (sc_list.GetContextAtIndex(i, sc)) {
928b9c1b51eSKate Stone           addr_t step_addr =
929b9c1b51eSKate Stone               sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
930b9c1b51eSKate Stone           if (step_addr != LLDB_INVALID_ADDRESS) {
9319b70ddb3SJim Ingham             if (fun_range.ContainsLoadAddress(step_addr, target))
932481cef25SGreg Clayton               step_over_until_addrs.push_back(step_addr);
9339b70ddb3SJim Ingham             else
9349b70ddb3SJim Ingham               all_in_function = false;
935481cef25SGreg Clayton           }
936481cef25SGreg Clayton         }
937481cef25SGreg Clayton       }
938481cef25SGreg Clayton     }
939481cef25SGreg Clayton 
940b9c1b51eSKate Stone     if (step_over_until_addrs.empty()) {
941b9c1b51eSKate Stone       if (all_in_function) {
942481cef25SGreg Clayton         step_file_spec.GetPath(path, sizeof(path));
943b9c1b51eSKate Stone         sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path,
944b9c1b51eSKate Stone                                           line);
945b9c1b51eSKate Stone       } else
94686edbf41SGreg Clayton         sb_error.SetErrorString("step until target not in current function");
947b9c1b51eSKate Stone     } else {
948e103ae92SJonas Devlieghere       Status new_plan_status;
949b9c1b51eSKate Stone       ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil(
950b9c1b51eSKate Stone           abort_other_plans, &step_over_until_addrs[0],
951b9c1b51eSKate Stone           step_over_until_addrs.size(), stop_other_threads,
952e103ae92SJonas Devlieghere           frame_sp->GetFrameIndex(), new_plan_status));
953481cef25SGreg Clayton 
954e103ae92SJonas Devlieghere       if (new_plan_status.Success())
9554d56e9c1SJim Ingham         sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
956e103ae92SJonas Devlieghere       else
957e103ae92SJonas Devlieghere         sb_error.SetErrorString(new_plan_status.AsCString());
958481cef25SGreg Clayton     }
959b9c1b51eSKate Stone   } else {
960481cef25SGreg Clayton     sb_error.SetErrorString("this SBThread object is invalid");
961481cef25SGreg Clayton   }
962baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
963481cef25SGreg Clayton }
964481cef25SGreg Clayton 
965b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) {
966baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
967baf5664fSJonas Devlieghere                      (const char *), script_class_name);
968baf5664fSJonas Devlieghere 
969baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
970baf5664fSJonas Devlieghere       StepUsingScriptedThreadPlan(script_class_name, true));
971c915a7d2SJim Ingham }
972c915a7d2SJim Ingham 
973b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
974b9c1b51eSKate Stone                                             bool resume_immediately) {
975baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
976baf5664fSJonas Devlieghere                      (const char *, bool), script_class_name,
977baf5664fSJonas Devlieghere                      resume_immediately);
978baf5664fSJonas Devlieghere 
97927a14f19SJim Ingham   lldb::SBStructuredData no_data;
9803da7dcf3SJonas Devlieghere   return LLDB_RECORD_RESULT(StepUsingScriptedThreadPlan(
9813da7dcf3SJonas Devlieghere       script_class_name, no_data, resume_immediately));
98227a14f19SJim Ingham }
98327a14f19SJim Ingham 
98427a14f19SJim Ingham SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
98527a14f19SJim Ingham                                               SBStructuredData &args_data,
98627a14f19SJim Ingham                                               bool resume_immediately) {
98727a14f19SJim Ingham   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
98827a14f19SJim Ingham                      (const char *, lldb::SBStructuredData &, bool),
9893da7dcf3SJonas Devlieghere                      script_class_name, args_data, resume_immediately);
99027a14f19SJim Ingham 
991e103ae92SJonas Devlieghere   SBError error;
9922bdbfd50SJim Ingham 
993bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
994bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
9952bdbfd50SJim Ingham 
996b9c1b51eSKate Stone   if (!exe_ctx.HasThreadScope()) {
997e103ae92SJonas Devlieghere     error.SetErrorString("this SBThread object is invalid");
998baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(error);
9992bdbfd50SJim Ingham   }
10002bdbfd50SJim Ingham 
10012bdbfd50SJim Ingham   Thread *thread = exe_ctx.GetThreadPtr();
1002e103ae92SJonas Devlieghere   Status new_plan_status;
100327a14f19SJim Ingham   StructuredData::ObjectSP obj_sp = args_data.m_impl_up->GetObjectSP();
100427a14f19SJim Ingham 
1005e103ae92SJonas Devlieghere   ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted(
100627a14f19SJim Ingham       false, script_class_name, obj_sp, false, new_plan_status);
10072bdbfd50SJim Ingham 
1008e103ae92SJonas Devlieghere   if (new_plan_status.Fail()) {
1009e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
1010baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(error);
1011c915a7d2SJim Ingham   }
1012c915a7d2SJim Ingham 
1013e103ae92SJonas Devlieghere   if (!resume_immediately)
1014baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(error);
1015c915a7d2SJim Ingham 
1016e103ae92SJonas Devlieghere   if (new_plan_status.Success())
1017e103ae92SJonas Devlieghere     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
1018e103ae92SJonas Devlieghere   else
1019e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
10202bdbfd50SJim Ingham 
1021baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(error);
10222bdbfd50SJim Ingham }
10232bdbfd50SJim Ingham 
1024b9c1b51eSKate Stone SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
1025baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, JumpToLine,
1026baf5664fSJonas Devlieghere                      (lldb::SBFileSpec &, uint32_t), file_spec, line);
1027baf5664fSJonas Devlieghere 
1028f86248d9SRichard Mitton   SBError sb_error;
1029f86248d9SRichard Mitton 
1030bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1031bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1032f86248d9SRichard Mitton 
1033b9c1b51eSKate Stone   if (!exe_ctx.HasThreadScope()) {
1034f86248d9SRichard Mitton     sb_error.SetErrorString("this SBThread object is invalid");
1035baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(sb_error);
1036f86248d9SRichard Mitton   }
1037f86248d9SRichard Mitton 
1038f86248d9SRichard Mitton   Thread *thread = exe_ctx.GetThreadPtr();
1039f86248d9SRichard Mitton 
104028e4942bSPavel Labath   Status err = thread->JumpToLine(file_spec.ref(), line, true);
1041f86248d9SRichard Mitton   sb_error.SetError(err);
1042baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
1043f86248d9SRichard Mitton }
1044f86248d9SRichard Mitton 
1045b9c1b51eSKate Stone SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
1046baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, ReturnFromFrame,
1047baf5664fSJonas Devlieghere                      (lldb::SBFrame &, lldb::SBValue &), frame, return_value);
1048baf5664fSJonas Devlieghere 
10494413758cSJim Ingham   SBError sb_error;
10504413758cSJim Ingham 
1051bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1052bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
10534413758cSJim Ingham 
1054b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
10554413758cSJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
1056b9c1b51eSKate Stone     sb_error.SetError(
1057b9c1b51eSKate Stone         thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
10584413758cSJim Ingham   }
10594413758cSJim Ingham 
1060baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
10614413758cSJim Ingham }
10624413758cSJim Ingham 
1063b9c1b51eSKate Stone SBError SBThread::UnwindInnermostExpression() {
1064baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBError, SBThread,
1065baf5664fSJonas Devlieghere                              UnwindInnermostExpression);
1066baf5664fSJonas Devlieghere 
10674ac8e93aSJim Ingham   SBError sb_error;
10684ac8e93aSJim Ingham 
10694ac8e93aSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
10704ac8e93aSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
10714ac8e93aSJim Ingham 
1072b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
10734ac8e93aSJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
10744ac8e93aSJim Ingham     sb_error.SetError(thread->UnwindInnermostExpression());
10754ac8e93aSJim Ingham     if (sb_error.Success())
10764ac8e93aSJim Ingham       thread->SetSelectedFrameByIndex(0, false);
10774ac8e93aSJim Ingham   }
10784ac8e93aSJim Ingham 
1079baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
10804ac8e93aSJim Ingham }
1081481cef25SGreg Clayton 
1082b9c1b51eSKate Stone bool SBThread::Suspend() {
1083baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, Suspend);
1084baf5664fSJonas Devlieghere 
1085859f54b3SAlexander Polyakov   SBError error; // Ignored
1086859f54b3SAlexander Polyakov   return Suspend(error);
1087859f54b3SAlexander Polyakov }
1088859f54b3SAlexander Polyakov 
1089859f54b3SAlexander Polyakov bool SBThread::Suspend(SBError &error) {
1090baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, Suspend, (lldb::SBError &), error);
1091baf5664fSJonas Devlieghere 
1092b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1093b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1094b2e7d28eSJim Ingham 
1095c9858e4dSGreg Clayton   bool result = false;
1096b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1097c9858e4dSGreg Clayton     Process::StopLocker stop_locker;
1098b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
10991ac04c30SGreg Clayton       exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
1100c9858e4dSGreg Clayton       result = true;
1101b9c1b51eSKate Stone     } else {
1102859f54b3SAlexander Polyakov       error.SetErrorString("process is running");
1103c9858e4dSGreg Clayton     }
1104859f54b3SAlexander Polyakov   } else
1105859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
1106c9858e4dSGreg Clayton   return result;
1107722a0cdcSGreg Clayton }
1108722a0cdcSGreg Clayton 
1109b9c1b51eSKate Stone bool SBThread::Resume() {
1110baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, Resume);
1111baf5664fSJonas Devlieghere 
1112859f54b3SAlexander Polyakov   SBError error; // Ignored
1113859f54b3SAlexander Polyakov   return Resume(error);
1114859f54b3SAlexander Polyakov }
1115859f54b3SAlexander Polyakov 
1116859f54b3SAlexander Polyakov bool SBThread::Resume(SBError &error) {
1117baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, Resume, (lldb::SBError &), error);
1118baf5664fSJonas Devlieghere 
1119b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1120b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1121b2e7d28eSJim Ingham 
1122c9858e4dSGreg Clayton   bool result = false;
1123b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1124c9858e4dSGreg Clayton     Process::StopLocker stop_locker;
1125b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11266c9ed91cSJim Ingham       const bool override_suspend = true;
11276c9ed91cSJim Ingham       exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
1128c9858e4dSGreg Clayton       result = true;
1129b9c1b51eSKate Stone     } else {
1130859f54b3SAlexander Polyakov       error.SetErrorString("process is running");
1131c9858e4dSGreg Clayton     }
1132859f54b3SAlexander Polyakov   } else
1133859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
1134c9858e4dSGreg Clayton   return result;
1135722a0cdcSGreg Clayton }
1136722a0cdcSGreg Clayton 
1137b9c1b51eSKate Stone bool SBThread::IsSuspended() {
1138baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, IsSuspended);
1139baf5664fSJonas Devlieghere 
1140b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1141b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1142b2e7d28eSJim Ingham 
11431ac04c30SGreg Clayton   if (exe_ctx.HasThreadScope())
11441ac04c30SGreg Clayton     return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
1145722a0cdcSGreg Clayton   return false;
1146722a0cdcSGreg Clayton }
1147722a0cdcSGreg Clayton 
1148b9c1b51eSKate Stone bool SBThread::IsStopped() {
1149baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, IsStopped);
1150baf5664fSJonas Devlieghere 
1151b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1152b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1153b2e7d28eSJim Ingham 
1154a75418dbSAndrew Kaylor   if (exe_ctx.HasThreadScope())
1155a75418dbSAndrew Kaylor     return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1156a75418dbSAndrew Kaylor   return false;
1157a75418dbSAndrew Kaylor }
1158a75418dbSAndrew Kaylor 
1159b9c1b51eSKate Stone SBProcess SBThread::GetProcess() {
1160baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBProcess, SBThread, GetProcess);
1161baf5664fSJonas Devlieghere 
1162b9556accSGreg Clayton   SBProcess sb_process;
1163b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1164b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1165b2e7d28eSJim Ingham 
1166b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1167b9c1b51eSKate Stone     // Have to go up to the target so we can get a shared pointer to our
1168b9c1b51eSKate Stone     // process...
11691ac04c30SGreg Clayton     sb_process.SetSP(exe_ctx.GetProcessSP());
117030fdc8d8SChris Lattner   }
1171ceb6b139SCaroline Tice 
1172baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_process);
117330fdc8d8SChris Lattner }
117430fdc8d8SChris Lattner 
1175b9c1b51eSKate Stone uint32_t SBThread::GetNumFrames() {
1176baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBThread, GetNumFrames);
1177baf5664fSJonas Devlieghere 
1178ceb6b139SCaroline Tice   uint32_t num_frames = 0;
1179bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1180bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11814fc6cb9cSJim Ingham 
1182b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11837fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1184b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11851ac04c30SGreg Clayton       num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1186c9858e4dSGreg Clayton     }
11877fdf9ef1SGreg Clayton   }
1188ceb6b139SCaroline Tice 
1189ceb6b139SCaroline Tice   return num_frames;
119030fdc8d8SChris Lattner }
119130fdc8d8SChris Lattner 
1192b9c1b51eSKate Stone SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
1193baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBFrame, SBThread, GetFrameAtIndex, (uint32_t), idx);
1194baf5664fSJonas Devlieghere 
119530fdc8d8SChris Lattner   SBFrame sb_frame;
1196b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1197bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1198bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11994fc6cb9cSJim Ingham 
1200b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
12017fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1202b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
12031ac04c30SGreg Clayton       frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
1204b9556accSGreg Clayton       sb_frame.SetFrameSP(frame_sp);
1205c9858e4dSGreg Clayton     }
12067fdf9ef1SGreg Clayton   }
1207ceb6b139SCaroline Tice 
1208baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_frame);
120930fdc8d8SChris Lattner }
121030fdc8d8SChris Lattner 
1211b9c1b51eSKate Stone lldb::SBFrame SBThread::GetSelectedFrame() {
1212baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBFrame, SBThread, GetSelectedFrame);
1213baf5664fSJonas Devlieghere 
1214f028a1fbSGreg Clayton   SBFrame sb_frame;
1215b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1216bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1217bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12184fc6cb9cSJim Ingham 
1219b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
12207fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1221b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
12221ac04c30SGreg Clayton       frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame();
1223b9556accSGreg Clayton       sb_frame.SetFrameSP(frame_sp);
1224c9858e4dSGreg Clayton     }
12257fdf9ef1SGreg Clayton   }
1226f028a1fbSGreg Clayton 
1227baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_frame);
1228f028a1fbSGreg Clayton }
1229f028a1fbSGreg Clayton 
1230b9c1b51eSKate Stone lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
1231baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBFrame, SBThread, SetSelectedFrame, (uint32_t),
1232baf5664fSJonas Devlieghere                      idx);
1233baf5664fSJonas Devlieghere 
1234f028a1fbSGreg Clayton   SBFrame sb_frame;
1235b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1236bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1237bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12384fc6cb9cSJim Ingham 
1239b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
12407fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1241b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
12421ac04c30SGreg Clayton       Thread *thread = exe_ctx.GetThreadPtr();
12431ac04c30SGreg Clayton       frame_sp = thread->GetStackFrameAtIndex(idx);
1244b9c1b51eSKate Stone       if (frame_sp) {
12451ac04c30SGreg Clayton         thread->SetSelectedFrame(frame_sp.get());
1246b9556accSGreg Clayton         sb_frame.SetFrameSP(frame_sp);
1247f028a1fbSGreg Clayton       }
1248c9858e4dSGreg Clayton     }
12497fdf9ef1SGreg Clayton   }
1250f028a1fbSGreg Clayton 
1251baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_frame);
1252f028a1fbSGreg Clayton }
1253f028a1fbSGreg Clayton 
1254b9c1b51eSKate Stone bool SBThread::EventIsThreadEvent(const SBEvent &event) {
1255baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(bool, SBThread, EventIsThreadEvent,
1256baf5664fSJonas Devlieghere                             (const lldb::SBEvent &), event);
1257baf5664fSJonas Devlieghere 
1258248a1305SKonrad Kleine   return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != nullptr;
12594f465cffSJim Ingham }
12604f465cffSJim Ingham 
1261b9c1b51eSKate Stone SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) {
1262baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(lldb::SBFrame, SBThread, GetStackFrameFromEvent,
1263baf5664fSJonas Devlieghere                             (const lldb::SBEvent &), event);
1264baf5664fSJonas Devlieghere 
1265baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
1266baf5664fSJonas Devlieghere       Thread::ThreadEventData::GetStackFrameFromEvent(event.get()));
12674f465cffSJim Ingham }
12684f465cffSJim Ingham 
1269b9c1b51eSKate Stone SBThread SBThread::GetThreadFromEvent(const SBEvent &event) {
1270baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(lldb::SBThread, SBThread, GetThreadFromEvent,
1271baf5664fSJonas Devlieghere                             (const lldb::SBEvent &), event);
1272baf5664fSJonas Devlieghere 
1273baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
1274baf5664fSJonas Devlieghere       Thread::ThreadEventData::GetThreadFromEvent(event.get()));
12754f465cffSJim Ingham }
1276f028a1fbSGreg Clayton 
1277b9c1b51eSKate Stone bool SBThread::operator==(const SBThread &rhs) const {
1278baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, operator==,(const lldb::SBThread &),
1279baf5664fSJonas Devlieghere                            rhs);
1280baf5664fSJonas Devlieghere 
1281b9c1b51eSKate Stone   return m_opaque_sp->GetThreadSP().get() ==
1282b9c1b51eSKate Stone          rhs.m_opaque_sp->GetThreadSP().get();
128330fdc8d8SChris Lattner }
128430fdc8d8SChris Lattner 
1285b9c1b51eSKate Stone bool SBThread::operator!=(const SBThread &rhs) const {
1286baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, operator!=,(const lldb::SBThread &),
1287baf5664fSJonas Devlieghere                            rhs);
1288baf5664fSJonas Devlieghere 
1289b9c1b51eSKate Stone   return m_opaque_sp->GetThreadSP().get() !=
1290b9c1b51eSKate Stone          rhs.m_opaque_sp->GetThreadSP().get();
129130fdc8d8SChris Lattner }
1292dde9cff3SCaroline Tice 
1293b9c1b51eSKate Stone bool SBThread::GetStatus(SBStream &status) const {
1294baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetStatus, (lldb::SBStream &),
1295baf5664fSJonas Devlieghere                            status);
1296baf5664fSJonas Devlieghere 
12974f465cffSJim Ingham   Stream &strm = status.ref();
12984f465cffSJim Ingham 
1299b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1300b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1301b2e7d28eSJim Ingham 
1302b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
13036a9767c7SJim Ingham     exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true);
1304b9c1b51eSKate Stone   } else
13054f465cffSJim Ingham     strm.PutCString("No status");
13064f465cffSJim Ingham 
13074f465cffSJim Ingham   return true;
13084f465cffSJim Ingham }
13094f465cffSJim Ingham 
1310b9c1b51eSKate Stone bool SBThread::GetDescription(SBStream &description) const {
1311baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetDescription, (lldb::SBStream &),
1312baf5664fSJonas Devlieghere                            description);
1313baf5664fSJonas Devlieghere 
13146a9767c7SJim Ingham   return GetDescription(description, false);
13156a9767c7SJim Ingham }
13166a9767c7SJim Ingham 
13176a9767c7SJim Ingham bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
1318baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetDescription,
1319baf5664fSJonas Devlieghere                            (lldb::SBStream &, bool), description, stop_format);
1320baf5664fSJonas Devlieghere 
1321da7bc7d0SGreg Clayton   Stream &strm = description.ref();
1322da7bc7d0SGreg Clayton 
1323b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1324b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1325b2e7d28eSJim Ingham 
1326b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1327b9c1b51eSKate Stone     exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm,
13286a9767c7SJim Ingham                                                     LLDB_INVALID_THREAD_ID,
13296a9767c7SJim Ingham                                                     stop_format);
1330b9c1b51eSKate Stone     // strm.Printf("SBThread: tid = 0x%4.4" PRIx64,
1331b9c1b51eSKate Stone     // exe_ctx.GetThreadPtr()->GetID());
1332b9c1b51eSKate Stone   } else
1333da7bc7d0SGreg Clayton     strm.PutCString("No value");
1334ceb6b139SCaroline Tice 
1335ceb6b139SCaroline Tice   return true;
1336ceb6b139SCaroline Tice }
13375dd4916fSJason Molenda 
1338b9c1b51eSKate Stone SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
1339baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBThread, SBThread, GetExtendedBacktraceThread,
1340baf5664fSJonas Devlieghere                      (const char *), type);
1341baf5664fSJonas Devlieghere 
1342bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1343bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
13445dd4916fSJason Molenda   SBThread sb_origin_thread;
13455dd4916fSJason Molenda 
13465dd4916fSJason Molenda   Process::StopLocker stop_locker;
1347b9c1b51eSKate Stone   if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1348b78094abSJim Ingham     if (exe_ctx.HasThreadScope()) {
13497a2f7904SJason Molenda       ThreadSP real_thread(exe_ctx.GetThreadSP());
1350b9c1b51eSKate Stone       if (real_thread) {
13515dd4916fSJason Molenda         ConstString type_const(type);
13527a2f7904SJason Molenda         Process *process = exe_ctx.GetProcessPtr();
1353b9c1b51eSKate Stone         if (process) {
13547a2f7904SJason Molenda           SystemRuntime *runtime = process->GetSystemRuntime();
1355b9c1b51eSKate Stone           if (runtime) {
1356b9c1b51eSKate Stone             ThreadSP new_thread_sp(
1357b9c1b51eSKate Stone                 runtime->GetExtendedBacktraceThread(real_thread, type_const));
1358b9c1b51eSKate Stone             if (new_thread_sp) {
1359b9c1b51eSKate Stone               // Save this in the Process' ExtendedThreadList so a strong
136005097246SAdrian Prantl               // pointer retains the object.
13617a2f7904SJason Molenda               process->GetExtendedThreadList().AddThread(new_thread_sp);
13627a2f7904SJason Molenda               sb_origin_thread.SetThread(new_thread_sp);
1363a6e9130dSJason Molenda             }
1364a6e9130dSJason Molenda           }
13657a2f7904SJason Molenda         }
13665dd4916fSJason Molenda       }
13675dd4916fSJason Molenda     }
13685dd4916fSJason Molenda   }
13695dd4916fSJason Molenda 
1370baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_origin_thread);
13715dd4916fSJason Molenda }
13728ee9cb58SJason Molenda 
1373b9c1b51eSKate Stone uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
1374baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBThread,
1375baf5664fSJonas Devlieghere                              GetExtendedBacktraceOriginatingIndexID);
1376baf5664fSJonas Devlieghere 
13778ee9cb58SJason Molenda   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
13788ee9cb58SJason Molenda   if (thread_sp)
13798ee9cb58SJason Molenda     return thread_sp->GetExtendedBacktraceOriginatingIndexID();
13808ee9cb58SJason Molenda   return LLDB_INVALID_INDEX32;
13818ee9cb58SJason Molenda }
1382b4892cd2SJason Molenda 
1383e60bc53bSKuba Mracek SBValue SBThread::GetCurrentException() {
1384baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBValue, SBThread, GetCurrentException);
1385e60bc53bSKuba Mracek 
1386baf5664fSJonas Devlieghere   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1387baf5664fSJonas Devlieghere   if (!thread_sp)
1388baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(SBValue());
1389baf5664fSJonas Devlieghere 
1390baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(SBValue(thread_sp->GetCurrentException()));
1391e60bc53bSKuba Mracek }
1392e60bc53bSKuba Mracek 
1393e60bc53bSKuba Mracek SBThread SBThread::GetCurrentExceptionBacktrace() {
1394baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBThread, SBThread,
1395baf5664fSJonas Devlieghere                              GetCurrentExceptionBacktrace);
1396e60bc53bSKuba Mracek 
1397baf5664fSJonas Devlieghere   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1398baf5664fSJonas Devlieghere   if (!thread_sp)
1399baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(SBThread());
1400baf5664fSJonas Devlieghere 
1401baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
1402baf5664fSJonas Devlieghere       SBThread(thread_sp->GetCurrentExceptionBacktrace()));
1403c9e1190aSKuba Mracek }
1404e60bc53bSKuba Mracek 
1405b9c1b51eSKate Stone bool SBThread::SafeToCallFunctions() {
1406baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, SafeToCallFunctions);
1407baf5664fSJonas Devlieghere 
1408b4892cd2SJason Molenda   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1409b4892cd2SJason Molenda   if (thread_sp)
1410b4892cd2SJason Molenda     return thread_sp->SafeToCallFunctions();
1411b4892cd2SJason Molenda   return true;
1412b4892cd2SJason Molenda }
14132bdbfd50SJim Ingham 
1414b9c1b51eSKate Stone lldb_private::Thread *SBThread::operator->() {
141526ca5a57SPavel Labath   return get();
14162bdbfd50SJim Ingham }
14172bdbfd50SJim Ingham 
1418b9c1b51eSKate Stone lldb_private::Thread *SBThread::get() {
141926ca5a57SPavel Labath   return m_opaque_sp->GetThreadSP().get();
14202bdbfd50SJim Ingham }
1421ae211eceSMichal Gorny 
1422ae211eceSMichal Gorny namespace lldb_private {
1423ae211eceSMichal Gorny namespace repro {
1424ae211eceSMichal Gorny 
1425ae211eceSMichal Gorny template <>
1426ae211eceSMichal Gorny void RegisterMethods<SBThread>(Registry &R) {
1427ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(const char *, SBThread, GetBroadcasterClassName,
1428ae211eceSMichal Gorny                               ());
1429ae211eceSMichal Gorny   LLDB_REGISTER_CONSTRUCTOR(SBThread, ());
1430ae211eceSMichal Gorny   LLDB_REGISTER_CONSTRUCTOR(SBThread, (const lldb::ThreadSP &));
1431ae211eceSMichal Gorny   LLDB_REGISTER_CONSTRUCTOR(SBThread, (const lldb::SBThread &));
1432ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(const lldb::SBThread &,
1433ae211eceSMichal Gorny                        SBThread, operator=,(const lldb::SBThread &));
1434ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(lldb::SBQueue, SBThread, GetQueue, ());
1435ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, IsValid, ());
1436ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, operator bool, ());
1437ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, Clear, ());
1438ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::StopReason, SBThread, GetStopReason, ());
1439ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(size_t, SBThread, GetStopReasonDataCount, ());
1440ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(uint64_t, SBThread, GetStopReasonDataAtIndex,
1441ae211eceSMichal Gorny                        (uint32_t));
1442ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, GetStopReasonExtendedInfoAsJSON,
1443ae211eceSMichal Gorny                        (lldb::SBStream &));
1444ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBThreadCollection, SBThread,
1445ae211eceSMichal Gorny                        GetStopReasonExtendedBacktraces,
1446ae211eceSMichal Gorny                        (lldb::InstrumentationRuntimeType));
1447ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBValue, SBThread, GetStopReturnValue, ());
1448ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(lldb::tid_t, SBThread, GetThreadID, ());
1449ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(uint32_t, SBThread, GetIndexID, ());
1450ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(const char *, SBThread, GetName, ());
1451ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(const char *, SBThread, GetQueueName, ());
1452ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(lldb::queue_id_t, SBThread, GetQueueID, ());
1453ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, GetInfoItemByPathAsString,
1454ae211eceSMichal Gorny                        (const char *, lldb::SBStream &));
1455ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOver, (lldb::RunMode));
1456ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOver,
1457ae211eceSMichal Gorny                        (lldb::RunMode, lldb::SBError &));
1458ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInto, (lldb::RunMode));
1459ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInto,
1460ae211eceSMichal Gorny                        (const char *, lldb::RunMode));
1461ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(
1462ae211eceSMichal Gorny       void, SBThread, StepInto,
1463ae211eceSMichal Gorny       (const char *, uint32_t, lldb::SBError &, lldb::RunMode));
1464ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOut, ());
1465ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOut, (lldb::SBError &));
1466ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOutOfFrame, (lldb::SBFrame &));
1467ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOutOfFrame,
1468ae211eceSMichal Gorny                        (lldb::SBFrame &, lldb::SBError &));
1469ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInstruction, (bool));
1470ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInstruction,
1471ae211eceSMichal Gorny                        (bool, lldb::SBError &));
1472ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, RunToAddress, (lldb::addr_t));
1473ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, RunToAddress,
1474ae211eceSMichal Gorny                        (lldb::addr_t, lldb::SBError &));
1475ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepOverUntil,
1476ae211eceSMichal Gorny                        (lldb::SBFrame &, lldb::SBFileSpec &, uint32_t));
1477ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
1478ae211eceSMichal Gorny                        (const char *));
1479ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
1480ae211eceSMichal Gorny                        (const char *, bool));
148127a14f19SJim Ingham   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
148227a14f19SJim Ingham                        (const char *, SBStructuredData &, bool));
1483ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, JumpToLine,
1484ae211eceSMichal Gorny                        (lldb::SBFileSpec &, uint32_t));
1485ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, ReturnFromFrame,
1486ae211eceSMichal Gorny                        (lldb::SBFrame &, lldb::SBValue &));
1487ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, UnwindInnermostExpression,
1488ae211eceSMichal Gorny                        ());
1489ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Suspend, ());
1490ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Suspend, (lldb::SBError &));
1491ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Resume, ());
1492ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Resume, (lldb::SBError &));
1493ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, IsSuspended, ());
1494ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, IsStopped, ());
1495ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBProcess, SBThread, GetProcess, ());
1496ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(uint32_t, SBThread, GetNumFrames, ());
1497ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, GetFrameAtIndex, (uint32_t));
1498ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, GetSelectedFrame, ());
1499ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, SetSelectedFrame, (uint32_t));
1500ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(bool, SBThread, EventIsThreadEvent,
1501ae211eceSMichal Gorny                               (const lldb::SBEvent &));
1502ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(lldb::SBFrame, SBThread, GetStackFrameFromEvent,
1503ae211eceSMichal Gorny                               (const lldb::SBEvent &));
1504ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(lldb::SBThread, SBThread, GetThreadFromEvent,
1505ae211eceSMichal Gorny                               (const lldb::SBEvent &));
1506ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool,
1507ae211eceSMichal Gorny                              SBThread, operator==,(const lldb::SBThread &));
1508ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool,
1509ae211eceSMichal Gorny                              SBThread, operator!=,(const lldb::SBThread &));
1510ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetStatus, (lldb::SBStream &));
1511ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetDescription,
1512ae211eceSMichal Gorny                              (lldb::SBStream &));
1513ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetDescription,
1514ae211eceSMichal Gorny                              (lldb::SBStream &, bool));
1515ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBThread, SBThread, GetExtendedBacktraceThread,
1516ae211eceSMichal Gorny                        (const char *));
1517ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(uint32_t, SBThread,
1518ae211eceSMichal Gorny                        GetExtendedBacktraceOriginatingIndexID, ());
1519ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBValue, SBThread, GetCurrentException, ());
1520ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBThread, SBThread, GetCurrentExceptionBacktrace,
1521ae211eceSMichal Gorny                        ());
1522ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, SafeToCallFunctions, ());
15232f025bb8SJonas Devlieghere   LLDB_REGISTER_CHAR_PTR_REDIRECT(size_t, SBThread, GetStopDescription);
1524ae211eceSMichal Gorny }
1525ae211eceSMichal Gorny 
1526ae211eceSMichal Gorny }
1527ae211eceSMichal Gorny }
1528