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