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"
10bd4bf82aSJonas Devlieghere #include "Utils.h"
11bd4bf82aSJonas Devlieghere #include "lldb/API/SBAddress.h"
12bd4bf82aSJonas Devlieghere #include "lldb/API/SBDebugger.h"
13bd4bf82aSJonas Devlieghere #include "lldb/API/SBEvent.h"
1430fdc8d8SChris Lattner #include "lldb/API/SBFileSpec.h"
15bd4bf82aSJonas Devlieghere #include "lldb/API/SBFrame.h"
16bd4bf82aSJonas Devlieghere #include "lldb/API/SBProcess.h"
17dde9cff3SCaroline Tice #include "lldb/API/SBStream.h"
1827a14f19SJim Ingham #include "lldb/API/SBStructuredData.h"
19b9c1b51eSKate Stone #include "lldb/API/SBSymbolContext.h"
20bd4bf82aSJonas Devlieghere #include "lldb/API/SBThreadCollection.h"
21bd4bf82aSJonas Devlieghere #include "lldb/API/SBThreadPlan.h"
22bd4bf82aSJonas Devlieghere #include "lldb/API/SBValue.h"
234e78f606SGreg Clayton #include "lldb/Breakpoint/BreakpointLocation.h"
246611103cSGreg Clayton #include "lldb/Core/Debugger.h"
2530fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h"
2627a14f19SJim Ingham #include "lldb/Core/StructuredDataImpl.h"
27a78bd7ffSZachary Turner #include "lldb/Core/ValueObject.h"
286611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
2993749ab3SZachary Turner #include "lldb/Symbol/CompileUnit.h"
30b9c1b51eSKate Stone #include "lldb/Symbol/SymbolContext.h"
3130fdc8d8SChris Lattner #include "lldb/Target/Process.h"
32b9ffa98cSJason Molenda #include "lldb/Target/Queue.h"
33f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h"
34b9c1b51eSKate Stone #include "lldb/Target/SystemRuntime.h"
3530fdc8d8SChris Lattner #include "lldb/Target/Target.h"
36b9c1b51eSKate Stone #include "lldb/Target/Thread.h"
3730fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h"
38b9c1b51eSKate Stone #include "lldb/Target/ThreadPlanStepInRange.h"
3930fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h"
4030fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h"
4130fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h"
421755f5b1SJonas Devlieghere #include "lldb/Utility/Instrumentation.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 
GetBroadcasterClassName()53b9c1b51eSKate Stone const char *SBThread::GetBroadcasterClassName() {
541755f5b1SJonas Devlieghere   LLDB_INSTRUMENT();
55baf5664fSJonas Devlieghere 
564f465cffSJim Ingham   return Thread::GetStaticBroadcasterClass().AsCString();
574f465cffSJim Ingham }
584f465cffSJim Ingham 
59cfd1acedSGreg Clayton // Constructors
SBThread()60baf5664fSJonas Devlieghere SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {
611755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
62baf5664fSJonas Devlieghere }
6330fdc8d8SChris Lattner 
SBThread(const ThreadSP & lldb_object_sp)64b9c1b51eSKate Stone SBThread::SBThread(const ThreadSP &lldb_object_sp)
65baf5664fSJonas Devlieghere     : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {
661755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, lldb_object_sp);
67baf5664fSJonas Devlieghere }
6830fdc8d8SChris Lattner 
SBThread(const SBThread & rhs)69a3436f73SKazu Hirata SBThread::SBThread(const SBThread &rhs) {
701755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, rhs);
71baf5664fSJonas Devlieghere 
72bd4bf82aSJonas Devlieghere   m_opaque_sp = clone(rhs.m_opaque_sp);
73bd4bf82aSJonas Devlieghere }
7430fdc8d8SChris Lattner 
75cfd1acedSGreg Clayton // Assignment operator
76cfd1acedSGreg Clayton 
operator =(const SBThread & rhs)77b9c1b51eSKate Stone const lldb::SBThread &SBThread::operator=(const SBThread &rhs) {
781755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, rhs);
79baf5664fSJonas Devlieghere 
80cfd1acedSGreg Clayton   if (this != &rhs)
81bd4bf82aSJonas Devlieghere     m_opaque_sp = clone(rhs.m_opaque_sp);
82d232abc3SJonas Devlieghere   return *this;
83cfd1acedSGreg Clayton }
84cfd1acedSGreg Clayton 
8530fdc8d8SChris Lattner // Destructor
86866b7a65SJonas Devlieghere SBThread::~SBThread() = default;
8730fdc8d8SChris Lattner 
GetQueue() const88b9c1b51eSKate Stone lldb::SBQueue SBThread::GetQueue() const {
891755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
90baf5664fSJonas Devlieghere 
91b9ffa98cSJason Molenda   SBQueue sb_queue;
92b9ffa98cSJason Molenda   QueueSP queue_sp;
93bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
94bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
95b9ffa98cSJason Molenda 
96b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
97b9ffa98cSJason Molenda     Process::StopLocker stop_locker;
98b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
99b9ffa98cSJason Molenda       queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
100b9c1b51eSKate Stone       if (queue_sp) {
101b9ffa98cSJason Molenda         sb_queue.SetQueue(queue_sp);
102b9ffa98cSJason Molenda       }
103b9ffa98cSJason Molenda     }
104b9ffa98cSJason Molenda   }
105b9ffa98cSJason Molenda 
106d232abc3SJonas Devlieghere   return sb_queue;
107b9ffa98cSJason Molenda }
108b9ffa98cSJason Molenda 
IsValid() const109b9c1b51eSKate Stone bool SBThread::IsValid() const {
1101755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
1117f5237bcSPavel Labath   return this->operator bool();
1127f5237bcSPavel Labath }
operator bool() const1137f5237bcSPavel Labath SBThread::operator bool() const {
1141755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
115baf5664fSJonas Devlieghere 
116bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
117bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1187fa7dc36SJim Ingham 
1197fa7dc36SJim Ingham   Target *target = exe_ctx.GetTargetPtr();
1207fa7dc36SJim Ingham   Process *process = exe_ctx.GetProcessPtr();
121b9c1b51eSKate Stone   if (target && process) {
1227fa7dc36SJim Ingham     Process::StopLocker stop_locker;
1237fa7dc36SJim Ingham     if (stop_locker.TryLock(&process->GetRunLock()))
124248a1305SKonrad Kleine       return m_opaque_sp->GetThreadSP().get() != nullptr;
12530fdc8d8SChris Lattner   }
1267fa7dc36SJim Ingham   // Without a valid target & process, this thread can't be valid.
1277fa7dc36SJim Ingham   return false;
1287fa7dc36SJim Ingham }
12930fdc8d8SChris Lattner 
Clear()130baf5664fSJonas Devlieghere void SBThread::Clear() {
1311755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
132baf5664fSJonas Devlieghere 
133baf5664fSJonas Devlieghere   m_opaque_sp->Clear();
134baf5664fSJonas Devlieghere }
13548e42549SGreg Clayton 
GetStopReason()136b9c1b51eSKate Stone StopReason SBThread::GetStopReason() {
1371755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
138baf5664fSJonas Devlieghere 
139ceb6b139SCaroline Tice   StopReason reason = eStopReasonInvalid;
140bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
141bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1424fc6cb9cSJim Ingham 
143b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1447fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
145b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
14697d5cf05SGreg Clayton       return exe_ctx.GetThreadPtr()->GetStopReason();
147c9858e4dSGreg Clayton     }
1487fdf9ef1SGreg Clayton   }
149ceb6b139SCaroline Tice 
150ceb6b139SCaroline Tice   return reason;
15130fdc8d8SChris Lattner }
15230fdc8d8SChris Lattner 
GetStopReasonDataCount()153b9c1b51eSKate Stone size_t SBThread::GetStopReasonDataCount() {
1541755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
155baf5664fSJonas Devlieghere 
156bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
157bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1584fc6cb9cSJim Ingham 
159b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1607fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
161b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1621ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
163b9c1b51eSKate Stone       if (stop_info_sp) {
1644e78f606SGreg Clayton         StopReason reason = stop_info_sp->GetStopReason();
165b9c1b51eSKate Stone         switch (reason) {
1664e78f606SGreg Clayton         case eStopReasonInvalid:
1674e78f606SGreg Clayton         case eStopReasonNone:
1684e78f606SGreg Clayton         case eStopReasonTrace:
16990ba8115SGreg Clayton         case eStopReasonExec:
1704e78f606SGreg Clayton         case eStopReasonPlanComplete:
171f85defaeSAndrew Kaylor         case eStopReasonThreadExiting:
172afdf842bSKuba Brecka         case eStopReasonInstrumentation:
1730b697561SWalter Erquinigo         case eStopReasonProcessorTrace:
1746c37984eSMichał Górny         case eStopReasonVForkDone:
1754e78f606SGreg Clayton           // There is no data for these stop reasons.
1764e78f606SGreg Clayton           return 0;
1774e78f606SGreg Clayton 
178b9c1b51eSKate Stone         case eStopReasonBreakpoint: {
1794e78f606SGreg Clayton           break_id_t site_id = stop_info_sp->GetValue();
180b9c1b51eSKate Stone           lldb::BreakpointSiteSP bp_site_sp(
181b9c1b51eSKate Stone               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
182b9c1b51eSKate Stone                   site_id));
1834e78f606SGreg Clayton           if (bp_site_sp)
1844e78f606SGreg Clayton             return bp_site_sp->GetNumberOfOwners() * 2;
1854e78f606SGreg Clayton           else
1864e78f606SGreg Clayton             return 0; // Breakpoint must have cleared itself...
187b9c1b51eSKate Stone         } break;
1884e78f606SGreg Clayton 
1894e78f606SGreg Clayton         case eStopReasonWatchpoint:
190290fa41bSJohnny Chen           return 1;
1914e78f606SGreg Clayton 
1924e78f606SGreg Clayton         case eStopReasonSignal:
1934e78f606SGreg Clayton           return 1;
1944e78f606SGreg Clayton 
1954e78f606SGreg Clayton         case eStopReasonException:
1964e78f606SGreg Clayton           return 1;
1976c37984eSMichał Górny 
1986c37984eSMichał Górny         case eStopReasonFork:
1996c37984eSMichał Górny           return 1;
2006c37984eSMichał Górny 
2016c37984eSMichał Górny         case eStopReasonVFork:
2026c37984eSMichał Górny           return 1;
2034e78f606SGreg Clayton         }
2044e78f606SGreg Clayton       }
205c9858e4dSGreg Clayton     }
2067fdf9ef1SGreg Clayton   }
2074e78f606SGreg Clayton   return 0;
2084e78f606SGreg Clayton }
2094e78f606SGreg Clayton 
GetStopReasonDataAtIndex(uint32_t idx)210b9c1b51eSKate Stone uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
2111755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, idx);
212baf5664fSJonas Devlieghere 
213bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
214bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
2154fc6cb9cSJim Ingham 
216b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
2177fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
218b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
2191ac04c30SGreg Clayton       Thread *thread = exe_ctx.GetThreadPtr();
2201ac04c30SGreg Clayton       StopInfoSP stop_info_sp = thread->GetStopInfo();
221b9c1b51eSKate Stone       if (stop_info_sp) {
2224e78f606SGreg Clayton         StopReason reason = stop_info_sp->GetStopReason();
223b9c1b51eSKate Stone         switch (reason) {
2244e78f606SGreg Clayton         case eStopReasonInvalid:
2254e78f606SGreg Clayton         case eStopReasonNone:
2264e78f606SGreg Clayton         case eStopReasonTrace:
22790ba8115SGreg Clayton         case eStopReasonExec:
2284e78f606SGreg Clayton         case eStopReasonPlanComplete:
229f85defaeSAndrew Kaylor         case eStopReasonThreadExiting:
230afdf842bSKuba Brecka         case eStopReasonInstrumentation:
2310b697561SWalter Erquinigo         case eStopReasonProcessorTrace:
2326c37984eSMichał Górny         case eStopReasonVForkDone:
2334e78f606SGreg Clayton           // There is no data for these stop reasons.
2344e78f606SGreg Clayton           return 0;
2354e78f606SGreg Clayton 
236b9c1b51eSKate Stone         case eStopReasonBreakpoint: {
2374e78f606SGreg Clayton           break_id_t site_id = stop_info_sp->GetValue();
238b9c1b51eSKate Stone           lldb::BreakpointSiteSP bp_site_sp(
239b9c1b51eSKate Stone               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
240b9c1b51eSKate Stone                   site_id));
241b9c1b51eSKate Stone           if (bp_site_sp) {
2424e78f606SGreg Clayton             uint32_t bp_index = idx / 2;
243b9c1b51eSKate Stone             BreakpointLocationSP bp_loc_sp(
244b9c1b51eSKate Stone                 bp_site_sp->GetOwnerAtIndex(bp_index));
245b9c1b51eSKate Stone             if (bp_loc_sp) {
246b9c1b51eSKate Stone               if (idx & 1) {
2474e78f606SGreg Clayton                 // Odd idx, return the breakpoint location ID
2484e78f606SGreg Clayton                 return bp_loc_sp->GetID();
249b9c1b51eSKate Stone               } else {
2504e78f606SGreg Clayton                 // Even idx, return the breakpoint ID
2514e78f606SGreg Clayton                 return bp_loc_sp->GetBreakpoint().GetID();
2524e78f606SGreg Clayton               }
2534e78f606SGreg Clayton             }
2544e78f606SGreg Clayton           }
2554e78f606SGreg Clayton           return LLDB_INVALID_BREAK_ID;
256b9c1b51eSKate Stone         } break;
2574e78f606SGreg Clayton 
2584e78f606SGreg Clayton         case eStopReasonWatchpoint:
259290fa41bSJohnny Chen           return stop_info_sp->GetValue();
2604e78f606SGreg Clayton 
2614e78f606SGreg Clayton         case eStopReasonSignal:
2624e78f606SGreg Clayton           return stop_info_sp->GetValue();
2634e78f606SGreg Clayton 
2644e78f606SGreg Clayton         case eStopReasonException:
2654e78f606SGreg Clayton           return stop_info_sp->GetValue();
2666c37984eSMichał Górny 
2676c37984eSMichał Górny         case eStopReasonFork:
2686c37984eSMichał Górny           return stop_info_sp->GetValue();
2696c37984eSMichał Górny 
2706c37984eSMichał Górny         case eStopReasonVFork:
2716c37984eSMichał Górny           return stop_info_sp->GetValue();
2724e78f606SGreg Clayton         }
2734e78f606SGreg Clayton       }
274c9858e4dSGreg Clayton     }
2757fdf9ef1SGreg Clayton   }
2764e78f606SGreg Clayton   return 0;
2774e78f606SGreg Clayton }
2784e78f606SGreg Clayton 
GetStopReasonExtendedInfoAsJSON(lldb::SBStream & stream)279b9c1b51eSKate Stone bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) {
2801755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, stream);
281baf5664fSJonas Devlieghere 
282afdf842bSKuba Brecka   Stream &strm = stream.ref();
283afdf842bSKuba Brecka 
284b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
285b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
286b2e7d28eSJim Ingham 
287afdf842bSKuba Brecka   if (!exe_ctx.HasThreadScope())
288afdf842bSKuba Brecka     return false;
289afdf842bSKuba Brecka 
290afdf842bSKuba Brecka   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
291afdf842bSKuba Brecka   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
292afdf842bSKuba Brecka   if (!info)
293afdf842bSKuba Brecka     return false;
294afdf842bSKuba Brecka 
295afdf842bSKuba Brecka   info->Dump(strm);
296afdf842bSKuba Brecka 
297afdf842bSKuba Brecka   return true;
298afdf842bSKuba Brecka }
299afdf842bSKuba Brecka 
3006a831436SKuba Brecka SBThreadCollection
GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type)301b9c1b51eSKate Stone SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
3021755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, type);
303baf5664fSJonas Devlieghere 
3045e3fe22cSJonas Devlieghere   SBThreadCollection threads;
3056a831436SKuba Brecka 
306b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
307b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
308b2e7d28eSJim Ingham 
3096a831436SKuba Brecka   if (!exe_ctx.HasThreadScope())
310d232abc3SJonas Devlieghere     return SBThreadCollection();
3116a831436SKuba Brecka 
3126a831436SKuba Brecka   ProcessSP process_sp = exe_ctx.GetProcessSP();
3136a831436SKuba Brecka 
3146a831436SKuba Brecka   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
3156a831436SKuba Brecka   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
3166a831436SKuba Brecka   if (!info)
317d232abc3SJonas Devlieghere     return threads;
3186a831436SKuba Brecka 
3195e3fe22cSJonas Devlieghere   threads = process_sp->GetInstrumentationRuntime(type)
3205e3fe22cSJonas Devlieghere                 ->GetBacktracesFromExtendedStopInfo(info);
321d232abc3SJonas Devlieghere   return threads;
3226a831436SKuba Brecka }
3236a831436SKuba Brecka 
GetStopDescription(char * dst,size_t dst_len)324b9c1b51eSKate Stone size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
3251755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, dst, dst_len);
326baf5664fSJonas Devlieghere 
327bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
328bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3294fc6cb9cSJim Ingham 
33030fdc8d8SChris Lattner   if (dst)
33130fdc8d8SChris Lattner     *dst = 0;
33220ce8affSFred Riss 
33320ce8affSFred Riss   if (!exe_ctx.HasThreadScope())
33430fdc8d8SChris Lattner     return 0;
33520ce8affSFred Riss 
33620ce8affSFred Riss   Process::StopLocker stop_locker;
33720ce8affSFred Riss   if (!stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
33820ce8affSFred Riss     return 0;
33920ce8affSFred Riss 
34020ce8affSFred Riss   std::string thread_stop_desc = exe_ctx.GetThreadPtr()->GetStopDescription();
34120ce8affSFred Riss   if (thread_stop_desc.empty())
34220ce8affSFred Riss     return 0;
34320ce8affSFred Riss 
34420ce8affSFred Riss   if (dst)
34520ce8affSFred Riss     return ::snprintf(dst, dst_len, "%s", thread_stop_desc.c_str()) + 1;
34620ce8affSFred Riss 
34720ce8affSFred Riss   // NULL dst passed in, return the length needed to contain the
34820ce8affSFred Riss   // description.
34920ce8affSFred Riss   return thread_stop_desc.size() + 1; // Include the NULL byte for size
35030fdc8d8SChris Lattner }
35130fdc8d8SChris Lattner 
GetStopReturnValue()352b9c1b51eSKate Stone SBValue SBThread::GetStopReturnValue() {
3531755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
354baf5664fSJonas Devlieghere 
35573ca05a2SJim Ingham   ValueObjectSP return_valobj_sp;
356bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
357bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3584fc6cb9cSJim Ingham 
359b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
3607fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
361b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
3621ac04c30SGreg Clayton       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
363b9c1b51eSKate Stone       if (stop_info_sp) {
36473ca05a2SJim Ingham         return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp);
36573ca05a2SJim Ingham       }
366c9858e4dSGreg Clayton     }
3677fdf9ef1SGreg Clayton   }
36873ca05a2SJim Ingham 
369d232abc3SJonas Devlieghere   return SBValue(return_valobj_sp);
37073ca05a2SJim Ingham }
37173ca05a2SJim Ingham 
SetThread(const ThreadSP & lldb_object_sp)372b9c1b51eSKate Stone void SBThread::SetThread(const ThreadSP &lldb_object_sp) {
3737fdf9ef1SGreg Clayton   m_opaque_sp->SetThreadSP(lldb_object_sp);
37430fdc8d8SChris Lattner }
37530fdc8d8SChris Lattner 
GetThreadID() const376b9c1b51eSKate Stone lldb::tid_t SBThread::GetThreadID() const {
3771755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
378baf5664fSJonas Devlieghere 
3797fdf9ef1SGreg Clayton   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
38017a6ad05SGreg Clayton   if (thread_sp)
3811ac04c30SGreg Clayton     return thread_sp->GetID();
3821ac04c30SGreg Clayton   return LLDB_INVALID_THREAD_ID;
38330fdc8d8SChris Lattner }
38430fdc8d8SChris Lattner 
GetIndexID() const385b9c1b51eSKate Stone uint32_t SBThread::GetIndexID() const {
3861755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
387baf5664fSJonas Devlieghere 
3887fdf9ef1SGreg Clayton   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
38917a6ad05SGreg Clayton   if (thread_sp)
39017a6ad05SGreg Clayton     return thread_sp->GetIndexID();
39130fdc8d8SChris Lattner   return LLDB_INVALID_INDEX32;
39230fdc8d8SChris Lattner }
3931ac04c30SGreg Clayton 
GetName() const394b9c1b51eSKate Stone const char *SBThread::GetName() const {
3951755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
396baf5664fSJonas Devlieghere 
397248a1305SKonrad Kleine   const char *name = nullptr;
398bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
399bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4004fc6cb9cSJim Ingham 
401b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4027fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
403b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4041ac04c30SGreg Clayton       name = exe_ctx.GetThreadPtr()->GetName();
405c9858e4dSGreg Clayton     }
4067fdf9ef1SGreg Clayton   }
407ceb6b139SCaroline Tice 
4084838131bSGreg Clayton   return name;
40930fdc8d8SChris Lattner }
41030fdc8d8SChris Lattner 
GetQueueName() const411b9c1b51eSKate Stone const char *SBThread::GetQueueName() const {
4121755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
413baf5664fSJonas Devlieghere 
414248a1305SKonrad Kleine   const char *name = nullptr;
415bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
416bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4174fc6cb9cSJim Ingham 
418b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4197fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
420b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4211ac04c30SGreg Clayton       name = exe_ctx.GetThreadPtr()->GetQueueName();
422c9858e4dSGreg Clayton     }
4237fdf9ef1SGreg Clayton   }
424ceb6b139SCaroline Tice 
4254838131bSGreg Clayton   return name;
42630fdc8d8SChris Lattner }
42730fdc8d8SChris Lattner 
GetQueueID() const428b9c1b51eSKate Stone lldb::queue_id_t SBThread::GetQueueID() const {
4291755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
430baf5664fSJonas Devlieghere 
4314fdb5863SJason Molenda   queue_id_t id = LLDB_INVALID_QUEUE_ID;
432bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
433bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4344fdb5863SJason Molenda 
435b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
4364fdb5863SJason Molenda     Process::StopLocker stop_locker;
437b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
4384fdb5863SJason Molenda       id = exe_ctx.GetThreadPtr()->GetQueueID();
4394fdb5863SJason Molenda     }
4404fdb5863SJason Molenda   }
4414fdb5863SJason Molenda 
4424fdb5863SJason Molenda   return id;
4434fdb5863SJason Molenda }
4444fdb5863SJason Molenda 
GetInfoItemByPathAsString(const char * path,SBStream & strm)445b9c1b51eSKate Stone bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
4461755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, path, strm);
447baf5664fSJonas Devlieghere 
448705b1809SJason Molenda   bool success = false;
449bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
450bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
451705b1809SJason Molenda 
452b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
453705b1809SJason Molenda     Process::StopLocker stop_locker;
454b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
455705b1809SJason Molenda       Thread *thread = exe_ctx.GetThreadPtr();
456705b1809SJason Molenda       StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
457b9c1b51eSKate Stone       if (info_root_sp) {
458b9c1b51eSKate Stone         StructuredData::ObjectSP node =
459b9c1b51eSKate Stone             info_root_sp->GetObjectForDotSeparatedPath(path);
460b9c1b51eSKate Stone         if (node) {
4615bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeString) {
4622833321fSZachary Turner             strm.Printf("%s", node->GetAsString()->GetValue().str().c_str());
463705b1809SJason Molenda             success = true;
464705b1809SJason Molenda           }
4655bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeInteger) {
466705b1809SJason Molenda             strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue());
467705b1809SJason Molenda             success = true;
468705b1809SJason Molenda           }
4695bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeFloat) {
470705b1809SJason Molenda             strm.Printf("0x%f", node->GetAsFloat()->GetValue());
471705b1809SJason Molenda             success = true;
472705b1809SJason Molenda           }
4735bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeBoolean) {
474a6682a41SJonas Devlieghere             if (node->GetAsBoolean()->GetValue())
475705b1809SJason Molenda               strm.Printf("true");
476705b1809SJason Molenda             else
477705b1809SJason Molenda               strm.Printf("false");
478705b1809SJason Molenda             success = true;
479705b1809SJason Molenda           }
4805bfee5f1SAbhishek Aggarwal           if (node->GetType() == eStructuredDataTypeNull) {
481705b1809SJason Molenda             strm.Printf("null");
482705b1809SJason Molenda             success = true;
483705b1809SJason Molenda           }
484705b1809SJason Molenda         }
485705b1809SJason Molenda       }
486705b1809SJason Molenda     }
487705b1809SJason Molenda   }
488705b1809SJason Molenda 
489705b1809SJason Molenda   return success;
490705b1809SJason Molenda }
491705b1809SJason Molenda 
ResumeNewPlan(ExecutionContext & exe_ctx,ThreadPlan * new_plan)492b9c1b51eSKate Stone SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
493b9c1b51eSKate Stone                                 ThreadPlan *new_plan) {
49464e7ead1SJim Ingham   SBError sb_error;
49564e7ead1SJim Ingham 
49664e7ead1SJim Ingham   Process *process = exe_ctx.GetProcessPtr();
497b9c1b51eSKate Stone   if (!process) {
49864e7ead1SJim Ingham     sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
49964e7ead1SJim Ingham     return sb_error;
50064e7ead1SJim Ingham   }
50164e7ead1SJim Ingham 
50264e7ead1SJim Ingham   Thread *thread = exe_ctx.GetThreadPtr();
503b9c1b51eSKate Stone   if (!thread) {
50464e7ead1SJim Ingham     sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
50564e7ead1SJim Ingham     return sb_error;
50664e7ead1SJim Ingham   }
50764e7ead1SJim Ingham 
50804cbfa95SQuinn Pham   // User level plans should be Controlling Plans so they can be interrupted,
50904cbfa95SQuinn Pham   // other plans executed, and then a "continue" will resume the plan.
510248a1305SKonrad Kleine   if (new_plan != nullptr) {
51104cbfa95SQuinn Pham     new_plan->SetIsControllingPlan(true);
51264e7ead1SJim Ingham     new_plan->SetOkayToDiscard(false);
51364e7ead1SJim Ingham   }
51464e7ead1SJim Ingham 
51564e7ead1SJim Ingham   // Why do we need to set the current thread by ID here???
51664e7ead1SJim Ingham   process->GetThreadList().SetSelectedThreadByID(thread->GetID());
51764e7ead1SJim Ingham 
518dc6224e0SGreg Clayton   if (process->GetTarget().GetDebugger().GetAsyncExecution())
519dc6224e0SGreg Clayton     sb_error.ref() = process->Resume();
520dc6224e0SGreg Clayton   else
521248a1305SKonrad Kleine     sb_error.ref() = process->ResumeSynchronous(nullptr);
52264e7ead1SJim Ingham 
52364e7ead1SJim Ingham   return sb_error;
52464e7ead1SJim Ingham }
52530fdc8d8SChris Lattner 
StepOver(lldb::RunMode stop_other_threads)526b9c1b51eSKate Stone void SBThread::StepOver(lldb::RunMode stop_other_threads) {
5271755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, stop_other_threads);
528baf5664fSJonas Devlieghere 
529859f54b3SAlexander Polyakov   SBError error; // Ignored
530859f54b3SAlexander Polyakov   StepOver(stop_other_threads, error);
531859f54b3SAlexander Polyakov }
532859f54b3SAlexander Polyakov 
StepOver(lldb::RunMode stop_other_threads,SBError & error)533859f54b3SAlexander Polyakov void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
5341755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, stop_other_threads, error);
535baf5664fSJonas Devlieghere 
536bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
537bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
53817a6ad05SGreg Clayton 
539859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
540859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
541859f54b3SAlexander Polyakov     return;
542859f54b3SAlexander Polyakov   }
543859f54b3SAlexander Polyakov 
5441ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
5457ba6e991SJim Ingham   bool abort_other_plans = false;
546b57e4a1bSJason Molenda   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
54730fdc8d8SChris Lattner 
548e103ae92SJonas Devlieghere   Status new_plan_status;
5494d56e9c1SJim Ingham   ThreadPlanSP new_plan_sp;
550b9c1b51eSKate Stone   if (frame_sp) {
551b9c1b51eSKate Stone     if (frame_sp->HasDebugInformation()) {
5524b4b2478SJim Ingham       const LazyBool avoid_no_debug = eLazyBoolCalculate;
55330fdc8d8SChris Lattner       SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
554b9c1b51eSKate Stone       new_plan_sp = thread->QueueThreadPlanForStepOverRange(
555b9c1b51eSKate Stone           abort_other_plans, sc.line_entry, sc, stop_other_threads,
556e103ae92SJonas Devlieghere           new_plan_status, avoid_no_debug);
557b9c1b51eSKate Stone     } else {
558b9c1b51eSKate Stone       new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
559e103ae92SJonas Devlieghere           true, abort_other_plans, stop_other_threads, new_plan_status);
56030fdc8d8SChris Lattner     }
56130fdc8d8SChris Lattner   }
562859f54b3SAlexander Polyakov   error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
56330fdc8d8SChris Lattner }
56430fdc8d8SChris Lattner 
StepInto(lldb::RunMode stop_other_threads)565b9c1b51eSKate Stone void SBThread::StepInto(lldb::RunMode stop_other_threads) {
5661755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, stop_other_threads);
567baf5664fSJonas Devlieghere 
568248a1305SKonrad Kleine   StepInto(nullptr, stop_other_threads);
569c627682eSJim Ingham }
570c627682eSJim Ingham 
StepInto(const char * target_name,lldb::RunMode stop_other_threads)571b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name,
572b9c1b51eSKate Stone                         lldb::RunMode stop_other_threads) {
5731755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, target_name, stop_other_threads);
574baf5664fSJonas Devlieghere 
575859f54b3SAlexander Polyakov   SBError error; // Ignored
576cbf6f9b2SJim Ingham   StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
577cbf6f9b2SJim Ingham }
578cbf6f9b2SJim Ingham 
StepInto(const char * target_name,uint32_t end_line,SBError & error,lldb::RunMode stop_other_threads)579b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name, uint32_t end_line,
580b9c1b51eSKate Stone                         SBError &error, lldb::RunMode stop_other_threads) {
5811755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, target_name, end_line, error, stop_other_threads);
582ceb6b139SCaroline Tice 
583bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
584bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
58517a6ad05SGreg Clayton 
586859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
587859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
588859f54b3SAlexander Polyakov     return;
589859f54b3SAlexander Polyakov   }
590859f54b3SAlexander Polyakov 
5917ba6e991SJim Ingham   bool abort_other_plans = false;
59230fdc8d8SChris Lattner 
5931ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
594b57e4a1bSJason Molenda   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
5954d56e9c1SJim Ingham   ThreadPlanSP new_plan_sp;
596e103ae92SJonas Devlieghere   Status new_plan_status;
59730fdc8d8SChris Lattner 
598b9c1b51eSKate Stone   if (frame_sp && frame_sp->HasDebugInformation()) {
599cbf6f9b2SJim Ingham     SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
600cbf6f9b2SJim Ingham     AddressRange range;
601cbf6f9b2SJim Ingham     if (end_line == LLDB_INVALID_LINE_NUMBER)
602cbf6f9b2SJim Ingham       range = sc.line_entry.range;
603b9c1b51eSKate Stone     else {
604cbf6f9b2SJim Ingham       if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
605cbf6f9b2SJim Ingham         return;
606cbf6f9b2SJim Ingham     }
607cbf6f9b2SJim Ingham 
608b9c1b51eSKate Stone     const LazyBool step_out_avoids_code_without_debug_info =
609b9c1b51eSKate Stone         eLazyBoolCalculate;
610b9c1b51eSKate Stone     const LazyBool step_in_avoids_code_without_debug_info =
611b9c1b51eSKate Stone         eLazyBoolCalculate;
612b9c1b51eSKate Stone     new_plan_sp = thread->QueueThreadPlanForStepInRange(
613b9c1b51eSKate Stone         abort_other_plans, range, sc, target_name, stop_other_threads,
614e103ae92SJonas Devlieghere         new_plan_status, step_in_avoids_code_without_debug_info,
6154b4b2478SJim Ingham         step_out_avoids_code_without_debug_info);
616b9c1b51eSKate Stone   } else {
617b9c1b51eSKate Stone     new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
618e103ae92SJonas Devlieghere         false, abort_other_plans, stop_other_threads, new_plan_status);
61930fdc8d8SChris Lattner   }
620e103ae92SJonas Devlieghere 
621e103ae92SJonas Devlieghere   if (new_plan_status.Success())
622cbf6f9b2SJim Ingham     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
623e103ae92SJonas Devlieghere   else
624e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
62530fdc8d8SChris Lattner }
62630fdc8d8SChris Lattner 
StepOut()627b9c1b51eSKate Stone void SBThread::StepOut() {
6281755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
629baf5664fSJonas Devlieghere 
630859f54b3SAlexander Polyakov   SBError error; // Ignored
631859f54b3SAlexander Polyakov   StepOut(error);
632859f54b3SAlexander Polyakov }
633859f54b3SAlexander Polyakov 
StepOut(SBError & error)634859f54b3SAlexander Polyakov void SBThread::StepOut(SBError &error) {
6351755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, error);
636baf5664fSJonas Devlieghere 
637bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
638bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
6394fc6cb9cSJim Ingham 
640859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
641859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
642859f54b3SAlexander Polyakov     return;
643859f54b3SAlexander Polyakov   }
644859f54b3SAlexander Polyakov 
6457ba6e991SJim Ingham   bool abort_other_plans = false;
64694b09246SJim Ingham   bool stop_other_threads = false;
64730fdc8d8SChris Lattner 
6481ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
6491ac04c30SGreg Clayton 
6504b4b2478SJim Ingham   const LazyBool avoid_no_debug = eLazyBoolCalculate;
651e103ae92SJonas Devlieghere   Status new_plan_status;
652b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
653248a1305SKonrad Kleine       abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
654e103ae92SJonas Devlieghere       eVoteNoOpinion, 0, new_plan_status, avoid_no_debug));
655481cef25SGreg Clayton 
656e103ae92SJonas Devlieghere   if (new_plan_status.Success())
657859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
658e103ae92SJonas Devlieghere   else
659e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
660481cef25SGreg Clayton }
661481cef25SGreg Clayton 
StepOutOfFrame(SBFrame & sb_frame)662859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
6631755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, sb_frame);
664baf5664fSJonas Devlieghere 
665859f54b3SAlexander Polyakov   SBError error; // Ignored
666859f54b3SAlexander Polyakov   StepOutOfFrame(sb_frame, error);
667859f54b3SAlexander Polyakov }
668859f54b3SAlexander Polyakov 
StepOutOfFrame(SBFrame & sb_frame,SBError & error)669859f54b3SAlexander Polyakov void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
6701755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, sb_frame, error);
671481cef25SGreg Clayton 
672bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
673bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
6744fc6cb9cSJim Ingham 
675b9c1b51eSKate Stone   if (!sb_frame.IsValid()) {
676859f54b3SAlexander Polyakov     error.SetErrorString("passed invalid SBFrame object");
677989a7558SJim Ingham     return;
678989a7558SJim Ingham   }
679989a7558SJim Ingham 
680b57e4a1bSJason Molenda   StackFrameSP frame_sp(sb_frame.GetFrameSP());
681481cef25SGreg Clayton 
682859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
683859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
684859f54b3SAlexander Polyakov     return;
685859f54b3SAlexander Polyakov   }
686859f54b3SAlexander Polyakov 
6877ba6e991SJim Ingham   bool abort_other_plans = false;
68894b09246SJim Ingham   bool stop_other_threads = false;
6891ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
690b9c1b51eSKate Stone   if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
691859f54b3SAlexander Polyakov     error.SetErrorString("passed a frame from another thread");
692859f54b3SAlexander Polyakov     return;
693989a7558SJim Ingham   }
694481cef25SGreg Clayton 
695e103ae92SJonas Devlieghere   Status new_plan_status;
696b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
697248a1305SKonrad Kleine       abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
698e103ae92SJonas Devlieghere       eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status));
69930fdc8d8SChris Lattner 
700e103ae92SJonas Devlieghere   if (new_plan_status.Success())
701859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
702e103ae92SJonas Devlieghere   else
703e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
70430fdc8d8SChris Lattner }
70530fdc8d8SChris Lattner 
StepInstruction(bool step_over)706b9c1b51eSKate Stone void SBThread::StepInstruction(bool step_over) {
7071755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, step_over);
708baf5664fSJonas Devlieghere 
709859f54b3SAlexander Polyakov   SBError error; // Ignored
710859f54b3SAlexander Polyakov   StepInstruction(step_over, error);
711859f54b3SAlexander Polyakov }
712859f54b3SAlexander Polyakov 
StepInstruction(bool step_over,SBError & error)713859f54b3SAlexander Polyakov void SBThread::StepInstruction(bool step_over, SBError &error) {
7141755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, step_over, error);
715baf5664fSJonas Devlieghere 
716bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
717bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
718ceb6b139SCaroline Tice 
719859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
720859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
721859f54b3SAlexander Polyakov     return;
722859f54b3SAlexander Polyakov   }
723859f54b3SAlexander Polyakov 
7241ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
725e103ae92SJonas Devlieghere   Status new_plan_status;
726e103ae92SJonas Devlieghere   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction(
727e103ae92SJonas Devlieghere       step_over, true, true, new_plan_status));
72864e7ead1SJim Ingham 
729e103ae92SJonas Devlieghere   if (new_plan_status.Success())
730859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
731e103ae92SJonas Devlieghere   else
732e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
73330fdc8d8SChris Lattner }
73430fdc8d8SChris Lattner 
RunToAddress(lldb::addr_t addr)735b9c1b51eSKate Stone void SBThread::RunToAddress(lldb::addr_t addr) {
7361755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, addr);
737baf5664fSJonas Devlieghere 
738859f54b3SAlexander Polyakov   SBError error; // Ignored
739859f54b3SAlexander Polyakov   RunToAddress(addr, error);
740859f54b3SAlexander Polyakov }
741859f54b3SAlexander Polyakov 
RunToAddress(lldb::addr_t addr,SBError & error)742859f54b3SAlexander Polyakov void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
7431755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, addr, error);
744baf5664fSJonas Devlieghere 
745bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
746bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
747ceb6b139SCaroline Tice 
748859f54b3SAlexander Polyakov   if (!exe_ctx.HasThreadScope()) {
749859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
750859f54b3SAlexander Polyakov     return;
751859f54b3SAlexander Polyakov   }
752859f54b3SAlexander Polyakov 
7537ba6e991SJim Ingham   bool abort_other_plans = false;
75430fdc8d8SChris Lattner   bool stop_other_threads = true;
75530fdc8d8SChris Lattner 
756e72dfb32SGreg Clayton   Address target_addr(addr);
75730fdc8d8SChris Lattner 
7581ac04c30SGreg Clayton   Thread *thread = exe_ctx.GetThreadPtr();
7591ac04c30SGreg Clayton 
760e103ae92SJonas Devlieghere   Status new_plan_status;
761b9c1b51eSKate Stone   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
762e103ae92SJonas Devlieghere       abort_other_plans, target_addr, stop_other_threads, new_plan_status));
76364e7ead1SJim Ingham 
764e103ae92SJonas Devlieghere   if (new_plan_status.Success())
765859f54b3SAlexander Polyakov     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
766e103ae92SJonas Devlieghere   else
767e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
76830fdc8d8SChris Lattner }
76930fdc8d8SChris Lattner 
StepOverUntil(lldb::SBFrame & sb_frame,lldb::SBFileSpec & sb_file_spec,uint32_t line)770b9c1b51eSKate Stone SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
771b9c1b51eSKate Stone                                 lldb::SBFileSpec &sb_file_spec, uint32_t line) {
7721755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, sb_frame, sb_file_spec, line);
773baf5664fSJonas Devlieghere 
774481cef25SGreg Clayton   SBError sb_error;
775481cef25SGreg Clayton   char path[PATH_MAX];
776481cef25SGreg Clayton 
777bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
778bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
7794fc6cb9cSJim Ingham 
780b57e4a1bSJason Molenda   StackFrameSP frame_sp(sb_frame.GetFrameSP());
78117a6ad05SGreg Clayton 
782b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
7831ac04c30SGreg Clayton     Target *target = exe_ctx.GetTargetPtr();
7841ac04c30SGreg Clayton     Thread *thread = exe_ctx.GetThreadPtr();
785481cef25SGreg Clayton 
786b9c1b51eSKate Stone     if (line == 0) {
787481cef25SGreg Clayton       sb_error.SetErrorString("invalid line argument");
788d232abc3SJonas Devlieghere       return sb_error;
789481cef25SGreg Clayton     }
790481cef25SGreg Clayton 
791b9c1b51eSKate Stone     if (!frame_sp) {
7921ac04c30SGreg Clayton       frame_sp = thread->GetSelectedFrame();
793481cef25SGreg Clayton       if (!frame_sp)
7941ac04c30SGreg Clayton         frame_sp = thread->GetStackFrameAtIndex(0);
795481cef25SGreg Clayton     }
796481cef25SGreg Clayton 
797481cef25SGreg Clayton     SymbolContext frame_sc;
798b9c1b51eSKate Stone     if (!frame_sp) {
799481cef25SGreg Clayton       sb_error.SetErrorString("no valid frames in thread to step");
800d232abc3SJonas Devlieghere       return sb_error;
801481cef25SGreg Clayton     }
802481cef25SGreg Clayton 
803481cef25SGreg Clayton     // If we have a frame, get its line
804b9c1b51eSKate Stone     frame_sc = frame_sp->GetSymbolContext(
805b9c1b51eSKate Stone         eSymbolContextCompUnit | eSymbolContextFunction |
806b9c1b51eSKate Stone         eSymbolContextLineEntry | eSymbolContextSymbol);
807481cef25SGreg Clayton 
808248a1305SKonrad Kleine     if (frame_sc.comp_unit == nullptr) {
809b9c1b51eSKate Stone       sb_error.SetErrorStringWithFormat(
810b9c1b51eSKate Stone           "frame %u doesn't have debug information", frame_sp->GetFrameIndex());
811d232abc3SJonas Devlieghere       return sb_error;
812481cef25SGreg Clayton     }
813481cef25SGreg Clayton 
814481cef25SGreg Clayton     FileSpec step_file_spec;
815b9c1b51eSKate Stone     if (sb_file_spec.IsValid()) {
816481cef25SGreg Clayton       // The file spec passed in was valid, so use it
817481cef25SGreg Clayton       step_file_spec = sb_file_spec.ref();
818b9c1b51eSKate Stone     } else {
819481cef25SGreg Clayton       if (frame_sc.line_entry.IsValid())
820481cef25SGreg Clayton         step_file_spec = frame_sc.line_entry.file;
821b9c1b51eSKate Stone       else {
822481cef25SGreg Clayton         sb_error.SetErrorString("invalid file argument or no file for frame");
823d232abc3SJonas Devlieghere         return sb_error;
824481cef25SGreg Clayton       }
825481cef25SGreg Clayton     }
826481cef25SGreg Clayton 
8279b70ddb3SJim Ingham     // Grab the current function, then we will make sure the "until" address is
8289b70ddb3SJim Ingham     // within the function.  We discard addresses that are out of the current
829b9c1b51eSKate Stone     // function, and then if there are no addresses remaining, give an
83005097246SAdrian Prantl     // appropriate error message.
8319b70ddb3SJim Ingham 
8329b70ddb3SJim Ingham     bool all_in_function = true;
8339b70ddb3SJim Ingham     AddressRange fun_range = frame_sc.function->GetAddressRange();
8349b70ddb3SJim Ingham 
835481cef25SGreg Clayton     std::vector<addr_t> step_over_until_addrs;
8367ba6e991SJim Ingham     const bool abort_other_plans = false;
837c02e3344SJim Ingham     const bool stop_other_threads = false;
8383e2ed744SMed Ismail Bennani     // TODO: Handle SourceLocationSpec column information
8393e2ed744SMed Ismail Bennani     SourceLocationSpec location_spec(
8403e2ed744SMed Ismail Bennani         step_file_spec, line, /*column=*/llvm::None, /*check_inlines=*/true,
8413e2ed744SMed Ismail Bennani         /*exact_match=*/false);
842481cef25SGreg Clayton 
843481cef25SGreg Clayton     SymbolContextList sc_list;
8443e2ed744SMed Ismail Bennani     frame_sc.comp_unit->ResolveSymbolContext(location_spec,
845c671639aSKonrad Kleine                                              eSymbolContextLineEntry, sc_list);
846c671639aSKonrad Kleine     const uint32_t num_matches = sc_list.GetSize();
847b9c1b51eSKate Stone     if (num_matches > 0) {
848481cef25SGreg Clayton       SymbolContext sc;
849b9c1b51eSKate Stone       for (uint32_t i = 0; i < num_matches; ++i) {
850b9c1b51eSKate Stone         if (sc_list.GetContextAtIndex(i, sc)) {
851b9c1b51eSKate Stone           addr_t step_addr =
852b9c1b51eSKate Stone               sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
853b9c1b51eSKate Stone           if (step_addr != LLDB_INVALID_ADDRESS) {
8549b70ddb3SJim Ingham             if (fun_range.ContainsLoadAddress(step_addr, target))
855481cef25SGreg Clayton               step_over_until_addrs.push_back(step_addr);
8569b70ddb3SJim Ingham             else
8579b70ddb3SJim Ingham               all_in_function = false;
858481cef25SGreg Clayton           }
859481cef25SGreg Clayton         }
860481cef25SGreg Clayton       }
861481cef25SGreg Clayton     }
862481cef25SGreg Clayton 
863b9c1b51eSKate Stone     if (step_over_until_addrs.empty()) {
864b9c1b51eSKate Stone       if (all_in_function) {
865481cef25SGreg Clayton         step_file_spec.GetPath(path, sizeof(path));
866b9c1b51eSKate Stone         sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path,
867b9c1b51eSKate Stone                                           line);
868b9c1b51eSKate Stone       } else
86986edbf41SGreg Clayton         sb_error.SetErrorString("step until target not in current function");
870b9c1b51eSKate Stone     } else {
871e103ae92SJonas Devlieghere       Status new_plan_status;
872b9c1b51eSKate Stone       ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil(
873b9c1b51eSKate Stone           abort_other_plans, &step_over_until_addrs[0],
874b9c1b51eSKate Stone           step_over_until_addrs.size(), stop_other_threads,
875e103ae92SJonas Devlieghere           frame_sp->GetFrameIndex(), new_plan_status));
876481cef25SGreg Clayton 
877e103ae92SJonas Devlieghere       if (new_plan_status.Success())
8784d56e9c1SJim Ingham         sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
879e103ae92SJonas Devlieghere       else
880e103ae92SJonas Devlieghere         sb_error.SetErrorString(new_plan_status.AsCString());
881481cef25SGreg Clayton     }
882b9c1b51eSKate Stone   } else {
883481cef25SGreg Clayton     sb_error.SetErrorString("this SBThread object is invalid");
884481cef25SGreg Clayton   }
885d232abc3SJonas Devlieghere   return sb_error;
886481cef25SGreg Clayton }
887481cef25SGreg Clayton 
StepUsingScriptedThreadPlan(const char * script_class_name)888b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) {
8891755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, script_class_name);
890baf5664fSJonas Devlieghere 
891d232abc3SJonas Devlieghere   return StepUsingScriptedThreadPlan(script_class_name, true);
892c915a7d2SJim Ingham }
893c915a7d2SJim Ingham 
StepUsingScriptedThreadPlan(const char * script_class_name,bool resume_immediately)894b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
895b9c1b51eSKate Stone                                             bool resume_immediately) {
8961755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, script_class_name, resume_immediately);
897baf5664fSJonas Devlieghere 
89827a14f19SJim Ingham   lldb::SBStructuredData no_data;
899d232abc3SJonas Devlieghere   return StepUsingScriptedThreadPlan(script_class_name, no_data,
900d232abc3SJonas Devlieghere                                      resume_immediately);
90127a14f19SJim Ingham }
90227a14f19SJim Ingham 
StepUsingScriptedThreadPlan(const char * script_class_name,SBStructuredData & args_data,bool resume_immediately)90327a14f19SJim Ingham SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
90427a14f19SJim Ingham                                               SBStructuredData &args_data,
90527a14f19SJim Ingham                                               bool resume_immediately) {
9061755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, script_class_name, args_data, resume_immediately);
90727a14f19SJim Ingham 
908e103ae92SJonas Devlieghere   SBError error;
9092bdbfd50SJim Ingham 
910bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
911bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
9122bdbfd50SJim Ingham 
913b9c1b51eSKate Stone   if (!exe_ctx.HasThreadScope()) {
914e103ae92SJonas Devlieghere     error.SetErrorString("this SBThread object is invalid");
915d232abc3SJonas Devlieghere     return error;
9162bdbfd50SJim Ingham   }
9172bdbfd50SJim Ingham 
9182bdbfd50SJim Ingham   Thread *thread = exe_ctx.GetThreadPtr();
919e103ae92SJonas Devlieghere   Status new_plan_status;
92027a14f19SJim Ingham   StructuredData::ObjectSP obj_sp = args_data.m_impl_up->GetObjectSP();
92127a14f19SJim Ingham 
922e103ae92SJonas Devlieghere   ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted(
92327a14f19SJim Ingham       false, script_class_name, obj_sp, false, new_plan_status);
9242bdbfd50SJim Ingham 
925e103ae92SJonas Devlieghere   if (new_plan_status.Fail()) {
926e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
927d232abc3SJonas Devlieghere     return error;
928c915a7d2SJim Ingham   }
929c915a7d2SJim Ingham 
930e103ae92SJonas Devlieghere   if (!resume_immediately)
931d232abc3SJonas Devlieghere     return error;
932c915a7d2SJim Ingham 
933e103ae92SJonas Devlieghere   if (new_plan_status.Success())
934e103ae92SJonas Devlieghere     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
935e103ae92SJonas Devlieghere   else
936e103ae92SJonas Devlieghere     error.SetErrorString(new_plan_status.AsCString());
9372bdbfd50SJim Ingham 
938d232abc3SJonas Devlieghere   return error;
9392bdbfd50SJim Ingham }
9402bdbfd50SJim Ingham 
JumpToLine(lldb::SBFileSpec & file_spec,uint32_t line)941b9c1b51eSKate Stone SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
9421755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, file_spec, line);
943baf5664fSJonas Devlieghere 
944f86248d9SRichard Mitton   SBError sb_error;
945f86248d9SRichard Mitton 
946bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
947bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
948f86248d9SRichard Mitton 
949b9c1b51eSKate Stone   if (!exe_ctx.HasThreadScope()) {
950f86248d9SRichard Mitton     sb_error.SetErrorString("this SBThread object is invalid");
951d232abc3SJonas Devlieghere     return sb_error;
952f86248d9SRichard Mitton   }
953f86248d9SRichard Mitton 
954f86248d9SRichard Mitton   Thread *thread = exe_ctx.GetThreadPtr();
955f86248d9SRichard Mitton 
95628e4942bSPavel Labath   Status err = thread->JumpToLine(file_spec.ref(), line, true);
957f86248d9SRichard Mitton   sb_error.SetError(err);
958d232abc3SJonas Devlieghere   return sb_error;
959f86248d9SRichard Mitton }
960f86248d9SRichard Mitton 
ReturnFromFrame(SBFrame & frame,SBValue & return_value)961b9c1b51eSKate Stone SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
9621755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, frame, return_value);
963baf5664fSJonas Devlieghere 
9644413758cSJim Ingham   SBError sb_error;
9654413758cSJim Ingham 
966bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
967bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
9684413758cSJim Ingham 
969b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
9704413758cSJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
971b9c1b51eSKate Stone     sb_error.SetError(
972b9c1b51eSKate Stone         thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
9734413758cSJim Ingham   }
9744413758cSJim Ingham 
975d232abc3SJonas Devlieghere   return sb_error;
9764413758cSJim Ingham }
9774413758cSJim Ingham 
UnwindInnermostExpression()978b9c1b51eSKate Stone SBError SBThread::UnwindInnermostExpression() {
9791755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
980baf5664fSJonas Devlieghere 
9814ac8e93aSJim Ingham   SBError sb_error;
9824ac8e93aSJim Ingham 
9834ac8e93aSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
9844ac8e93aSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
9854ac8e93aSJim Ingham 
986b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
9874ac8e93aSJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
9884ac8e93aSJim Ingham     sb_error.SetError(thread->UnwindInnermostExpression());
9894ac8e93aSJim Ingham     if (sb_error.Success())
9904ac8e93aSJim Ingham       thread->SetSelectedFrameByIndex(0, false);
9914ac8e93aSJim Ingham   }
9924ac8e93aSJim Ingham 
993d232abc3SJonas Devlieghere   return sb_error;
9944ac8e93aSJim Ingham }
995481cef25SGreg Clayton 
Suspend()996b9c1b51eSKate Stone bool SBThread::Suspend() {
9971755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
998baf5664fSJonas Devlieghere 
999859f54b3SAlexander Polyakov   SBError error; // Ignored
1000859f54b3SAlexander Polyakov   return Suspend(error);
1001859f54b3SAlexander Polyakov }
1002859f54b3SAlexander Polyakov 
Suspend(SBError & error)1003859f54b3SAlexander Polyakov bool SBThread::Suspend(SBError &error) {
10041755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, error);
1005baf5664fSJonas Devlieghere 
1006b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1007b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1008b2e7d28eSJim Ingham 
1009c9858e4dSGreg Clayton   bool result = false;
1010b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1011c9858e4dSGreg Clayton     Process::StopLocker stop_locker;
1012b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
10131ac04c30SGreg Clayton       exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
1014c9858e4dSGreg Clayton       result = true;
1015b9c1b51eSKate Stone     } else {
1016859f54b3SAlexander Polyakov       error.SetErrorString("process is running");
1017c9858e4dSGreg Clayton     }
1018859f54b3SAlexander Polyakov   } else
1019859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
1020c9858e4dSGreg Clayton   return result;
1021722a0cdcSGreg Clayton }
1022722a0cdcSGreg Clayton 
Resume()1023b9c1b51eSKate Stone bool SBThread::Resume() {
10241755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
1025baf5664fSJonas Devlieghere 
1026859f54b3SAlexander Polyakov   SBError error; // Ignored
1027859f54b3SAlexander Polyakov   return Resume(error);
1028859f54b3SAlexander Polyakov }
1029859f54b3SAlexander Polyakov 
Resume(SBError & error)1030859f54b3SAlexander Polyakov bool SBThread::Resume(SBError &error) {
10311755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, error);
1032baf5664fSJonas Devlieghere 
1033b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1034b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1035b2e7d28eSJim Ingham 
1036c9858e4dSGreg Clayton   bool result = false;
1037b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1038c9858e4dSGreg Clayton     Process::StopLocker stop_locker;
1039b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
10406c9ed91cSJim Ingham       const bool override_suspend = true;
10416c9ed91cSJim Ingham       exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
1042c9858e4dSGreg Clayton       result = true;
1043b9c1b51eSKate Stone     } else {
1044859f54b3SAlexander Polyakov       error.SetErrorString("process is running");
1045c9858e4dSGreg Clayton     }
1046859f54b3SAlexander Polyakov   } else
1047859f54b3SAlexander Polyakov     error.SetErrorString("this SBThread object is invalid");
1048c9858e4dSGreg Clayton   return result;
1049722a0cdcSGreg Clayton }
1050722a0cdcSGreg Clayton 
IsSuspended()1051b9c1b51eSKate Stone bool SBThread::IsSuspended() {
10521755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
1053baf5664fSJonas Devlieghere 
1054b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1055b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1056b2e7d28eSJim Ingham 
10571ac04c30SGreg Clayton   if (exe_ctx.HasThreadScope())
10581ac04c30SGreg Clayton     return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
1059722a0cdcSGreg Clayton   return false;
1060722a0cdcSGreg Clayton }
1061722a0cdcSGreg Clayton 
IsStopped()1062b9c1b51eSKate Stone bool SBThread::IsStopped() {
10631755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
1064baf5664fSJonas Devlieghere 
1065b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1066b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1067b2e7d28eSJim Ingham 
1068a75418dbSAndrew Kaylor   if (exe_ctx.HasThreadScope())
1069a75418dbSAndrew Kaylor     return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1070a75418dbSAndrew Kaylor   return false;
1071a75418dbSAndrew Kaylor }
1072a75418dbSAndrew Kaylor 
GetProcess()1073b9c1b51eSKate Stone SBProcess SBThread::GetProcess() {
10741755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
1075baf5664fSJonas Devlieghere 
1076b9556accSGreg Clayton   SBProcess sb_process;
1077b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1078b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1079b2e7d28eSJim Ingham 
1080b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1081b9c1b51eSKate Stone     // Have to go up to the target so we can get a shared pointer to our
1082b9c1b51eSKate Stone     // process...
10831ac04c30SGreg Clayton     sb_process.SetSP(exe_ctx.GetProcessSP());
108430fdc8d8SChris Lattner   }
1085ceb6b139SCaroline Tice 
1086d232abc3SJonas Devlieghere   return sb_process;
108730fdc8d8SChris Lattner }
108830fdc8d8SChris Lattner 
GetNumFrames()1089b9c1b51eSKate Stone uint32_t SBThread::GetNumFrames() {
10901755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
1091baf5664fSJonas Devlieghere 
1092ceb6b139SCaroline Tice   uint32_t num_frames = 0;
1093bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1094bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
10954fc6cb9cSJim Ingham 
1096b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
10977fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1098b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
10991ac04c30SGreg Clayton       num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1100c9858e4dSGreg Clayton     }
11017fdf9ef1SGreg Clayton   }
1102ceb6b139SCaroline Tice 
1103ceb6b139SCaroline Tice   return num_frames;
110430fdc8d8SChris Lattner }
110530fdc8d8SChris Lattner 
GetFrameAtIndex(uint32_t idx)1106b9c1b51eSKate Stone SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
11071755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, idx);
1108baf5664fSJonas Devlieghere 
110930fdc8d8SChris Lattner   SBFrame sb_frame;
1110b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1111bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1112bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11134fc6cb9cSJim Ingham 
1114b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11157fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1116b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11171ac04c30SGreg Clayton       frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
1118b9556accSGreg Clayton       sb_frame.SetFrameSP(frame_sp);
1119c9858e4dSGreg Clayton     }
11207fdf9ef1SGreg Clayton   }
1121ceb6b139SCaroline Tice 
1122d232abc3SJonas Devlieghere   return sb_frame;
112330fdc8d8SChris Lattner }
112430fdc8d8SChris Lattner 
GetSelectedFrame()1125b9c1b51eSKate Stone lldb::SBFrame SBThread::GetSelectedFrame() {
11261755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
1127baf5664fSJonas Devlieghere 
1128f028a1fbSGreg Clayton   SBFrame sb_frame;
1129b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1130bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1131bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11324fc6cb9cSJim Ingham 
1133b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11347fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1135b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11361ac04c30SGreg Clayton       frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame();
1137b9556accSGreg Clayton       sb_frame.SetFrameSP(frame_sp);
1138c9858e4dSGreg Clayton     }
11397fdf9ef1SGreg Clayton   }
1140f028a1fbSGreg Clayton 
1141d232abc3SJonas Devlieghere   return sb_frame;
1142f028a1fbSGreg Clayton }
1143f028a1fbSGreg Clayton 
SetSelectedFrame(uint32_t idx)1144b9c1b51eSKate Stone lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
11451755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, idx);
1146baf5664fSJonas Devlieghere 
1147f028a1fbSGreg Clayton   SBFrame sb_frame;
1148b57e4a1bSJason Molenda   StackFrameSP frame_sp;
1149bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1150bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11514fc6cb9cSJim Ingham 
1152b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
11537fdf9ef1SGreg Clayton     Process::StopLocker stop_locker;
1154b9c1b51eSKate Stone     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
11551ac04c30SGreg Clayton       Thread *thread = exe_ctx.GetThreadPtr();
11561ac04c30SGreg Clayton       frame_sp = thread->GetStackFrameAtIndex(idx);
1157b9c1b51eSKate Stone       if (frame_sp) {
11581ac04c30SGreg Clayton         thread->SetSelectedFrame(frame_sp.get());
1159b9556accSGreg Clayton         sb_frame.SetFrameSP(frame_sp);
1160f028a1fbSGreg Clayton       }
1161c9858e4dSGreg Clayton     }
11627fdf9ef1SGreg Clayton   }
1163f028a1fbSGreg Clayton 
1164d232abc3SJonas Devlieghere   return sb_frame;
1165f028a1fbSGreg Clayton }
1166f028a1fbSGreg Clayton 
EventIsThreadEvent(const SBEvent & event)1167b9c1b51eSKate Stone bool SBThread::EventIsThreadEvent(const SBEvent &event) {
11681755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(event);
1169baf5664fSJonas Devlieghere 
1170248a1305SKonrad Kleine   return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != nullptr;
11714f465cffSJim Ingham }
11724f465cffSJim Ingham 
GetStackFrameFromEvent(const SBEvent & event)1173b9c1b51eSKate Stone SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) {
11741755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(event);
1175baf5664fSJonas Devlieghere 
1176d232abc3SJonas Devlieghere   return Thread::ThreadEventData::GetStackFrameFromEvent(event.get());
11774f465cffSJim Ingham }
11784f465cffSJim Ingham 
GetThreadFromEvent(const SBEvent & event)1179b9c1b51eSKate Stone SBThread SBThread::GetThreadFromEvent(const SBEvent &event) {
11801755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(event);
1181baf5664fSJonas Devlieghere 
1182d232abc3SJonas Devlieghere   return Thread::ThreadEventData::GetThreadFromEvent(event.get());
11834f465cffSJim Ingham }
1184f028a1fbSGreg Clayton 
operator ==(const SBThread & rhs) const1185b9c1b51eSKate Stone bool SBThread::operator==(const SBThread &rhs) const {
11861755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, rhs);
1187baf5664fSJonas Devlieghere 
1188b9c1b51eSKate Stone   return m_opaque_sp->GetThreadSP().get() ==
1189b9c1b51eSKate Stone          rhs.m_opaque_sp->GetThreadSP().get();
119030fdc8d8SChris Lattner }
119130fdc8d8SChris Lattner 
operator !=(const SBThread & rhs) const1192b9c1b51eSKate Stone bool SBThread::operator!=(const SBThread &rhs) const {
11931755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, rhs);
1194baf5664fSJonas Devlieghere 
1195b9c1b51eSKate Stone   return m_opaque_sp->GetThreadSP().get() !=
1196b9c1b51eSKate Stone          rhs.m_opaque_sp->GetThreadSP().get();
119730fdc8d8SChris Lattner }
1198dde9cff3SCaroline Tice 
GetStatus(SBStream & status) const1199b9c1b51eSKate Stone bool SBThread::GetStatus(SBStream &status) const {
12001755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, status);
1201baf5664fSJonas Devlieghere 
12024f465cffSJim Ingham   Stream &strm = status.ref();
12034f465cffSJim Ingham 
1204b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1205b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1206b2e7d28eSJim Ingham 
1207b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
12086a9767c7SJim Ingham     exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true);
1209b9c1b51eSKate Stone   } else
12104f465cffSJim Ingham     strm.PutCString("No status");
12114f465cffSJim Ingham 
12124f465cffSJim Ingham   return true;
12134f465cffSJim Ingham }
12144f465cffSJim Ingham 
GetDescription(SBStream & description) const1215b9c1b51eSKate Stone bool SBThread::GetDescription(SBStream &description) const {
12161755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, description);
1217baf5664fSJonas Devlieghere 
12186a9767c7SJim Ingham   return GetDescription(description, false);
12196a9767c7SJim Ingham }
12206a9767c7SJim Ingham 
GetDescription(SBStream & description,bool stop_format) const12216a9767c7SJim Ingham bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
12221755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, description, stop_format);
1223baf5664fSJonas Devlieghere 
1224da7bc7d0SGreg Clayton   Stream &strm = description.ref();
1225da7bc7d0SGreg Clayton 
1226b2e7d28eSJim Ingham   std::unique_lock<std::recursive_mutex> lock;
1227b2e7d28eSJim Ingham   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1228b2e7d28eSJim Ingham 
1229b9c1b51eSKate Stone   if (exe_ctx.HasThreadScope()) {
1230b9c1b51eSKate Stone     exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm,
12316a9767c7SJim Ingham                                                     LLDB_INVALID_THREAD_ID,
12326a9767c7SJim Ingham                                                     stop_format);
1233b9c1b51eSKate Stone     // strm.Printf("SBThread: tid = 0x%4.4" PRIx64,
1234b9c1b51eSKate Stone     // exe_ctx.GetThreadPtr()->GetID());
1235b9c1b51eSKate Stone   } else
1236da7bc7d0SGreg Clayton     strm.PutCString("No value");
1237ceb6b139SCaroline Tice 
1238ceb6b139SCaroline Tice   return true;
1239ceb6b139SCaroline Tice }
12405dd4916fSJason Molenda 
GetExtendedBacktraceThread(const char * type)1241b9c1b51eSKate Stone SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
12421755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, type);
1243baf5664fSJonas Devlieghere 
1244bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock;
1245bb19a13cSSaleem Abdulrasool   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12465dd4916fSJason Molenda   SBThread sb_origin_thread;
12475dd4916fSJason Molenda 
12485dd4916fSJason Molenda   Process::StopLocker stop_locker;
1249b9c1b51eSKate Stone   if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1250b78094abSJim Ingham     if (exe_ctx.HasThreadScope()) {
12517a2f7904SJason Molenda       ThreadSP real_thread(exe_ctx.GetThreadSP());
1252b9c1b51eSKate Stone       if (real_thread) {
12535dd4916fSJason Molenda         ConstString type_const(type);
12547a2f7904SJason Molenda         Process *process = exe_ctx.GetProcessPtr();
1255b9c1b51eSKate Stone         if (process) {
12567a2f7904SJason Molenda           SystemRuntime *runtime = process->GetSystemRuntime();
1257b9c1b51eSKate Stone           if (runtime) {
1258b9c1b51eSKate Stone             ThreadSP new_thread_sp(
1259b9c1b51eSKate Stone                 runtime->GetExtendedBacktraceThread(real_thread, type_const));
1260b9c1b51eSKate Stone             if (new_thread_sp) {
1261b9c1b51eSKate Stone               // Save this in the Process' ExtendedThreadList so a strong
126205097246SAdrian Prantl               // pointer retains the object.
12637a2f7904SJason Molenda               process->GetExtendedThreadList().AddThread(new_thread_sp);
12647a2f7904SJason Molenda               sb_origin_thread.SetThread(new_thread_sp);
1265a6e9130dSJason Molenda             }
1266a6e9130dSJason Molenda           }
12677a2f7904SJason Molenda         }
12685dd4916fSJason Molenda       }
12695dd4916fSJason Molenda     }
12705dd4916fSJason Molenda   }
12715dd4916fSJason Molenda 
1272d232abc3SJonas Devlieghere   return sb_origin_thread;
12735dd4916fSJason Molenda }
12748ee9cb58SJason Molenda 
GetExtendedBacktraceOriginatingIndexID()1275b9c1b51eSKate Stone uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
12761755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
1277baf5664fSJonas Devlieghere 
12788ee9cb58SJason Molenda   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
12798ee9cb58SJason Molenda   if (thread_sp)
12808ee9cb58SJason Molenda     return thread_sp->GetExtendedBacktraceOriginatingIndexID();
12818ee9cb58SJason Molenda   return LLDB_INVALID_INDEX32;
12828ee9cb58SJason Molenda }
1283b4892cd2SJason Molenda 
GetCurrentException()1284e60bc53bSKuba Mracek SBValue SBThread::GetCurrentException() {
12851755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
1286e60bc53bSKuba Mracek 
1287baf5664fSJonas Devlieghere   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1288baf5664fSJonas Devlieghere   if (!thread_sp)
1289d232abc3SJonas Devlieghere     return SBValue();
1290baf5664fSJonas Devlieghere 
1291d232abc3SJonas Devlieghere   return SBValue(thread_sp->GetCurrentException());
1292e60bc53bSKuba Mracek }
1293e60bc53bSKuba Mracek 
GetCurrentExceptionBacktrace()1294e60bc53bSKuba Mracek SBThread SBThread::GetCurrentExceptionBacktrace() {
12951755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
1296e60bc53bSKuba Mracek 
1297baf5664fSJonas Devlieghere   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1298baf5664fSJonas Devlieghere   if (!thread_sp)
1299d232abc3SJonas Devlieghere     return SBThread();
1300baf5664fSJonas Devlieghere 
1301d232abc3SJonas Devlieghere   return SBThread(thread_sp->GetCurrentExceptionBacktrace());
1302c9e1190aSKuba Mracek }
1303e60bc53bSKuba Mracek 
SafeToCallFunctions()1304b9c1b51eSKate Stone bool SBThread::SafeToCallFunctions() {
13051755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
1306baf5664fSJonas Devlieghere 
1307b4892cd2SJason Molenda   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1308b4892cd2SJason Molenda   if (thread_sp)
1309b4892cd2SJason Molenda     return thread_sp->SafeToCallFunctions();
1310b4892cd2SJason Molenda   return true;
1311b4892cd2SJason Molenda }
13122bdbfd50SJim Ingham 
operator ->()1313b9c1b51eSKate Stone lldb_private::Thread *SBThread::operator->() {
131426ca5a57SPavel Labath   return get();
13152bdbfd50SJim Ingham }
13162bdbfd50SJim Ingham 
get()1317b9c1b51eSKate Stone lldb_private::Thread *SBThread::get() {
131826ca5a57SPavel Labath   return m_opaque_sp->GetThreadSP().get();
13192bdbfd50SJim Ingham }
1320*ac666d17SMichał Górny 
GetSiginfo()1321*ac666d17SMichał Górny SBValue SBThread::GetSiginfo() {
1322*ac666d17SMichał Górny   LLDB_INSTRUMENT_VA(this);
1323*ac666d17SMichał Górny 
1324*ac666d17SMichał Górny   ThreadSP thread_sp = m_opaque_sp->GetThreadSP();
1325*ac666d17SMichał Górny   if (!thread_sp)
1326*ac666d17SMichał Górny     return SBValue();
1327*ac666d17SMichał Górny   return thread_sp->GetSiginfoValue();
1328*ac666d17SMichał Górny }
1329