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:
1750b697561SWalter Erquinigo         case eStopReasonProcessorTrace:
1766c37984eSMichał Górny         case eStopReasonVForkDone:
1774e78f606SGreg Clayton           // There is no data for these stop reasons.
1784e78f606SGreg Clayton           return 0;
1794e78f606SGreg Clayton 
180b9c1b51eSKate Stone         case eStopReasonBreakpoint: {
1814e78f606SGreg Clayton           break_id_t site_id = stop_info_sp->GetValue();
182b9c1b51eSKate Stone           lldb::BreakpointSiteSP bp_site_sp(
183b9c1b51eSKate Stone               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
184b9c1b51eSKate Stone                   site_id));
1854e78f606SGreg Clayton           if (bp_site_sp)
1864e78f606SGreg Clayton             return bp_site_sp->GetNumberOfOwners() * 2;
1874e78f606SGreg Clayton           else
1884e78f606SGreg Clayton             return 0; // Breakpoint must have cleared itself...
189b9c1b51eSKate Stone         } break;
1904e78f606SGreg Clayton 
1914e78f606SGreg Clayton         case eStopReasonWatchpoint:
192290fa41bSJohnny Chen           return 1;
1934e78f606SGreg Clayton 
1944e78f606SGreg Clayton         case eStopReasonSignal:
1954e78f606SGreg Clayton           return 1;
1964e78f606SGreg Clayton 
1974e78f606SGreg Clayton         case eStopReasonException:
1984e78f606SGreg Clayton           return 1;
1996c37984eSMichał Górny 
2006c37984eSMichał Górny         case eStopReasonFork:
2016c37984eSMichał Górny           return 1;
2026c37984eSMichał Górny 
2036c37984eSMichał Górny         case eStopReasonVFork:
2046c37984eSMichał Górny           return 1;
2054e78f606SGreg Clayton         }
2064e78f606SGreg Clayton       }
207c9858e4dSGreg Clayton     }
2087fdf9ef1SGreg Clayton   }
2094e78f606SGreg Clayton   return 0;
2104e78f606SGreg Clayton }
2114e78f606SGreg Clayton 
212b9c1b51eSKate Stone uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
213baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(uint64_t, SBThread, GetStopReasonDataAtIndex, (uint32_t),
214baf5664fSJonas Devlieghere                      idx);
215baf5664fSJonas Devlieghere 
216bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
217bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
2184fc6cb9cSJim Ingham 
219b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
2207fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
221b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
2221ac04c30SGreg Clayton       Thread *thread = exe_ctx.GetThreadPtr();
2231ac04c30SGreg Clayton       StopInfoSP stop_info_sp = thread->GetStopInfo();
224b9c1b51eSKate Stone       if (stop_info_sp) {
2254e78f606SGreg Clayton         StopReason reason = stop_info_sp->GetStopReason();
226b9c1b51eSKate Stone         switch (reason) {
2274e78f606SGreg Clayton         case eStopReasonInvalid:
2284e78f606SGreg Clayton         case eStopReasonNone:
2294e78f606SGreg Clayton         case eStopReasonTrace:
23090ba8115SGreg Clayton         case eStopReasonExec:
2314e78f606SGreg Clayton         case eStopReasonPlanComplete:
232f85defaeSAndrew Kaylor         case eStopReasonThreadExiting:
233afdf842bSKuba Brecka         case eStopReasonInstrumentation:
2340b697561SWalter Erquinigo         case eStopReasonProcessorTrace:
2356c37984eSMichał Górny         case eStopReasonVForkDone:
2364e78f606SGreg Clayton           // There is no data for these stop reasons.
2374e78f606SGreg Clayton           return 0;
2384e78f606SGreg Clayton 
239b9c1b51eSKate Stone         case eStopReasonBreakpoint: {
2404e78f606SGreg Clayton           break_id_t site_id = stop_info_sp->GetValue();
241b9c1b51eSKate Stone           lldb::BreakpointSiteSP bp_site_sp(
242b9c1b51eSKate Stone               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
243b9c1b51eSKate Stone                   site_id));
244b9c1b51eSKate Stone           if (bp_site_sp) {
2454e78f606SGreg Clayton             uint32_t bp_index = idx / 2;
246b9c1b51eSKate Stone             BreakpointLocationSP bp_loc_sp(
247b9c1b51eSKate Stone                 bp_site_sp->GetOwnerAtIndex(bp_index));
248b9c1b51eSKate Stone             if (bp_loc_sp) {
249b9c1b51eSKate Stone               if (idx & 1) {
2504e78f606SGreg Clayton                 // Odd idx, return the breakpoint location ID
2514e78f606SGreg Clayton                 return bp_loc_sp->GetID();
252b9c1b51eSKate Stone               } else {
2534e78f606SGreg Clayton                 // Even idx, return the breakpoint ID
2544e78f606SGreg Clayton                 return bp_loc_sp->GetBreakpoint().GetID();
2554e78f606SGreg Clayton               }
2564e78f606SGreg Clayton             }
2574e78f606SGreg Clayton           }
2584e78f606SGreg Clayton           return LLDB_INVALID_BREAK_ID;
259b9c1b51eSKate Stone         } break;
2604e78f606SGreg Clayton 
2614e78f606SGreg Clayton         case eStopReasonWatchpoint:
262290fa41bSJohnny Chen           return stop_info_sp->GetValue();
2634e78f606SGreg Clayton 
2644e78f606SGreg Clayton         case eStopReasonSignal:
2654e78f606SGreg Clayton           return stop_info_sp->GetValue();
2664e78f606SGreg Clayton 
2674e78f606SGreg Clayton         case eStopReasonException:
2684e78f606SGreg Clayton           return stop_info_sp->GetValue();
2696c37984eSMichał Górny 
2706c37984eSMichał Górny         case eStopReasonFork:
2716c37984eSMichał Górny           return stop_info_sp->GetValue();
2726c37984eSMichał Górny 
2736c37984eSMichał Górny         case eStopReasonVFork:
2746c37984eSMichał Górny           return stop_info_sp->GetValue();
2754e78f606SGreg Clayton         }
2764e78f606SGreg Clayton       }
277c9858e4dSGreg Clayton     }
2787fdf9ef1SGreg Clayton   }
2794e78f606SGreg Clayton   return 0;
2804e78f606SGreg Clayton }
2814e78f606SGreg Clayton 
282b9c1b51eSKate Stone bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) {
283baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, GetStopReasonExtendedInfoAsJSON,
284baf5664fSJonas Devlieghere                      (lldb::SBStream &), stream);
285baf5664fSJonas Devlieghere 
286afdf842bSKuba Brecka   Stream &strm = stream.ref();
287afdf842bSKuba Brecka 
288b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
289b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
290b2e7d28eSJim Ingham 
291afdf842bSKuba Brecka   if (!exe_ctx.HasThreadScope())
292afdf842bSKuba Brecka     return false;
293afdf842bSKuba Brecka 
294afdf842bSKuba Brecka   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
295afdf842bSKuba Brecka   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
296afdf842bSKuba Brecka   if (!info)
297afdf842bSKuba Brecka     return false;
298afdf842bSKuba Brecka 
299afdf842bSKuba Brecka   info->Dump(strm);
300afdf842bSKuba Brecka 
301afdf842bSKuba Brecka   return true;
302afdf842bSKuba Brecka }
303afdf842bSKuba Brecka 
3046a831436SKuba Brecka SBThreadCollection
305b9c1b51eSKate Stone SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
306baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBThreadCollection, SBThread,
307baf5664fSJonas Devlieghere                      GetStopReasonExtendedBacktraces,
308baf5664fSJonas Devlieghere                      (lldb::InstrumentationRuntimeType), type);
309baf5664fSJonas Devlieghere 
3105e3fe22cSJonas Devlieghere   SBThreadCollection threads;
3116a831436SKuba Brecka 
312b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
313b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
314b2e7d28eSJim Ingham 
3156a831436SKuba Brecka   if (!exe_ctx.HasThreadScope())
3165e3fe22cSJonas Devlieghere     return LLDB_RECORD_RESULT(SBThreadCollection());
3176a831436SKuba Brecka 
3186a831436SKuba Brecka   ProcessSP process_sp = exe_ctx.GetProcessSP();
3196a831436SKuba Brecka 
3206a831436SKuba Brecka   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
3216a831436SKuba Brecka   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
3226a831436SKuba Brecka   if (!info)
323baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(threads);
3246a831436SKuba Brecka 
3255e3fe22cSJonas Devlieghere   threads = process_sp->GetInstrumentationRuntime(type)
3265e3fe22cSJonas Devlieghere                 ->GetBacktracesFromExtendedStopInfo(info);
3275e3fe22cSJonas Devlieghere   return LLDB_RECORD_RESULT(threads);
3286a831436SKuba Brecka }
3296a831436SKuba Brecka 
330b9c1b51eSKate Stone size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
331e687aa82SJonas Devlieghere   LLDB_RECORD_CHAR_PTR_METHOD(size_t, SBThread, GetStopDescription,
332e687aa82SJonas Devlieghere                               (char *, size_t), dst, "", dst_len);
333baf5664fSJonas Devlieghere 
334bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
335bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3364fc6cb9cSJim Ingham 
33730fdc8d8SChris Lattner   if (dst)
33830fdc8d8SChris Lattner     *dst = 0;
33920ce8affSFred Riss 
34020ce8affSFred Riss   if (!exe_ctx.HasThreadScope())
34130fdc8d8SChris Lattner     return 0;
34220ce8affSFred Riss 
34320ce8affSFred Riss   Process::StopLocker stop_locker;
34420ce8affSFred Riss   if (!stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
34520ce8affSFred Riss     return 0;
34620ce8affSFred Riss 
34720ce8affSFred Riss   std::string thread_stop_desc = exe_ctx.GetThreadPtr()->GetStopDescription();
34820ce8affSFred Riss   if (thread_stop_desc.empty())
34920ce8affSFred Riss     return 0;
35020ce8affSFred Riss 
35120ce8affSFred Riss   if (dst)
35220ce8affSFred Riss     return ::snprintf(dst, dst_len, "%s", thread_stop_desc.c_str()) + 1;
35320ce8affSFred Riss 
35420ce8affSFred Riss   // NULL dst passed in, return the length needed to contain the
35520ce8affSFred Riss   // description.
35620ce8affSFred Riss   return thread_stop_desc.size() + 1; // Include the NULL byte for size
35730fdc8d8SChris Lattner }
35830fdc8d8SChris Lattner 
359b9c1b51eSKate Stone SBValue SBThread::GetStopReturnValue() {
360baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBValue, SBThread, GetStopReturnValue);
361baf5664fSJonas Devlieghere 
36273ca05a2SJim Ingham   ValueObjectSP return_valobj_sp;
363bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
364bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3654fc6cb9cSJim Ingham 
366b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
3677fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
368b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
3691ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
370b9c1b51eSKate Stone       if (stop_info_sp) {
37173ca05a2SJim Ingham         return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp);
37273ca05a2SJim Ingham       }
373c9858e4dSGreg Clayton     }
3747fdf9ef1SGreg Clayton   }
37573ca05a2SJim Ingham 
376baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(SBValue(return_valobj_sp));
37773ca05a2SJim Ingham }
37873ca05a2SJim Ingham 
379b9c1b51eSKate Stone void SBThread::SetThread(const ThreadSP &lldb_object_sp) {
3807fdf9ef1SGreg Clayton   m_opaque_sp->SetThreadSP(lldb_object_sp);
38130fdc8d8SChris Lattner }
38230fdc8d8SChris Lattner 
383b9c1b51eSKate Stone lldb::tid_t SBThread::GetThreadID() const {
384baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::tid_t, SBThread, GetThreadID);
385baf5664fSJonas Devlieghere 
3867fdf9ef1SGreg Clayton   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
38717a6ad05SGreg Clayton   if (thread_sp)
3881ac04c30SGreg Clayton     return thread_sp->GetID();
3891ac04c30SGreg Clayton   return LLDB_INVALID_THREAD_ID;
39030fdc8d8SChris Lattner }
39130fdc8d8SChris Lattner 
392b9c1b51eSKate Stone uint32_t SBThread::GetIndexID() const {
393baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBThread, GetIndexID);
394baf5664fSJonas Devlieghere 
3957fdf9ef1SGreg Clayton   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
39617a6ad05SGreg Clayton   if (thread_sp)
39717a6ad05SGreg Clayton     return thread_sp->GetIndexID();
39830fdc8d8SChris Lattner   return LLDB_INVALID_INDEX32;
39930fdc8d8SChris Lattner }
4001ac04c30SGreg Clayton 
401b9c1b51eSKate Stone const char *SBThread::GetName() const {
402baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBThread, GetName);
403baf5664fSJonas Devlieghere 
404248a1305SKonrad Kleine   const char *name = nullptr;
405bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
406bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4074fc6cb9cSJim Ingham 
408b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4097fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
410b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4111ac04c30SGreg Clayton       name = exe_ctx.GetThreadPtr()->GetName();
412c9858e4dSGreg Clayton     }
4137fdf9ef1SGreg Clayton   }
414ceb6b139SCaroline Tice 
4154838131bSGreg Clayton   return name;
41630fdc8d8SChris Lattner }
41730fdc8d8SChris Lattner 
418b9c1b51eSKate Stone const char *SBThread::GetQueueName() const {
419baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBThread, GetQueueName);
420baf5664fSJonas Devlieghere 
421248a1305SKonrad Kleine   const char *name = nullptr;
422bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
423bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4244fc6cb9cSJim Ingham 
425b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4267fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
427b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4281ac04c30SGreg Clayton       name = exe_ctx.GetThreadPtr()->GetQueueName();
429c9858e4dSGreg Clayton     }
4307fdf9ef1SGreg Clayton   }
431ceb6b139SCaroline Tice 
4324838131bSGreg Clayton   return name;
43330fdc8d8SChris Lattner }
43430fdc8d8SChris Lattner 
435b9c1b51eSKate Stone lldb::queue_id_t SBThread::GetQueueID() const {
436baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::queue_id_t, SBThread, GetQueueID);
437baf5664fSJonas Devlieghere 
4384fdb5863SJason Molenda   queue_id_t id = LLDB_INVALID_QUEUE_ID;
439bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
440bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4414fdb5863SJason Molenda 
442b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4434fdb5863SJason Molenda     Process::StopLocker stop_locker;
444b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4454fdb5863SJason Molenda       id = exe_ctx.GetThreadPtr()->GetQueueID();
4464fdb5863SJason Molenda     }
4474fdb5863SJason Molenda   }
4484fdb5863SJason Molenda 
4494fdb5863SJason Molenda   return id;
4504fdb5863SJason Molenda }
4514fdb5863SJason Molenda 
452b9c1b51eSKate Stone bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
453baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, GetInfoItemByPathAsString,
454baf5664fSJonas Devlieghere                      (const char *, lldb::SBStream &), path, strm);
455baf5664fSJonas Devlieghere 
456705b1809SJason Molenda   bool success = false;
457bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
458bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
459705b1809SJason Molenda 
460b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
461705b1809SJason Molenda     Process::StopLocker stop_locker;
462b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
463705b1809SJason Molenda       Thread *thread = exe_ctx.GetThreadPtr();
464705b1809SJason Molenda       StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
465b9c1b51eSKate Stone       if (info_root_sp) {
466b9c1b51eSKate Stone         StructuredData::ObjectSP node =
467b9c1b51eSKate Stone             info_root_sp->GetObjectForDotSeparatedPath(path);
468b9c1b51eSKate Stone         if (node) {
4695bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeString) {
4702833321fSZachary Turner             strm.Printf("%s", node->GetAsString()->GetValue().str().c_str());
471705b1809SJason Molenda             success = true;
472705b1809SJason Molenda           }
4735bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeInteger) {
474705b1809SJason Molenda             strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue());
475705b1809SJason Molenda             success = true;
476705b1809SJason Molenda           }
4775bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeFloat) {
478705b1809SJason Molenda             strm.Printf("0x%f", node->GetAsFloat()->GetValue());
479705b1809SJason Molenda             success = true;
480705b1809SJason Molenda           }
4815bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeBoolean) {
482a6682a41SJonas Devlieghere             if (node->GetAsBoolean()->GetValue())
483705b1809SJason Molenda               strm.Printf("true");
484705b1809SJason Molenda             else
485705b1809SJason Molenda               strm.Printf("false");
486705b1809SJason Molenda             success = true;
487705b1809SJason Molenda           }
4885bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeNull) {
489705b1809SJason Molenda             strm.Printf("null");
490705b1809SJason Molenda             success = true;
491705b1809SJason Molenda           }
492705b1809SJason Molenda         }
493705b1809SJason Molenda       }
494705b1809SJason Molenda     }
495705b1809SJason Molenda   }
496705b1809SJason Molenda 
497705b1809SJason Molenda   return success;
498705b1809SJason Molenda }
499705b1809SJason Molenda 
500b9c1b51eSKate Stone SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
501b9c1b51eSKate Stone                                 ThreadPlan *new_plan) {
50264e7ead1SJim Ingham   SBError sb_error;
50364e7ead1SJim Ingham 
50464e7ead1SJim Ingham   Process *process = exe_ctx.GetProcessPtr();
505b9c1b51eSKate Stone   if (!process) {
50664e7ead1SJim Ingham     sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
50764e7ead1SJim Ingham     return sb_error;
50864e7ead1SJim Ingham   }
50964e7ead1SJim Ingham 
51064e7ead1SJim Ingham   Thread *thread = exe_ctx.GetThreadPtr();
511b9c1b51eSKate Stone   if (!thread) {
51264e7ead1SJim Ingham     sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
51364e7ead1SJim Ingham     return sb_error;
51464e7ead1SJim Ingham   }
51564e7ead1SJim Ingham 
516*04cbfa95SQuinn Pham   // User level plans should be Controlling Plans so they can be interrupted,
517*04cbfa95SQuinn Pham   // other plans executed, and then a "continue" will resume the plan.
518248a1305SKonrad Kleine   if (new_plan != nullptr) {
519*04cbfa95SQuinn Pham     new_plan->SetIsControllingPlan(true);
52064e7ead1SJim Ingham     new_plan->SetOkayToDiscard(false);
52164e7ead1SJim Ingham   }
52264e7ead1SJim Ingham 
52364e7ead1SJim Ingham   // Why do we need to set the current thread by ID here???
52464e7ead1SJim Ingham   process->GetThreadList().SetSelectedThreadByID(thread->GetID());
52564e7ead1SJim Ingham 
526dc6224e0SGreg Clayton   if (process->GetTarget().GetDebugger().GetAsyncExecution())
527dc6224e0SGreg Clayton     sb_error.ref() = process->Resume();
528dc6224e0SGreg Clayton   else
529248a1305SKonrad Kleine     sb_error.ref() = process->ResumeSynchronous(nullptr);
53064e7ead1SJim Ingham 
53164e7ead1SJim Ingham   return sb_error;
53264e7ead1SJim Ingham }
53330fdc8d8SChris Lattner 
534b9c1b51eSKate Stone void SBThread::StepOver(lldb::RunMode stop_other_threads) {
535baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOver, (lldb::RunMode),
536baf5664fSJonas Devlieghere                      stop_other_threads);
537baf5664fSJonas Devlieghere 
538859f54b3SAlexander Polyakov   SBError error; // Ignored
539859f54b3SAlexander Polyakov   StepOver(stop_other_threads, error);
540859f54b3SAlexander Polyakov }
541859f54b3SAlexander Polyakov 
542859f54b3SAlexander Polyakov void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
543baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOver, (lldb::RunMode, lldb::SBError &),
544baf5664fSJonas Devlieghere                      stop_other_threads, error);
545baf5664fSJonas Devlieghere 
546bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
547bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
54817a6ad05SGreg Clayton 
549859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
550859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
551859f54b3SAlexander Polyakov     return;
552859f54b3SAlexander Polyakov   }
553859f54b3SAlexander Polyakov 
5541ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
5557ba6e991SJim Ingham   bool abort_other_plans = false;
556b57e4a1bSJason Molenda   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
55730fdc8d8SChris Lattner 
558e103ae92SJonas Devlieghere   Status new_plan_status;
5594d56e9c1SJim Ingham   ThreadPlanSP new_plan_sp;
560b9c1b51eSKate Stone   if (frame_sp) {
561b9c1b51eSKate Stone     if (frame_sp->HasDebugInformation()) {
5624b4b2478SJim Ingham       const LazyBool avoid_no_debug = eLazyBoolCalculate;
56330fdc8d8SChris Lattner       SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
564b9c1b51eSKate Stone       new_plan_sp = thread->QueueThreadPlanForStepOverRange(
565b9c1b51eSKate Stone           abort_other_plans, sc.line_entry, sc, stop_other_threads,
566e103ae92SJonas Devlieghere           new_plan_status, avoid_no_debug);
567b9c1b51eSKate Stone     } else {
568b9c1b51eSKate Stone       new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
569e103ae92SJonas Devlieghere           true, abort_other_plans, stop_other_threads, new_plan_status);
57030fdc8d8SChris Lattner     }
57130fdc8d8SChris Lattner   }
572859f54b3SAlexander Polyakov   error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
57330fdc8d8SChris Lattner }
57430fdc8d8SChris Lattner 
575b9c1b51eSKate Stone void SBThread::StepInto(lldb::RunMode stop_other_threads) {
576baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInto, (lldb::RunMode),
577baf5664fSJonas Devlieghere                      stop_other_threads);
578baf5664fSJonas Devlieghere 
579248a1305SKonrad Kleine   StepInto(nullptr, stop_other_threads);
580c627682eSJim Ingham }
581c627682eSJim Ingham 
582b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name,
583b9c1b51eSKate Stone                         lldb::RunMode stop_other_threads) {
584baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInto, (const char *, lldb::RunMode),
585baf5664fSJonas Devlieghere                      target_name, stop_other_threads);
586baf5664fSJonas Devlieghere 
587859f54b3SAlexander Polyakov   SBError error; // Ignored
588cbf6f9b2SJim Ingham   StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
589cbf6f9b2SJim Ingham }
590cbf6f9b2SJim Ingham 
591b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name, uint32_t end_line,
592b9c1b51eSKate Stone                         SBError &error, lldb::RunMode stop_other_threads) {
593baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInto,
594baf5664fSJonas Devlieghere                      (const char *, uint32_t, lldb::SBError &, lldb::RunMode),
595baf5664fSJonas Devlieghere                      target_name, end_line, error, stop_other_threads);
596baf5664fSJonas Devlieghere 
597ceb6b139SCaroline Tice 
598bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
599bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
60017a6ad05SGreg Clayton 
601859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
602859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
603859f54b3SAlexander Polyakov     return;
604859f54b3SAlexander Polyakov   }
605859f54b3SAlexander Polyakov 
6067ba6e991SJim Ingham   bool abort_other_plans = false;
60730fdc8d8SChris Lattner 
6081ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
609b57e4a1bSJason Molenda   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
6104d56e9c1SJim Ingham   ThreadPlanSP new_plan_sp;
611e103ae92SJonas Devlieghere   Status new_plan_status;
61230fdc8d8SChris Lattner 
613b9c1b51eSKate Stone   if (frame_sp && frame_sp->HasDebugInformation()) {
614cbf6f9b2SJim Ingham     SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
615cbf6f9b2SJim Ingham     AddressRange range;
616cbf6f9b2SJim Ingham     if (end_line == LLDB_INVALID_LINE_NUMBER)
617cbf6f9b2SJim Ingham       range = sc.line_entry.range;
618b9c1b51eSKate Stone     else {
619cbf6f9b2SJim Ingham       if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
620cbf6f9b2SJim Ingham         return;
621cbf6f9b2SJim Ingham     }
622cbf6f9b2SJim Ingham 
623b9c1b51eSKate Stone     const LazyBool step_out_avoids_code_without_debug_info =
624b9c1b51eSKate Stone         eLazyBoolCalculate;
625b9c1b51eSKate Stone     const LazyBool step_in_avoids_code_without_debug_info =
626b9c1b51eSKate Stone         eLazyBoolCalculate;
627b9c1b51eSKate Stone     new_plan_sp = thread->QueueThreadPlanForStepInRange(
628b9c1b51eSKate Stone         abort_other_plans, range, sc, target_name, stop_other_threads,
629e103ae92SJonas Devlieghere         new_plan_status, step_in_avoids_code_without_debug_info,
6304b4b2478SJim Ingham         step_out_avoids_code_without_debug_info);
631b9c1b51eSKate Stone   } else {
632b9c1b51eSKate Stone     new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
633e103ae92SJonas Devlieghere         false, abort_other_plans, stop_other_threads, new_plan_status);
63430fdc8d8SChris Lattner   }
635e103ae92SJonas Devlieghere 
636e103ae92SJonas Devlieghere   if (new_plan_status.Success())
637cbf6f9b2SJim Ingham     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
638e103ae92SJonas Devlieghere   else
639e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
64030fdc8d8SChris Lattner }
64130fdc8d8SChris Lattner 
642b9c1b51eSKate Stone void SBThread::StepOut() {
643baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(void, SBThread, StepOut);
644baf5664fSJonas Devlieghere 
645859f54b3SAlexander Polyakov   SBError error; // Ignored
646859f54b3SAlexander Polyakov   StepOut(error);
647859f54b3SAlexander Polyakov }
648859f54b3SAlexander Polyakov 
649859f54b3SAlexander Polyakov void SBThread::StepOut(SBError &error) {
650baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOut, (lldb::SBError &), error);
651baf5664fSJonas Devlieghere 
652bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
653bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
6544fc6cb9cSJim Ingham 
655859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
656859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
657859f54b3SAlexander Polyakov     return;
658859f54b3SAlexander Polyakov   }
659859f54b3SAlexander Polyakov 
6607ba6e991SJim Ingham   bool abort_other_plans = false;
66194b09246SJim Ingham   bool stop_other_threads = false;
66230fdc8d8SChris Lattner 
6631ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
6641ac04c30SGreg Clayton 
6654b4b2478SJim Ingham   const LazyBool avoid_no_debug = eLazyBoolCalculate;
666e103ae92SJonas Devlieghere   Status new_plan_status;
667b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
668248a1305SKonrad Kleine       abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
669e103ae92SJonas Devlieghere       eVoteNoOpinion, 0, new_plan_status, avoid_no_debug));
670481cef25SGreg Clayton 
671e103ae92SJonas Devlieghere   if (new_plan_status.Success())
672859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
673e103ae92SJonas Devlieghere   else
674e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
675481cef25SGreg Clayton }
676481cef25SGreg Clayton 
677859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
678baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOutOfFrame, (lldb::SBFrame &),
679baf5664fSJonas Devlieghere                      sb_frame);
680baf5664fSJonas Devlieghere 
681859f54b3SAlexander Polyakov   SBError error; // Ignored
682859f54b3SAlexander Polyakov   StepOutOfFrame(sb_frame, error);
683859f54b3SAlexander Polyakov }
684859f54b3SAlexander Polyakov 
685859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
686baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepOutOfFrame,
687baf5664fSJonas Devlieghere                      (lldb::SBFrame &, lldb::SBError &), sb_frame, error);
688baf5664fSJonas Devlieghere 
689481cef25SGreg Clayton 
690bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
691bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
6924fc6cb9cSJim Ingham 
693b9c1b51eSKate Stone   if (!sb_frame.IsValid()) {
694859f54b3SAlexander Polyakov     error.SetErrorString("passed invalid SBFrame object");
695989a7558SJim Ingham     return;
696989a7558SJim Ingham   }
697989a7558SJim Ingham 
698b57e4a1bSJason Molenda   StackFrameSP frame_sp(sb_frame.GetFrameSP());
699481cef25SGreg Clayton 
700859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
701859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
702859f54b3SAlexander Polyakov     return;
703859f54b3SAlexander Polyakov   }
704859f54b3SAlexander Polyakov 
7057ba6e991SJim Ingham   bool abort_other_plans = false;
70694b09246SJim Ingham   bool stop_other_threads = false;
7071ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
708b9c1b51eSKate Stone   if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
709859f54b3SAlexander Polyakov     error.SetErrorString("passed a frame from another thread");
710859f54b3SAlexander Polyakov     return;
711989a7558SJim Ingham   }
712481cef25SGreg Clayton 
713e103ae92SJonas Devlieghere   Status new_plan_status;
714b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
715248a1305SKonrad Kleine       abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
716e103ae92SJonas Devlieghere       eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status));
71730fdc8d8SChris Lattner 
718e103ae92SJonas Devlieghere   if (new_plan_status.Success())
719859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
720e103ae92SJonas Devlieghere   else
721e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
72230fdc8d8SChris Lattner }
72330fdc8d8SChris Lattner 
724b9c1b51eSKate Stone void SBThread::StepInstruction(bool step_over) {
725baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInstruction, (bool), step_over);
726baf5664fSJonas Devlieghere 
727859f54b3SAlexander Polyakov   SBError error; // Ignored
728859f54b3SAlexander Polyakov   StepInstruction(step_over, error);
729859f54b3SAlexander Polyakov }
730859f54b3SAlexander Polyakov 
731859f54b3SAlexander Polyakov void SBThread::StepInstruction(bool step_over, SBError &error) {
732baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, StepInstruction, (bool, lldb::SBError &),
733baf5664fSJonas Devlieghere                      step_over, error);
734baf5664fSJonas Devlieghere 
735bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
736bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
737ceb6b139SCaroline Tice 
738859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
739859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
740859f54b3SAlexander Polyakov     return;
741859f54b3SAlexander Polyakov   }
742859f54b3SAlexander Polyakov 
7431ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
744e103ae92SJonas Devlieghere   Status new_plan_status;
745e103ae92SJonas Devlieghere   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction(
746e103ae92SJonas Devlieghere       step_over, true, true, new_plan_status));
74764e7ead1SJim Ingham 
748e103ae92SJonas Devlieghere   if (new_plan_status.Success())
749859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
750e103ae92SJonas Devlieghere   else
751e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
75230fdc8d8SChris Lattner }
75330fdc8d8SChris Lattner 
754b9c1b51eSKate Stone void SBThread::RunToAddress(lldb::addr_t addr) {
755baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, RunToAddress, (lldb::addr_t), addr);
756baf5664fSJonas Devlieghere 
757859f54b3SAlexander Polyakov   SBError error; // Ignored
758859f54b3SAlexander Polyakov   RunToAddress(addr, error);
759859f54b3SAlexander Polyakov }
760859f54b3SAlexander Polyakov 
761859f54b3SAlexander Polyakov void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
762baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBThread, RunToAddress,
763baf5664fSJonas Devlieghere                      (lldb::addr_t, lldb::SBError &), addr, error);
764baf5664fSJonas Devlieghere 
765bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
766bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
767ceb6b139SCaroline Tice 
768859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
769859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
770859f54b3SAlexander Polyakov     return;
771859f54b3SAlexander Polyakov   }
772859f54b3SAlexander Polyakov 
7737ba6e991SJim Ingham   bool abort_other_plans = false;
77430fdc8d8SChris Lattner   bool stop_other_threads = true;
77530fdc8d8SChris Lattner 
776e72dfb32SGreg Clayton   Address target_addr(addr);
77730fdc8d8SChris Lattner 
7781ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
7791ac04c30SGreg Clayton 
780e103ae92SJonas Devlieghere   Status new_plan_status;
781b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
782e103ae92SJonas Devlieghere       abort_other_plans, target_addr, stop_other_threads, new_plan_status));
78364e7ead1SJim Ingham 
784e103ae92SJonas Devlieghere   if (new_plan_status.Success())
785859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
786e103ae92SJonas Devlieghere   else
787e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
78830fdc8d8SChris Lattner }
78930fdc8d8SChris Lattner 
790b9c1b51eSKate Stone SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
791b9c1b51eSKate Stone                                 lldb::SBFileSpec &sb_file_spec, uint32_t line) {
792baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepOverUntil,
793baf5664fSJonas Devlieghere                      (lldb::SBFrame &, lldb::SBFileSpec &, uint32_t), sb_frame,
794baf5664fSJonas Devlieghere                      sb_file_spec, line);
795baf5664fSJonas Devlieghere 
796481cef25SGreg Clayton   SBError sb_error;
797481cef25SGreg Clayton   char path[PATH_MAX];
798481cef25SGreg Clayton 
799bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
800bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
8014fc6cb9cSJim Ingham 
802b57e4a1bSJason Molenda   StackFrameSP frame_sp(sb_frame.GetFrameSP());
80317a6ad05SGreg Clayton 
804b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
8051ac04c30SGreg Clayton     Target *target = exe_ctx.GetTargetPtr();
8061ac04c30SGreg Clayton     Thread *thread = exe_ctx.GetThreadPtr();
807481cef25SGreg Clayton 
808b9c1b51eSKate Stone     if (line == 0) {
809481cef25SGreg Clayton       sb_error.SetErrorString("invalid line argument");
810baf5664fSJonas Devlieghere       return LLDB_RECORD_RESULT(sb_error);
811481cef25SGreg Clayton     }
812481cef25SGreg Clayton 
813b9c1b51eSKate Stone     if (!frame_sp) {
8141ac04c30SGreg Clayton       frame_sp = thread->GetSelectedFrame();
815481cef25SGreg Clayton       if (!frame_sp)
8161ac04c30SGreg Clayton         frame_sp = thread->GetStackFrameAtIndex(0);
817481cef25SGreg Clayton     }
818481cef25SGreg Clayton 
819481cef25SGreg Clayton     SymbolContext frame_sc;
820b9c1b51eSKate Stone     if (!frame_sp) {
821481cef25SGreg Clayton       sb_error.SetErrorString("no valid frames in thread to step");
822baf5664fSJonas Devlieghere       return LLDB_RECORD_RESULT(sb_error);
823481cef25SGreg Clayton     }
824481cef25SGreg Clayton 
825481cef25SGreg Clayton     // If we have a frame, get its line
826b9c1b51eSKate Stone     frame_sc = frame_sp->GetSymbolContext(
827b9c1b51eSKate Stone         eSymbolContextCompUnit | eSymbolContextFunction |
828b9c1b51eSKate Stone         eSymbolContextLineEntry | eSymbolContextSymbol);
829481cef25SGreg Clayton 
830248a1305SKonrad Kleine     if (frame_sc.comp_unit == nullptr) {
831b9c1b51eSKate Stone       sb_error.SetErrorStringWithFormat(
832b9c1b51eSKate Stone           "frame %u doesn't have debug information", frame_sp->GetFrameIndex());
833baf5664fSJonas Devlieghere       return LLDB_RECORD_RESULT(sb_error);
834481cef25SGreg Clayton     }
835481cef25SGreg Clayton 
836481cef25SGreg Clayton     FileSpec step_file_spec;
837b9c1b51eSKate Stone     if (sb_file_spec.IsValid()) {
838481cef25SGreg Clayton       // The file spec passed in was valid, so use it
839481cef25SGreg Clayton       step_file_spec = sb_file_spec.ref();
840b9c1b51eSKate Stone     } else {
841481cef25SGreg Clayton       if (frame_sc.line_entry.IsValid())
842481cef25SGreg Clayton         step_file_spec = frame_sc.line_entry.file;
843b9c1b51eSKate Stone       else {
844481cef25SGreg Clayton         sb_error.SetErrorString("invalid file argument or no file for frame");
845baf5664fSJonas Devlieghere         return LLDB_RECORD_RESULT(sb_error);
846481cef25SGreg Clayton       }
847481cef25SGreg Clayton     }
848481cef25SGreg Clayton 
8499b70ddb3SJim Ingham     // Grab the current function, then we will make sure the "until" address is
8509b70ddb3SJim Ingham     // within the function.  We discard addresses that are out of the current
851b9c1b51eSKate Stone     // function, and then if there are no addresses remaining, give an
85205097246SAdrian Prantl     // appropriate error message.
8539b70ddb3SJim Ingham 
8549b70ddb3SJim Ingham     bool all_in_function = true;
8559b70ddb3SJim Ingham     AddressRange fun_range = frame_sc.function->GetAddressRange();
8569b70ddb3SJim Ingham 
857481cef25SGreg Clayton     std::vector<addr_t> step_over_until_addrs;
8587ba6e991SJim Ingham     const bool abort_other_plans = false;
859c02e3344SJim Ingham     const bool stop_other_threads = false;
8603e2ed744SMed Ismail Bennani     // TODO: Handle SourceLocationSpec column information
8613e2ed744SMed Ismail Bennani     SourceLocationSpec location_spec(
8623e2ed744SMed Ismail Bennani         step_file_spec, line, /*column=*/llvm::None, /*check_inlines=*/true,
8633e2ed744SMed Ismail Bennani         /*exact_match=*/false);
864481cef25SGreg Clayton 
865481cef25SGreg Clayton     SymbolContextList sc_list;
8663e2ed744SMed Ismail Bennani     frame_sc.comp_unit->ResolveSymbolContext(location_spec,
867c671639aSKonrad Kleine                                              eSymbolContextLineEntry, sc_list);
868c671639aSKonrad Kleine     const uint32_t num_matches = sc_list.GetSize();
869b9c1b51eSKate Stone     if (num_matches > 0) {
870481cef25SGreg Clayton       SymbolContext sc;
871b9c1b51eSKate Stone       for (uint32_t i = 0; i < num_matches; ++i) {
872b9c1b51eSKate Stone         if (sc_list.GetContextAtIndex(i, sc)) {
873b9c1b51eSKate Stone           addr_t step_addr =
874b9c1b51eSKate Stone               sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
875b9c1b51eSKate Stone           if (step_addr != LLDB_INVALID_ADDRESS) {
8769b70ddb3SJim Ingham             if (fun_range.ContainsLoadAddress(step_addr, target))
877481cef25SGreg Clayton               step_over_until_addrs.push_back(step_addr);
8789b70ddb3SJim Ingham             else
8799b70ddb3SJim Ingham               all_in_function = false;
880481cef25SGreg Clayton           }
881481cef25SGreg Clayton         }
882481cef25SGreg Clayton       }
883481cef25SGreg Clayton     }
884481cef25SGreg Clayton 
885b9c1b51eSKate Stone     if (step_over_until_addrs.empty()) {
886b9c1b51eSKate Stone       if (all_in_function) {
887481cef25SGreg Clayton         step_file_spec.GetPath(path, sizeof(path));
888b9c1b51eSKate Stone         sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path,
889b9c1b51eSKate Stone                                           line);
890b9c1b51eSKate Stone       } else
89186edbf41SGreg Clayton         sb_error.SetErrorString("step until target not in current function");
892b9c1b51eSKate Stone     } else {
893e103ae92SJonas Devlieghere       Status new_plan_status;
894b9c1b51eSKate Stone       ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil(
895b9c1b51eSKate Stone           abort_other_plans, &step_over_until_addrs[0],
896b9c1b51eSKate Stone           step_over_until_addrs.size(), stop_other_threads,
897e103ae92SJonas Devlieghere           frame_sp->GetFrameIndex(), new_plan_status));
898481cef25SGreg Clayton 
899e103ae92SJonas Devlieghere       if (new_plan_status.Success())
9004d56e9c1SJim Ingham         sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
901e103ae92SJonas Devlieghere       else
902e103ae92SJonas Devlieghere         sb_error.SetErrorString(new_plan_status.AsCString());
903481cef25SGreg Clayton     }
904b9c1b51eSKate Stone   } else {
905481cef25SGreg Clayton     sb_error.SetErrorString("this SBThread object is invalid");
906481cef25SGreg Clayton   }
907baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
908481cef25SGreg Clayton }
909481cef25SGreg Clayton 
910b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) {
911baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
912baf5664fSJonas Devlieghere                      (const char *), script_class_name);
913baf5664fSJonas Devlieghere 
914baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
915baf5664fSJonas Devlieghere       StepUsingScriptedThreadPlan(script_class_name, true));
916c915a7d2SJim Ingham }
917c915a7d2SJim Ingham 
918b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
919b9c1b51eSKate Stone                                             bool resume_immediately) {
920baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
921baf5664fSJonas Devlieghere                      (const char *, bool), script_class_name,
922baf5664fSJonas Devlieghere                      resume_immediately);
923baf5664fSJonas Devlieghere 
92427a14f19SJim Ingham   lldb::SBStructuredData no_data;
9253da7dcf3SJonas Devlieghere   return LLDB_RECORD_RESULT(StepUsingScriptedThreadPlan(
9263da7dcf3SJonas Devlieghere       script_class_name, no_data, resume_immediately));
92727a14f19SJim Ingham }
92827a14f19SJim Ingham 
92927a14f19SJim Ingham SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
93027a14f19SJim Ingham                                               SBStructuredData &args_data,
93127a14f19SJim Ingham                                               bool resume_immediately) {
93227a14f19SJim Ingham   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
93327a14f19SJim Ingham                      (const char *, lldb::SBStructuredData &, bool),
9343da7dcf3SJonas Devlieghere                      script_class_name, args_data, resume_immediately);
93527a14f19SJim Ingham 
936e103ae92SJonas Devlieghere   SBError error;
9372bdbfd50SJim Ingham 
938bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
939bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
9402bdbfd50SJim Ingham 
941b9c1b51eSKate Stone   if (!exe_ctx.HasThreadScope()) {
942e103ae92SJonas Devlieghere     error.SetErrorString("this SBThread object is invalid");
943baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(error);
9442bdbfd50SJim Ingham   }
9452bdbfd50SJim Ingham 
9462bdbfd50SJim Ingham   Thread *thread = exe_ctx.GetThreadPtr();
947e103ae92SJonas Devlieghere   Status new_plan_status;
94827a14f19SJim Ingham   StructuredData::ObjectSP obj_sp = args_data.m_impl_up->GetObjectSP();
94927a14f19SJim Ingham 
950e103ae92SJonas Devlieghere   ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted(
95127a14f19SJim Ingham       false, script_class_name, obj_sp, false, new_plan_status);
9522bdbfd50SJim Ingham 
953e103ae92SJonas Devlieghere   if (new_plan_status.Fail()) {
954e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
955baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(error);
956c915a7d2SJim Ingham   }
957c915a7d2SJim Ingham 
958e103ae92SJonas Devlieghere   if (!resume_immediately)
959baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(error);
960c915a7d2SJim Ingham 
961e103ae92SJonas Devlieghere   if (new_plan_status.Success())
962e103ae92SJonas Devlieghere     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
963e103ae92SJonas Devlieghere   else
964e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
9652bdbfd50SJim Ingham 
966baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(error);
9672bdbfd50SJim Ingham }
9682bdbfd50SJim Ingham 
969b9c1b51eSKate Stone SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
970baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, JumpToLine,
971baf5664fSJonas Devlieghere                      (lldb::SBFileSpec &, uint32_t), file_spec, line);
972baf5664fSJonas Devlieghere 
973f86248d9SRichard Mitton   SBError sb_error;
974f86248d9SRichard Mitton 
975bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
976bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
977f86248d9SRichard Mitton 
978b9c1b51eSKate Stone   if (!exe_ctx.HasThreadScope()) {
979f86248d9SRichard Mitton     sb_error.SetErrorString("this SBThread object is invalid");
980baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(sb_error);
981f86248d9SRichard Mitton   }
982f86248d9SRichard Mitton 
983f86248d9SRichard Mitton   Thread *thread = exe_ctx.GetThreadPtr();
984f86248d9SRichard Mitton 
98528e4942bSPavel Labath   Status err = thread->JumpToLine(file_spec.ref(), line, true);
986f86248d9SRichard Mitton   sb_error.SetError(err);
987baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
988f86248d9SRichard Mitton }
989f86248d9SRichard Mitton 
990b9c1b51eSKate Stone SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
991baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBError, SBThread, ReturnFromFrame,
992baf5664fSJonas Devlieghere                      (lldb::SBFrame &, lldb::SBValue &), frame, return_value);
993baf5664fSJonas Devlieghere 
9944413758cSJim Ingham   SBError sb_error;
9954413758cSJim Ingham 
996bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
997bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
9984413758cSJim Ingham 
999b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
10004413758cSJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
1001b9c1b51eSKate Stone     sb_error.SetError(
1002b9c1b51eSKate Stone         thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
10034413758cSJim Ingham   }
10044413758cSJim Ingham 
1005baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
10064413758cSJim Ingham }
10074413758cSJim Ingham 
1008b9c1b51eSKate Stone SBError SBThread::UnwindInnermostExpression() {
1009baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBError, SBThread,
1010baf5664fSJonas Devlieghere                              UnwindInnermostExpression);
1011baf5664fSJonas Devlieghere 
10124ac8e93aSJim Ingham   SBError sb_error;
10134ac8e93aSJim Ingham 
10144ac8e93aSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
10154ac8e93aSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
10164ac8e93aSJim Ingham 
1017b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
10184ac8e93aSJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
10194ac8e93aSJim Ingham     sb_error.SetError(thread->UnwindInnermostExpression());
10204ac8e93aSJim Ingham     if (sb_error.Success())
10214ac8e93aSJim Ingham       thread->SetSelectedFrameByIndex(0, false);
10224ac8e93aSJim Ingham   }
10234ac8e93aSJim Ingham 
1024baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_error);
10254ac8e93aSJim Ingham }
1026481cef25SGreg Clayton 
1027b9c1b51eSKate Stone bool SBThread::Suspend() {
1028baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, Suspend);
1029baf5664fSJonas Devlieghere 
1030859f54b3SAlexander Polyakov   SBError error; // Ignored
1031859f54b3SAlexander Polyakov   return Suspend(error);
1032859f54b3SAlexander Polyakov }
1033859f54b3SAlexander Polyakov 
1034859f54b3SAlexander Polyakov bool SBThread::Suspend(SBError &error) {
1035baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, Suspend, (lldb::SBError &), error);
1036baf5664fSJonas Devlieghere 
1037b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1038b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1039b2e7d28eSJim Ingham 
1040c9858e4dSGreg Clayton   bool result = false;
1041b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1042c9858e4dSGreg Clayton     Process::StopLocker stop_locker;
1043b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
10441ac04c30SGreg Clayton       exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
1045c9858e4dSGreg Clayton       result = true;
1046b9c1b51eSKate Stone     } else {
1047859f54b3SAlexander Polyakov       error.SetErrorString("process is running");
1048c9858e4dSGreg Clayton     }
1049859f54b3SAlexander Polyakov   } else
1050859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
1051c9858e4dSGreg Clayton   return result;
1052722a0cdcSGreg Clayton }
1053722a0cdcSGreg Clayton 
1054b9c1b51eSKate Stone bool SBThread::Resume() {
1055baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, Resume);
1056baf5664fSJonas Devlieghere 
1057859f54b3SAlexander Polyakov   SBError error; // Ignored
1058859f54b3SAlexander Polyakov   return Resume(error);
1059859f54b3SAlexander Polyakov }
1060859f54b3SAlexander Polyakov 
1061859f54b3SAlexander Polyakov bool SBThread::Resume(SBError &error) {
1062baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBThread, Resume, (lldb::SBError &), error);
1063baf5664fSJonas Devlieghere 
1064b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1065b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1066b2e7d28eSJim Ingham 
1067c9858e4dSGreg Clayton   bool result = false;
1068b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1069c9858e4dSGreg Clayton     Process::StopLocker stop_locker;
1070b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
10716c9ed91cSJim Ingham       const bool override_suspend = true;
10726c9ed91cSJim Ingham       exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
1073c9858e4dSGreg Clayton       result = true;
1074b9c1b51eSKate Stone     } else {
1075859f54b3SAlexander Polyakov       error.SetErrorString("process is running");
1076c9858e4dSGreg Clayton     }
1077859f54b3SAlexander Polyakov   } else
1078859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
1079c9858e4dSGreg Clayton   return result;
1080722a0cdcSGreg Clayton }
1081722a0cdcSGreg Clayton 
1082b9c1b51eSKate Stone bool SBThread::IsSuspended() {
1083baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, IsSuspended);
1084baf5664fSJonas Devlieghere 
1085b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1086b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1087b2e7d28eSJim Ingham 
10881ac04c30SGreg Clayton   if (exe_ctx.HasThreadScope())
10891ac04c30SGreg Clayton     return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
1090722a0cdcSGreg Clayton   return false;
1091722a0cdcSGreg Clayton }
1092722a0cdcSGreg Clayton 
1093b9c1b51eSKate Stone bool SBThread::IsStopped() {
1094baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, IsStopped);
1095baf5664fSJonas Devlieghere 
1096b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1097b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1098b2e7d28eSJim Ingham 
1099a75418dbSAndrew Kaylor   if (exe_ctx.HasThreadScope())
1100a75418dbSAndrew Kaylor     return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1101a75418dbSAndrew Kaylor   return false;
1102a75418dbSAndrew Kaylor }
1103a75418dbSAndrew Kaylor 
1104b9c1b51eSKate Stone SBProcess SBThread::GetProcess() {
1105baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBProcess, SBThread, GetProcess);
1106baf5664fSJonas Devlieghere 
1107b9556accSGreg Clayton   SBProcess sb_process;
1108b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1109b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1110b2e7d28eSJim Ingham 
1111b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1112b9c1b51eSKate Stone     // Have to go up to the target so we can get a shared pointer to our
1113b9c1b51eSKate Stone     // process...
11141ac04c30SGreg Clayton     sb_process.SetSP(exe_ctx.GetProcessSP());
111530fdc8d8SChris Lattner   }
1116ceb6b139SCaroline Tice 
1117baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_process);
111830fdc8d8SChris Lattner }
111930fdc8d8SChris Lattner 
1120b9c1b51eSKate Stone uint32_t SBThread::GetNumFrames() {
1121baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBThread, GetNumFrames);
1122baf5664fSJonas Devlieghere 
1123ceb6b139SCaroline Tice   uint32_t num_frames = 0;
1124bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1125bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11264fc6cb9cSJim Ingham 
1127b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11287fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1129b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11301ac04c30SGreg Clayton       num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1131c9858e4dSGreg Clayton     }
11327fdf9ef1SGreg Clayton   }
1133ceb6b139SCaroline Tice 
1134ceb6b139SCaroline Tice   return num_frames;
113530fdc8d8SChris Lattner }
113630fdc8d8SChris Lattner 
1137b9c1b51eSKate Stone SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
1138baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBFrame, SBThread, GetFrameAtIndex, (uint32_t), idx);
1139baf5664fSJonas Devlieghere 
114030fdc8d8SChris Lattner   SBFrame sb_frame;
1141b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1142bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1143bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11444fc6cb9cSJim Ingham 
1145b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11467fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1147b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11481ac04c30SGreg Clayton       frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
1149b9556accSGreg Clayton       sb_frame.SetFrameSP(frame_sp);
1150c9858e4dSGreg Clayton     }
11517fdf9ef1SGreg Clayton   }
1152ceb6b139SCaroline Tice 
1153baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_frame);
115430fdc8d8SChris Lattner }
115530fdc8d8SChris Lattner 
1156b9c1b51eSKate Stone lldb::SBFrame SBThread::GetSelectedFrame() {
1157baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBFrame, SBThread, GetSelectedFrame);
1158baf5664fSJonas Devlieghere 
1159f028a1fbSGreg Clayton   SBFrame sb_frame;
1160b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1161bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1162bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11634fc6cb9cSJim Ingham 
1164b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11657fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1166b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11671ac04c30SGreg Clayton       frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame();
1168b9556accSGreg Clayton       sb_frame.SetFrameSP(frame_sp);
1169c9858e4dSGreg Clayton     }
11707fdf9ef1SGreg Clayton   }
1171f028a1fbSGreg Clayton 
1172baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_frame);
1173f028a1fbSGreg Clayton }
1174f028a1fbSGreg Clayton 
1175b9c1b51eSKate Stone lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
1176baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBFrame, SBThread, SetSelectedFrame, (uint32_t),
1177baf5664fSJonas Devlieghere                      idx);
1178baf5664fSJonas Devlieghere 
1179f028a1fbSGreg Clayton   SBFrame sb_frame;
1180b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1181bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1182bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11834fc6cb9cSJim Ingham 
1184b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11857fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1186b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11871ac04c30SGreg Clayton       Thread *thread = exe_ctx.GetThreadPtr();
11881ac04c30SGreg Clayton       frame_sp = thread->GetStackFrameAtIndex(idx);
1189b9c1b51eSKate Stone       if (frame_sp) {
11901ac04c30SGreg Clayton         thread->SetSelectedFrame(frame_sp.get());
1191b9556accSGreg Clayton         sb_frame.SetFrameSP(frame_sp);
1192f028a1fbSGreg Clayton       }
1193c9858e4dSGreg Clayton     }
11947fdf9ef1SGreg Clayton   }
1195f028a1fbSGreg Clayton 
1196baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_frame);
1197f028a1fbSGreg Clayton }
1198f028a1fbSGreg Clayton 
1199b9c1b51eSKate Stone bool SBThread::EventIsThreadEvent(const SBEvent &event) {
1200baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(bool, SBThread, EventIsThreadEvent,
1201baf5664fSJonas Devlieghere                             (const lldb::SBEvent &), event);
1202baf5664fSJonas Devlieghere 
1203248a1305SKonrad Kleine   return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != nullptr;
12044f465cffSJim Ingham }
12054f465cffSJim Ingham 
1206b9c1b51eSKate Stone SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) {
1207baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(lldb::SBFrame, SBThread, GetStackFrameFromEvent,
1208baf5664fSJonas Devlieghere                             (const lldb::SBEvent &), event);
1209baf5664fSJonas Devlieghere 
1210baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
1211baf5664fSJonas Devlieghere       Thread::ThreadEventData::GetStackFrameFromEvent(event.get()));
12124f465cffSJim Ingham }
12134f465cffSJim Ingham 
1214b9c1b51eSKate Stone SBThread SBThread::GetThreadFromEvent(const SBEvent &event) {
1215baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(lldb::SBThread, SBThread, GetThreadFromEvent,
1216baf5664fSJonas Devlieghere                             (const lldb::SBEvent &), event);
1217baf5664fSJonas Devlieghere 
1218baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
1219baf5664fSJonas Devlieghere       Thread::ThreadEventData::GetThreadFromEvent(event.get()));
12204f465cffSJim Ingham }
1221f028a1fbSGreg Clayton 
1222b9c1b51eSKate Stone bool SBThread::operator==(const SBThread &rhs) const {
1223baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, operator==,(const lldb::SBThread &),
1224baf5664fSJonas Devlieghere                            rhs);
1225baf5664fSJonas Devlieghere 
1226b9c1b51eSKate Stone   return m_opaque_sp->GetThreadSP().get() ==
1227b9c1b51eSKate Stone          rhs.m_opaque_sp->GetThreadSP().get();
122830fdc8d8SChris Lattner }
122930fdc8d8SChris Lattner 
1230b9c1b51eSKate Stone bool SBThread::operator!=(const SBThread &rhs) const {
1231baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, operator!=,(const lldb::SBThread &),
1232baf5664fSJonas Devlieghere                            rhs);
1233baf5664fSJonas Devlieghere 
1234b9c1b51eSKate Stone   return m_opaque_sp->GetThreadSP().get() !=
1235b9c1b51eSKate Stone          rhs.m_opaque_sp->GetThreadSP().get();
123630fdc8d8SChris Lattner }
1237dde9cff3SCaroline Tice 
1238b9c1b51eSKate Stone bool SBThread::GetStatus(SBStream &status) const {
1239baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetStatus, (lldb::SBStream &),
1240baf5664fSJonas Devlieghere                            status);
1241baf5664fSJonas Devlieghere 
12424f465cffSJim Ingham   Stream &strm = status.ref();
12434f465cffSJim Ingham 
1244b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1245b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1246b2e7d28eSJim Ingham 
1247b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
12486a9767c7SJim Ingham     exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true);
1249b9c1b51eSKate Stone   } else
12504f465cffSJim Ingham     strm.PutCString("No status");
12514f465cffSJim Ingham 
12524f465cffSJim Ingham   return true;
12534f465cffSJim Ingham }
12544f465cffSJim Ingham 
1255b9c1b51eSKate Stone bool SBThread::GetDescription(SBStream &description) const {
1256baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetDescription, (lldb::SBStream &),
1257baf5664fSJonas Devlieghere                            description);
1258baf5664fSJonas Devlieghere 
12596a9767c7SJim Ingham   return GetDescription(description, false);
12606a9767c7SJim Ingham }
12616a9767c7SJim Ingham 
12626a9767c7SJim Ingham bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
1263baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetDescription,
1264baf5664fSJonas Devlieghere                            (lldb::SBStream &, bool), description, stop_format);
1265baf5664fSJonas Devlieghere 
1266da7bc7d0SGreg Clayton   Stream &strm = description.ref();
1267da7bc7d0SGreg Clayton 
1268b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1269b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1270b2e7d28eSJim Ingham 
1271b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1272b9c1b51eSKate Stone     exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm,
12736a9767c7SJim Ingham                                                     LLDB_INVALID_THREAD_ID,
12746a9767c7SJim Ingham                                                     stop_format);
1275b9c1b51eSKate Stone     // strm.Printf("SBThread: tid = 0x%4.4" PRIx64,
1276b9c1b51eSKate Stone     // exe_ctx.GetThreadPtr()->GetID());
1277b9c1b51eSKate Stone   } else
1278da7bc7d0SGreg Clayton     strm.PutCString("No value");
1279ceb6b139SCaroline Tice 
1280ceb6b139SCaroline Tice   return true;
1281ceb6b139SCaroline Tice }
12825dd4916fSJason Molenda 
1283b9c1b51eSKate Stone SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
1284baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBThread, SBThread, GetExtendedBacktraceThread,
1285baf5664fSJonas Devlieghere                      (const char *), type);
1286baf5664fSJonas Devlieghere 
1287bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1288bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12895dd4916fSJason Molenda   SBThread sb_origin_thread;
12905dd4916fSJason Molenda 
12915dd4916fSJason Molenda   Process::StopLocker stop_locker;
1292b9c1b51eSKate Stone   if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1293b78094abSJim Ingham     if (exe_ctx.HasThreadScope()) {
12947a2f7904SJason Molenda       ThreadSP real_thread(exe_ctx.GetThreadSP());
1295b9c1b51eSKate Stone       if (real_thread) {
12965dd4916fSJason Molenda         ConstString type_const(type);
12977a2f7904SJason Molenda         Process *process = exe_ctx.GetProcessPtr();
1298b9c1b51eSKate Stone         if (process) {
12997a2f7904SJason Molenda           SystemRuntime *runtime = process->GetSystemRuntime();
1300b9c1b51eSKate Stone           if (runtime) {
1301b9c1b51eSKate Stone             ThreadSP new_thread_sp(
1302b9c1b51eSKate Stone                 runtime->GetExtendedBacktraceThread(real_thread, type_const));
1303b9c1b51eSKate Stone             if (new_thread_sp) {
1304b9c1b51eSKate Stone               // Save this in the Process' ExtendedThreadList so a strong
130505097246SAdrian Prantl               // pointer retains the object.
13067a2f7904SJason Molenda               process->GetExtendedThreadList().AddThread(new_thread_sp);
13077a2f7904SJason Molenda               sb_origin_thread.SetThread(new_thread_sp);
1308a6e9130dSJason Molenda             }
1309a6e9130dSJason Molenda           }
13107a2f7904SJason Molenda         }
13115dd4916fSJason Molenda       }
13125dd4916fSJason Molenda     }
13135dd4916fSJason Molenda   }
13145dd4916fSJason Molenda 
1315baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_origin_thread);
13165dd4916fSJason Molenda }
13178ee9cb58SJason Molenda 
1318b9c1b51eSKate Stone uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
1319baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBThread,
1320baf5664fSJonas Devlieghere                              GetExtendedBacktraceOriginatingIndexID);
1321baf5664fSJonas Devlieghere 
13228ee9cb58SJason Molenda   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
13238ee9cb58SJason Molenda   if (thread_sp)
13248ee9cb58SJason Molenda     return thread_sp->GetExtendedBacktraceOriginatingIndexID();
13258ee9cb58SJason Molenda   return LLDB_INVALID_INDEX32;
13268ee9cb58SJason Molenda }
1327b4892cd2SJason Molenda 
1328e60bc53bSKuba Mracek SBValue SBThread::GetCurrentException() {
1329baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBValue, SBThread, GetCurrentException);
1330e60bc53bSKuba Mracek 
1331baf5664fSJonas Devlieghere   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1332baf5664fSJonas Devlieghere   if (!thread_sp)
1333baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(SBValue());
1334baf5664fSJonas Devlieghere 
1335baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(SBValue(thread_sp->GetCurrentException()));
1336e60bc53bSKuba Mracek }
1337e60bc53bSKuba Mracek 
1338e60bc53bSKuba Mracek SBThread SBThread::GetCurrentExceptionBacktrace() {
1339baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBThread, SBThread,
1340baf5664fSJonas Devlieghere                              GetCurrentExceptionBacktrace);
1341e60bc53bSKuba Mracek 
1342baf5664fSJonas Devlieghere   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1343baf5664fSJonas Devlieghere   if (!thread_sp)
1344baf5664fSJonas Devlieghere     return LLDB_RECORD_RESULT(SBThread());
1345baf5664fSJonas Devlieghere 
1346baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(
1347baf5664fSJonas Devlieghere       SBThread(thread_sp->GetCurrentExceptionBacktrace()));
1348c9e1190aSKuba Mracek }
1349e60bc53bSKuba Mracek 
1350b9c1b51eSKate Stone bool SBThread::SafeToCallFunctions() {
1351baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, SafeToCallFunctions);
1352baf5664fSJonas Devlieghere 
1353b4892cd2SJason Molenda   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1354b4892cd2SJason Molenda   if (thread_sp)
1355b4892cd2SJason Molenda     return thread_sp->SafeToCallFunctions();
1356b4892cd2SJason Molenda   return true;
1357b4892cd2SJason Molenda }
13582bdbfd50SJim Ingham 
1359b9c1b51eSKate Stone lldb_private::Thread *SBThread::operator->() {
136026ca5a57SPavel Labath   return get();
13612bdbfd50SJim Ingham }
13622bdbfd50SJim Ingham 
1363b9c1b51eSKate Stone lldb_private::Thread *SBThread::get() {
136426ca5a57SPavel Labath   return m_opaque_sp->GetThreadSP().get();
13652bdbfd50SJim Ingham }
1366ae211eceSMichal Gorny 
1367ae211eceSMichal Gorny namespace lldb_private {
1368ae211eceSMichal Gorny namespace repro {
1369ae211eceSMichal Gorny 
1370ae211eceSMichal Gorny template <>
1371ae211eceSMichal Gorny void RegisterMethods<SBThread>(Registry &R) {
1372ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(const char *, SBThread, GetBroadcasterClassName,
1373ae211eceSMichal Gorny                               ());
1374ae211eceSMichal Gorny   LLDB_REGISTER_CONSTRUCTOR(SBThread, ());
1375ae211eceSMichal Gorny   LLDB_REGISTER_CONSTRUCTOR(SBThread, (const lldb::ThreadSP &));
1376ae211eceSMichal Gorny   LLDB_REGISTER_CONSTRUCTOR(SBThread, (const lldb::SBThread &));
1377ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(const lldb::SBThread &,
1378ae211eceSMichal Gorny                        SBThread, operator=,(const lldb::SBThread &));
1379ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(lldb::SBQueue, SBThread, GetQueue, ());
1380ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, IsValid, ());
1381ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, operator bool, ());
1382ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, Clear, ());
1383ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::StopReason, SBThread, GetStopReason, ());
1384ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(size_t, SBThread, GetStopReasonDataCount, ());
1385ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(uint64_t, SBThread, GetStopReasonDataAtIndex,
1386ae211eceSMichal Gorny                        (uint32_t));
1387ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, GetStopReasonExtendedInfoAsJSON,
1388ae211eceSMichal Gorny                        (lldb::SBStream &));
1389ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBThreadCollection, SBThread,
1390ae211eceSMichal Gorny                        GetStopReasonExtendedBacktraces,
1391ae211eceSMichal Gorny                        (lldb::InstrumentationRuntimeType));
1392ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBValue, SBThread, GetStopReturnValue, ());
1393ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(lldb::tid_t, SBThread, GetThreadID, ());
1394ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(uint32_t, SBThread, GetIndexID, ());
1395ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(const char *, SBThread, GetName, ());
1396ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(const char *, SBThread, GetQueueName, ());
1397ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(lldb::queue_id_t, SBThread, GetQueueID, ());
1398ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, GetInfoItemByPathAsString,
1399ae211eceSMichal Gorny                        (const char *, lldb::SBStream &));
1400ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOver, (lldb::RunMode));
1401ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOver,
1402ae211eceSMichal Gorny                        (lldb::RunMode, lldb::SBError &));
1403ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInto, (lldb::RunMode));
1404ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInto,
1405ae211eceSMichal Gorny                        (const char *, lldb::RunMode));
1406ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(
1407ae211eceSMichal Gorny       void, SBThread, StepInto,
1408ae211eceSMichal Gorny       (const char *, uint32_t, lldb::SBError &, lldb::RunMode));
1409ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOut, ());
1410ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOut, (lldb::SBError &));
1411ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOutOfFrame, (lldb::SBFrame &));
1412ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepOutOfFrame,
1413ae211eceSMichal Gorny                        (lldb::SBFrame &, lldb::SBError &));
1414ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInstruction, (bool));
1415ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, StepInstruction,
1416ae211eceSMichal Gorny                        (bool, lldb::SBError &));
1417ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, RunToAddress, (lldb::addr_t));
1418ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(void, SBThread, RunToAddress,
1419ae211eceSMichal Gorny                        (lldb::addr_t, lldb::SBError &));
1420ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepOverUntil,
1421ae211eceSMichal Gorny                        (lldb::SBFrame &, lldb::SBFileSpec &, uint32_t));
1422ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
1423ae211eceSMichal Gorny                        (const char *));
1424ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
1425ae211eceSMichal Gorny                        (const char *, bool));
142627a14f19SJim Ingham   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
142727a14f19SJim Ingham                        (const char *, SBStructuredData &, bool));
1428ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, JumpToLine,
1429ae211eceSMichal Gorny                        (lldb::SBFileSpec &, uint32_t));
1430ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, ReturnFromFrame,
1431ae211eceSMichal Gorny                        (lldb::SBFrame &, lldb::SBValue &));
1432ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, UnwindInnermostExpression,
1433ae211eceSMichal Gorny                        ());
1434ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Suspend, ());
1435ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Suspend, (lldb::SBError &));
1436ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Resume, ());
1437ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, Resume, (lldb::SBError &));
1438ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, IsSuspended, ());
1439ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, IsStopped, ());
1440ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBProcess, SBThread, GetProcess, ());
1441ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(uint32_t, SBThread, GetNumFrames, ());
1442ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, GetFrameAtIndex, (uint32_t));
1443ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, GetSelectedFrame, ());
1444ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, SetSelectedFrame, (uint32_t));
1445ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(bool, SBThread, EventIsThreadEvent,
1446ae211eceSMichal Gorny                               (const lldb::SBEvent &));
1447ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(lldb::SBFrame, SBThread, GetStackFrameFromEvent,
1448ae211eceSMichal Gorny                               (const lldb::SBEvent &));
1449ae211eceSMichal Gorny   LLDB_REGISTER_STATIC_METHOD(lldb::SBThread, SBThread, GetThreadFromEvent,
1450ae211eceSMichal Gorny                               (const lldb::SBEvent &));
1451ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool,
1452ae211eceSMichal Gorny                              SBThread, operator==,(const lldb::SBThread &));
1453ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool,
1454ae211eceSMichal Gorny                              SBThread, operator!=,(const lldb::SBThread &));
1455ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetStatus, (lldb::SBStream &));
1456ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetDescription,
1457ae211eceSMichal Gorny                              (lldb::SBStream &));
1458ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetDescription,
1459ae211eceSMichal Gorny                              (lldb::SBStream &, bool));
1460ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBThread, SBThread, GetExtendedBacktraceThread,
1461ae211eceSMichal Gorny                        (const char *));
1462ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(uint32_t, SBThread,
1463ae211eceSMichal Gorny                        GetExtendedBacktraceOriginatingIndexID, ());
1464ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBValue, SBThread, GetCurrentException, ());
1465ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBThread, SBThread, GetCurrentExceptionBacktrace,
1466ae211eceSMichal Gorny                        ());
1467ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBThread, SafeToCallFunctions, ());
1468e687aa82SJonas Devlieghere   LLDB_REGISTER_CHAR_PTR_METHOD(size_t, SBThread, GetStopDescription);
1469ae211eceSMichal Gorny }
1470ae211eceSMichal Gorny 
1471ae211eceSMichal Gorny }
1472ae211eceSMichal Gorny }
1473